Reputation: 11
So I want to generate a random network with 3 nodes. And the edges have to random between the two nodes with a specific probability or strength.
Choosing the nodes with following probability : Node 1 :0.6 Node 2: 0.3 Node 3: 0.1
And I want to do it for multiple times as this is a part of temporal data. So in each time stamp one connection.
I am doing it in R with igraph. But the ER model could not do it.
Any idea how can I do it?
Edit: The edges are directed. ( Note : I am a biology student not a hardcore person who works with network. So any direction and suggestions will be helpful.)
Upvotes: 1
Views: 367
Reputation: 52008
What you want seems to be impossible. There are three possible edges: 1-2, 1-3, and 2-3. Let p_ij
denote the probability that edge i-j is chosen. Note that the probability that a given node appears on a randomly chosen edge is the sum of the two edge probabilities that involve that node, so that e.g.
p(1) = p_12 + p_13
You seem to want the p_ij
to satisfy:
p_12 + p_13 = 0.6
p_12 + p_23 = 0.3
p_13 + p_23 = 0.1
p_12 + p_13 + p_23 = 1
with the further constraint that each p_ij >= 0
.
This is simply impossible. The first three equations yield p_12 = 0.4
, p_13 = 0.2
and p_23 = -0.1
, which violates the fourth equation and the nonnegativity constraints.
If this argument doesn't imply that what you want is impossible, please explain what you are trying to do more clearly.
On Edit: If you want to simulate movement between nodes (as per your comments) you can do something like this:
#the following function takes a vector, nodes of
#populations and picks a random move of an individual
#from one node to another. Chosen source node is
#is picked with probability which is proportional
#to the population. Return value is a vector of
#the form c(from,to)
move <- function(nodes){
total.pop <- sum(nodes)
n <- length(nodes)
from <- sample(1:n,1,prob = nodes/total.pop)
to <- sample((1:n)[-from],1)
c(from,to)
}
#The following function takes an initial population
#distribution and simulates n moves according to the above
#it returns a dataframe with one row per step
moves <- function(nodes,steps){
n <- length(nodes)
current <- nodes #current nodes
A <- matrix(0,steps+1,n+3)
A[1,] <- c(0,c(NA,NA),nodes)
for(i in 1:steps){
v <- move(current)
current[v[1]] <- current[v[1]] - 1
current[v[2]] <- current[v[2]] + 1
A[i+1,] <- c(i,v,current)
}
df <- data.frame(A)
names(df) <- c("Step","From","To",paste("Node",1:n,sep = ""))
df
}
For example:
> sim <- moves(c(60,30,10),1000)
> plot(sim$Step,sim$Node1,type = "l",ylim = c(0,100),xlab = "Time Step", ylab = "populations")
> points(sim$Step,sim$Node2,type = "l",col = "blue")
> points(sim$Step,sim$Node3,type = "l",col = "red")
Output:
Upvotes: 1