在R中的广度优先搜索期间改变节点的属性

时间:2014-02-10 01:21:44

标签: r networking graph igraph breadth-first-search

我创建了一个包含100个节点的随机(Erdos-Renyi)图。我已将所有100个节点的属性值设置为0.我找到具有最大度数(最多邻居)的节点,并将其属性值从0更改为1.然后,使用节点作为根节点,以及另一个节点作为第二个根节点,我在网络上进行广度优先搜索(BFS)。

这与此question有关。

我像这样进行广度搜索:

# BFS on the network
bfs <- graph.bfs(graph, root = c(root_node, root_node2), unreachable = FALSE,
    order = TRUE, dist = TRUE)

我想查看第一个根节点的邻居,然后是第二个根节点的邻居,然后是第一个根节点的邻居的邻居,然后是第二个根节点的邻居的邻居,依此类推。 / p>

这样的事情:

                O                        # Note: O* is the first root node
                |                        # and O! is the second root node
                |
O----O----O!----O----O*----O----O----O
          |          |
          |          |
          O          O

因此,首先,查看第一个根节点的邻居:

                O                        # Note: double connections are
                |                        # the paths taken to the neighbors
                |
O----O----O!----O====O*====O----O----O
          |          ||
          |          ||
          O          O

然后查看第二个根节点的邻居:

                O
                |
                |
O----O====O!====O----O*----O----O----O
          ||         |
          ||         |
          O          O

然后,第一个根节点的邻居的邻居:

                O
                ||
                ||
O----O----O!----O----O*----O====O----O
          |          |
          |          |
          O          O

然后是第二个根节点的邻居的邻居:

                O
                |
                |
O====O----O!----O----O*----O----O----O
          |          |
          |          |
          O          O

依此类推,直到查看了所有节点:

                O
                |
                |
O----O----O!----O----O*----O----O====O
          |          |
          |          |
          O          O

在查看每个节点时,我想将其属性值从0更改为1,这样如果有另一条路径到达它,则知道该节点的那个已被查看。

另外,有没有办法计算查看所有节点需要多少次迭代?例如,这里是6(包括原文)。

注意:两个根节点以某种方式连接(即它们之间有一条路径)。

对图像感到抱歉,但这是基本的想法。希望这是有道理的。

非常感谢任何帮助。谢谢!

1 个答案:

答案 0 :(得分:0)

以下是如何做到这一点。首先,这是一个随机生成的图。

numnodes <- 50
the.graph <- grg.game(numnodes, 0.3)

V(the.graph)$visited <- 0
graph.degree <- degree(the.graph)

现在,我们采用最大顶点和随机顶点。 (您没有指定如何选择第二个)。我们随机重新排列顶点,直到它连接到顶点并且不是最大度顶点。

maxvertex <- sample(which(graph.degree == max(graph.degree)),1)
randvertex <- as.integer(sample(V(the.graph),1))
while((randvertex == maxvertex) ||
      (shortest.paths(the.graph,maxvertex,randvertex) == Inf)) {
  randvertex <- sample(V(the.graph),1)
}

当遍历这样的图形时,我喜欢跟踪我的位置。这是起始位置和将这些初始节点标记为已访问的行。

curpos <- c(maxvertex, randvertex)
for(num in curpos) V(the.graph)[num]$visited <- 1

现在我们实际进行搜索并将节点标记为已访问。如果所有节点都标记为已访问或者没有更多要连接的节点要探索,则循环将终止。如果代码被窃听,我们知道应该没有比搜索步骤更多的迭代,所以我们知道它是否经过图表没有连接,我们不需要继续。对于每次迭代,我们遍历包含当前占用节点的向量。如果没有访问过它的任何邻居,我们将它们标记为已访问,并将它们添加到向量中以供下次使用。一旦我们访问了此迭代的所有节点,我们就开始下一个循环。

maxloops = length(V(the.graph))
curloop = 0
while((curloop < maxloops) && (length(curpos)>0) &&
      (sum(V(the.graph)$visited) < numnodes)) {
  nextpos <- c()
  while(length(curpos)>0) {
    curnode <- curpos[1]
    curpos <- curpos[-1]

    adjnodes <- which(the.graph[curnode] == 1)
    for(adjnode in adjnodes) {
      if(!V(the.graph)[adjnode]$visited) {
        nextpos <- c(nextpos,adjnode)
        V(the.graph)[adjnode]$visited <- 1
      }
    }
  }
  curpos <- nextpos
  curloop <- curloop + 1
}

现在我们访问了连接到最大度数节点的所有节点。我们现在打印遍历图形所需的迭代次数。如果未访问任何节点,则会另外打印一条消息,指出图形未连接。

print(curloop)
if(sum(V(the.graph)$visited) < numnodes) print("Not a connected graph.")