Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set the parameters of Barabási model

I would like to use the Barabási–Albert (BA) Preferential Attachment model in order to generate graph with specified properties. Numbers of vertices and edges: V(g)=20, E(g)=72, respectively. Vectors of in- and out-degrees are known too. I would like to generate the directed graph without loops, multiple edges and isolated vertices.

Could somebody please give some ideas how to set parameters of the function barabasi.game()? My current settings are:

out_seq<-degree(g, mode="out")
sum(out_seq)
#[1] 72
g1<-barabasi.game(20,out.seq = out_seq)
summary(g1)
#IGRAPH D--- 20 62 -- Barabasi graph
#+ attr: name (g/c), power (g/n), m (g/x), zero.appeal (g/n),
#| algorithm (g/c)
has.multiple(g1)
#[1] FALSE

Previously I used the function degree.sequence.game(). It's working but I must remove the parameter: method="vl"

degs_out <- degree(g, mode="out")
degs_in <- degree(g, mode="in")
g1<-degree.sequence.game(degs_out, degs_in)#, method="vl")
# IGRAPH D D--- 20 72 -- Degree sequence random graph
#+ attr: name (g/c), method (g/c)

Thanks.

Edit. vl and v1 are different. In the first case vl are two letters v and l, in the second case v1 includes the letter v and number 1.

like image 393
Nick Avatar asked Nov 27 '25 13:11

Nick


1 Answers

I know this question has been hanging in here for a while, but hopefully my answer below serves as reference for similar situations in the future.

First you need to create an out.seq vector that adds up to 72, as suggested by @LiorKogan. You can do it by checking this post out. Here is the function that implements this task:

rand_vect <- function(N, M, sd = 1, pos.only = TRUE) {
  vec <- rnorm(N, M/N, sd)
  if (abs(sum(vec)) < 0.01) vec <- vec + 1
  vec <- round(vec / sum(vec) * M)
  deviation <- M - sum(vec)
  for (. in seq_len(abs(deviation))) {
    vec[i] <- vec[i <- sample(N, 1)] + sign(deviation)
  }
  if (pos.only) while (any(vec < 0)) {
    negs <- vec < 0
    pos  <- vec > 0
    vec[negs][i] <- vec[negs][i <- sample(sum(negs), 1)] + 1
    vec[pos][i]  <- vec[pos ][i <- sample(sum(pos ), 1)] - 1
  }
  vec
}

Since the initial nodes entering in the network can not connect with many other nodes (because they are not there yet!), you have to set their connections by hand in the vector init_nodes, i.e.: node 1 connects with nobody, node 2 connects only with node 1, node 3 connects with both... so on and so forth.

nodes=20
edges=72
init_nodes <- c(0,1,2,3,4)

For the "rest" of the vector, we use the function above such that the whole vector adds up to 72:

out_seq = c(init_nodes,rand_vect(nodes-length(init_nodes), edges-sum(init_nodes),pos.only = TRUE))

The routine above is perhaps subject to improvements, but it has been working fairly well in all my attempts. After this is done, you can check if the rule is working. It has to add up to 72:

sum(out_seq)

Now you can proceed with the Barabasi game using the vector out_seq

graph01 <- barabasi.game(nodes, 
              directed = TRUE,
              out.seq = out_seq
              ) 

Once the graph is created, you can double check if the requirement of 72 edges is met:

ecount(graph01)

And finally compare the vector out.seq with the actual degree formation:

degree(graph01, loops = FALSE, normalized=FALSE, mode="out")
out_seq

Last, ask R if your graph is simple:

is_simple(graph01)

Hope it helps! Good luck!

like image 121
Marcos RF Avatar answered Nov 29 '25 12:11

Marcos RF