【问题标题】:How to compute random walk between all pairs of nodes in graph?如何计算图中所有节点对之间的随机游走?
【发布时间】:2017-10-13 03:00:04
【问题描述】:

我有一个包含 15000 个节点的图表。我想计算其中所有节点对之间的随机游走并将其放入一个矩阵。 我查看了 R 中的 igraph 包

random_walk(graph, start, steps, mode = c("out", "in", "all"),
  stuck = c("return", "error"))

并且需要指定图中的起始节点和节点数。 我正在寻找一种计算有效的方法来计算图的所有可能起始节点的随机游走。 有人可以帮助我吗?

这是我的图表的样子:

1002 DHX8   SRPK1 0.5791602
1003 DHX8  CRNKL1 0.6729812
1004 DHX8   SRPK2 0.5791602
1005 DHX8    SNW1 0.8772539
1006 DHX8  SNRPD2 0.8772539

1007 DHX8 PRPF38A 0.5110222
1008 DHX8  NOTCH1 0.6168687
1009 DHX8    TAF9 0.6729812
1010 DHX8   CDC40 0.8772539
3477 SMAD4 SMURF1 0.6168687
3478 SMAD4   RAC2 0.6392732
3479 SMAD4   DAXX 0.4907872
3480 SMAD4  KPNB1 0.6168687
3481 SMAD4    HGS 0.4288047
3482 SMAD4  NAT8B 0.8772539
3483 SMAD4     AR 0.4745135
3484 SMAD4  ILKAP 0.6608392
3485 SMAD4   SKIL 0.2383471
3486 SMAD4  USP15 0.4288047
3487 SMAD4  DACH1 0.4745135

【问题讨论】:

  • 请提供一个可重现的例子。
  • 您能否澄清一下:您是要查找所有节点对之间的随机游走距离,还是要计算每个节点的随机游走并报告找到的节点之间的距离? 2)正在考虑这个图有向或无向。 3) 如果您正在寻找所有成对距离,如何报告预期的未连接节点?

标签: r


【解决方案1】:

由于您没有提供任何数据,我不确定运行需要多长时间,但您可以使用 purrr 包来遍历每个节点。这将输出一个输出列表,列表中的每个元素都是random_walk 函数的单个输出。

output <- purrr::map(
  .x = 1:15000,
  .f = function(x){
    random_walk(graph, start = x, steps = 1000, 
                mode = "all", stuck = "return")
  }
)

【讨论】:

  • 谢谢,好吧,我的图是权重,最后,我需要矩阵其中的元素 i,j 显示节点 i,j 之间的随机游走距离。你想完成它并获得 50 + 吗?
  • 我不确定您所说的“我的图表是重量”是什么意思。此外,我对这种类型的图表不太熟悉,也不完全确定 i 和 j 在这种情况下代表什么。对不起
  • 您能否提供一个您正在寻找的输出示例,以及如何计算输出。请原谅我缺乏领域知识,但是一台计算机如何手动随机游走一张小图?
【解决方案2】:

假设我正确地考虑了这个问题,用一些基本函数来实现这并不难:

#making the graph
m1<-sample(LETTERS, 15000, replace = T)
m2<-sample(LETTERS, 15000, replace = T)
w<-runif(15000, .1, 3)

graph<-data.frame(m1, m2, w, stringsAsFactors = F)
graph<-graph[graph$m1 != graph$m2,]

nodes<-list()

#parse the structure
for(node in unique(graph$m1)){
  temp <-list(target = c(), weight = c())
  df <-graph[graph$m1 == node,]

  if(nrow(df) == 0){
    next
  }

  for(i in 1:nrow(df)){
    temp$target<-c(temp$target, df[i,]$m2)
    temp$weight<-c(temp$weight, df[i,]$w)
   }

  nodes[[node]]<-temp
}

现在只需创建一个函数来进行遍历:

#Performs a single random walk
randomWalk<-function(nodes, start = 'A', steps = 5){
  step = 0:steps
  target = c(start)
  weight = c(0)

  if(!start %in% names(nodes)){
    return(paste(start, "not in list of nodes"))
    }

  for(i in 1:steps){

  options<-nodes[[start]]$target

  if(length(options) < 1){
    break
    }

  option_weights<-nodes[[start]]$weight

  rs<-sample(1:length(options), 1)
  target<-c(target, options[rs])
  weight<-c(weight, option_weights[rs])

  start<-options[rs]

  }

 return(data.frame(step, target, weight))
 }

#Testing
randomWalk(nodes, 'x', 20)
randomWalk(nodes, "X", 20)

循环遍历它们的函数很简单。

many_walks<-function(nodes, steps){
  walks<-list()

  for(st in names(nodes)){
    walks[[st]]<-randomWalk(nodes, st, steps)
   }
  return(walks)
}

不会太慢,但取决于您拥有的节点数。

many_walks(nodes, 50)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-03
    • 2016-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多