【问题标题】:Distance Matrix from second variable using get.shortest.paths()使用 get.shortest.paths() 与第二个变量的距离矩阵
【发布时间】:2014-05-16 20:37:18
【问题描述】:

我想进一步回答这个问题 (Find total of second variable related to the distance of route from get.shortest.paths())。当使用 newcost 变量找到“最短”路径时,如何获得节点之间的距离矩阵?

(我对 igraph 的经验非常有限)。

      df2 = rbind(c(234,235,21.6,75),
      c(234,326,11.0,35),
      c(235,241,14.5,78),
      c(326,241,8.2,98),
      c(241,245,15.3,75),
      c(234,245,38.46,65))

      df2 = as.data.frame(df2)
      names(df2) = c("start_id","end_id","newcost","distance")

      require(igraph)
      g2 <- graph.data.frame(df2, directed=FALSE)
      tmp2 = shortest.paths(g2,weights=E(g2)$newcost)
      tmp2 #this gives the matrix of newcost-weighted shortest distances

我可以使用帮助的地方是如何找到所有路径,比如使用optimal.path &lt;- get.shortest.paths,并使用sum(E(g2, path = optimal.path)$distance) 创建距离矩阵

我真正想要的是所有节点对的距离边缘列表,例如:

      startid endid shortestdist
      234     235     75
      234     245     208

这个问题的棘手之处在于 newcost 用于找到最短路径,但我想要的是另一个变量的总和 - 节点对之间每条最短路径上的距离变量。

【问题讨论】:

  • 那么,您想要tmp2 中的所有数据,但您只是想要不同的格式?您想要每个开始/结束组合的行而不是矩阵?
  • @MrFlick:感谢您的提问。我想要的不一样。 tmp2 中的数据是“newcost”总和,它给出了加权路径长度。我想要的是最短路径的距离变量的总和。
  • 你展示的两个例子恰好是相等的?
  • @MrFlick:该示例现已更正。谢谢!

标签: r routing igraph


【解决方案1】:

好的,首先让我明确一点,我自己不是igraph 用户。不过,我认为这个问题很有趣,所以我想看看。而且我也找不到解决您遇到的问题的简单方法。我最终制作了一些辅助函数来使该过程成为可能。我很有可能已经在 igraph 中重新编码了功能,但我找不到它。

让我首先定义get.shortest.paths.for.all,它不仅会返回给定属性的最短路径长度,还会返回图中所有顶点的最短路径。这是代码

get.shortest.paths.for.all<-function(graph, attr) {
    paths<-lapply(1:(vcount(graph)-1), function(i) {
        get.all.shortest.paths(
            graph, 
            weights=get.edge.attribute(g2,attr),
            from = V(graph)[i],
            to = V(graph)[(i+1):vcount(graph)]
        )$res
    })
    unsplit(paths, rep.int(seq_along(paths), sapply(paths, length)))
}

现在让我定义get.path.dist.matrix 将获取一个图表和一个路径列表(如get.shortest.paths.for.all 返回的路径),并将计算每个路径之间给定属性的距离

get.path.dist.matrix<-function(graph, path, attr) {
    dd<-get.adjacency(graph, attr=attr)
    uniqs <- numeric(0)
    if (is.list(path)) {
        starts<-sapply(path, head, 1)
        ends<-sapply(path, tail, 1)
        uniqs <- unique(sort(c(starts,ends)))
    } else {
        uniqs <- c(head(path,1), tail(path,1))
    }
    m<-matrix(0, nrow=length(uniqs), ncol=length(uniqs),
        dimnames=list(V(graph)$name[uniqs],V(graph)$name[uniqs]))
    for(pp in path) {
        m[pp[1], pp[length(pp)]]<-sum(dd[embed(pp,2)])
    }
    m+t(m)
}

使用您的示例数据,我这样使用它们

paths <- get.shortest.paths.for.all(g2, "newcost")
get.path.dist.matrix(g2, paths,"distance")

#     234 235 326 241 245
# 234   0  75  35 133 208
# 235  75   0 176  78 153
# 326  35 176   0  98 173
# 241 133  78  98   0  75
# 245 208 153 173  75   0

这似乎合理且与shortest.paths(g2,weights=E(g2)$distance) 不同。为了尝试测试我的功能,我看到了

all(tmp2==get.path.dist.matrix(g2, paths,"newcost"))

所以请随意尝试这些,如果您发现任何问题或可能的改进,请告诉我。

【讨论】:

    猜你喜欢
    • 2012-05-31
    • 1970-01-01
    • 2019-09-04
    • 2016-12-06
    • 2011-08-08
    • 2014-02-15
    • 1970-01-01
    • 2020-09-11
    • 1970-01-01
    相关资源
    最近更新 更多