2

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.

Nick
  • 1,086
  • 7
  • 21
  • You can manually build an out.seq vector such that the total number of edges (on all time steps) would sum up to 72. – Lior Kogan Dec 27 '15 at 19:53
  • @LiorKogan, thank you. I have built out_seq vector and check the total number of edges: sum is 72, but the generated graph has 62 edges only. How to change this case? – Nick Dec 28 '15 at 04:15
  • Is there a chance you are getting multi-edges? You can check with `is_simple`. The algorithm argument has some discussion on this here: http://igraph.org/r/doc/sample_pa.html – dougmet Jan 05 '16 at 14:00
  • Also just noticed this in the docs for out.seq: "Numeric vector giving the number of edges to add in each time step. **Its first element is ignored** as no edges are added in the first time step." Maybe the first element is being ignored with 10 edges in it? – dougmet Jan 05 '16 at 14:03

1 Answers1

2

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!

Marcos RF
  • 327
  • 2
  • 8