2013-12-12 1 views
0

Я создал случайную сеть (Erdos-Renyi), используя R (и пакет igraph), который имеет 10 узлов. Каждый узел был случайно присвоен с атрибутом либо 0, либо 1.Сохранение и доступ к значениям после каждой итерации в случайной сети в R

Я применил правило простого большинства на этих узлах, так что если большинство соседей узла имеют атрибут 0, то атрибут узла изменяется на 0 (или 1, если большинство из них 1). Он проходит через все узлы в сети итеративно, в соответствии с их числами (1-10) и применяет правило простого большинства.

Вот мой код, чтобы создать график:

# Creates an Erdos-Renyi graph with 10 nodes and edges with p=0.2 
num_nodes <- 10 
prob <- 0.2 
graph <- erdos.renyi.game(num_nodes, prob, type=c("gnp", "gnm"), directed=FALSE, 
    loops=FALSE) 

# Randomly sets the attributes of the nodes to either 0 or 1 
graph <- set.vertex.attribute(graph, "value", value = sample(0:1, num_nodes, 
    replace=TRUE)) 

Вот мой код, чтобы применить простое правило большинства, что у меня есть до сих пор:

modified <- FALSE 
iterations <- 0 #keeps track of how many iterations take place 
for (i in 1:num_nodes*10) { 
    modified = FALSE 
    iterations <- iterations + 1 
    for (i in 1:num_nodes) { 
     adj_ones <- 0 #keeps track of how many neighbors of a node have 1s 
     adj_zeros <- 0 #keeps track of how many neighbors of a node have 0s 
     for (j in neighbors(graph, i)) { #looks at the neighbors of a node 
      if (get.vertex.attribute(graph, "value", index = j) == 1) { 
       adj_ones <- adj_ones + 1 #increments one count if neighbor is 1 
      } else { 
       adj_zeros <- adj_zeros + 1 # or increments zero count if 
                  #neighbor is 0 
      } 
     } 
     modified = FALSE 
     #I need to modify this bit so that the 0 or 1 changes are only stored 
     #rather than actually changed 
     if (adj_ones > adj_zeros) { #updates 0 or 1 value of node 
      if (V(graph)$value[which(V(graph)==i)] == 0) { 
       modified = TRUE 
       V(graph)$value[which(V(graph)==i)] = 1 
      } 
     } else if (adj_ones < adj_zeros) { 
      if (V(graph)$value[which(V(graph)==i)] == 1) { 
       modified = TRUE 
       V(graph)$value[which(V(graph)==i)] = 0 
      } 
     } 
    if (!modified) { 
     break 
    } 
} 

Это все работает отлично, но я необходимо изменить его так, чтобы после того, как он посмотрел на узел, и если значение этого или этого значения должно быть изменено, вместо того, чтобы его менять, вместо этого оно сохраняет новое значение. Таким образом, когда проверяются соседние узлы этого узла, они используют исходное значение узла, а не измененное (сохраненное) значение. Сохраняемое значение каждого узла необходимо обновлять по мере необходимости после каждой итерации всех узлов. (то есть 2-я итерация всех значений узлов использует значения 1-й итерации узлов, а 3-я итерация использует значения 2-й итерации).

Я не слишком уверен, как это сделать. Мне нужно сохранить обновленные значения в фрейме данных и получить доступ к ним для каждой итерации с помощью этого? Как мне это сделать? Или есть другой способ сделать это?

+0

Я лично думаю, что пакет igraph является излишеством для этого. Если у вас есть сеть с <100 вершинами, просто используйте плотную матрицу смежности и вектор для хранения атрибутов. –

+0

Спасибо за предложение @GaborCsardi, но мне нужно делать и другие вещи с графиком, а пакет igraph - лучший способ сделать это. – LoneWolf

ответ

2

Вы можете создать вторую переменную для каждого узла (назовем ее «flip»), которая устанавливается, если узел должен перевернуть, потому что большинство его соседей отличаются. В первом проходе каждой итерации вы отмечаете все узлы, которые нужно перевернуть. Во втором проходе вы фактически обновляете все значения.

Вот код, который я думаю, что должно сделать трюк (основанный в значительной степени от кода, публикуемым):

library(igraph) 

# Creates an Erdos-Renyi graph with 10 nodes and edges with p=0.2 
num_nodes <- 10 
prob <- 0.2 
graph <- erdos.renyi.game(num_nodes, prob, type=c("gnp", "gnm"), directed=FALSE, 
    loops=FALSE) 

# Randomly sets the attributes of the nodes to either 0 or 1 
graph <- set.vertex.attribute(graph, "value", value = sample(0:1, num_nodes, 
    replace=TRUE)) 

modified <- FALSE 
iterations <- 0 #keeps track of how many iterations take place 
for (i in 1:num_nodes*10) { 
    # Initially set flip to all false 
    graph <- set.vertex.attribute(graph, "flip", value=rep(FALSE, num_nodes)) 

    modified = FALSE 
    iterations <- iterations + 1 
    for (i in 1:num_nodes) { 
     adj_ones <- 0 #keeps track of how many neighbors of a node have 1s 
     adj_zeros <- 0 #keeps track of how many neighbors of a node have 0s 
     for (j in neighbors(graph, i)) { #looks at the neighbors of a node 
      if (get.vertex.attribute(graph, "value", index = j) == 1) { 
       adj_ones <- adj_ones + 1 #increments one count if neighbor is 1 
      } else { 
       adj_zeros <- adj_zeros + 1 # or increments zero count if 
                  #neighbor is 0 
      } 
     } 
     modified = FALSE 
     #I need to modify this bit so that the 0 or 1 changes are only stored 
     #rather than actually changed 
     i.pos = which(V(graph) == i) 
     if (adj_ones > adj_zeros) { #updates 0 or 1 value of node 
      if (V(graph)$value[i.pos] == 0) { 
       modified = TRUE 
       V(graph)$flip[i.pos] = TRUE 
      } 
     } else if (adj_ones < adj_zeros) { 
      if (V(graph)$value[which(V(graph)==i)] == 1) { 
       modified = TRUE 
      V(graph)$flip[i.pos] = TRUE 
      } 
     } 
    } 
    if (!modified) { 
     break 
    } 

    # Actually flip the things we labeled as needing to flip 
    for (i in 1:num_nodes) { 
      if (V(graph)$flip[i]) { 
       V(graph)$value[i] = 1-V(graph)$value[i] 
      } 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^