【问题标题】:How to calculate a maximum-bottleneck path with igraph?如何用 igraph 计算最大瓶颈路径?
【发布时间】:2019-08-16 10:16:00
【问题描述】:

给定一个单源单汇容量网络,如何使用 igraph 计算maximum-bottleneck path(也称为最宽路径或最大容量路径问题)?

我已经读过(例如here 甚至使用伪代码there),可以对 Dijkstra 的算法进行一些修改,但我不想深入研究算法开发,而是使用 igraph。

例子

library(igraph)
set.seed(21)

nodes = cbind(
'id' = c('Fermenters', 'Methanogens', 'carbs', 'CO2', 'H2', 'other', 'CH4', 'H2O')
)

from <- c('carbs', rep('Fermenters', 3), rep('Methanogens', 2), 'CO2', 'H2')
to <- c('Fermenters', 'other', 'CO2', 'H2', 'CH4', 'H2O', rep('Methanogens', 2))
weight <- sample(1 : 20, 8)

links <- data.frame(from, to, weight, stringsAsFactors = FALSE)


net = graph_from_data_frame(links, vertices = nodes, directed = T)

## Calculate max-bottleneck here !


# # disabled because just vis
# plot(net, edge.width = E(net)$weight)

# require(networkD3)
# require(tidyverse)
# 
# d3net <- igraph_to_networkD3(net, group = rep(1, 8))
# forceNetwork(
#     Links = mutate(d3net$links, weight = E(net)$weight), Nodes = d3net$nodes,
#     Source = 'source', Target = 'target',
#     NodeID = 'name', Group = "group", Value = "weight", 
#     arrows = TRUE, opacity = 1, opacityNoHover = 1
# )

那么对于示例,我将如何计算从carbsH2O 的最大容量路径?

【问题讨论】:

  • Max-Flow 解决了一个相关但恕我直言不同的问题,即计算 2 个顶点之间的最大可能流。我感兴趣的问题是关于在加权图中找到两个指定顶点之间的路径,最大化路径中最小权重边的权重。(复制自维基百科)。跨度>

标签: r igraph graph-theory


【解决方案1】:

我不知道这会有多高效,但是您可以使用 igraph 查找所有“简单”路径,然后计算每个路径的最小边权重,然后选择最大...

require(tibble)
require(igraph)

nodes = data_frame('id' = c('A', "B", "C", "D"))

links = tribble(
  ~from, ~to, ~weight,
  "A" , "B", 10,
  "B", "C", 10,
  "C", "D", 6,
  "A", "D", 4,
)

net = graph_from_data_frame(links, vertices = nodes, directed = T)

simple_paths <- all_simple_paths(net, "A", "D")

simple_paths[which.max(
    sapply(simple_paths, function(path) {
      min(E(net, path = path)$weight)
    })
)]

# [[1]]
# + 4/4 vertices, named, from 061ab8d:
# [1] A B C D

【讨论】:

  • 这确实是一个解决方案(如果没有人想出更有效的方法,以后会被接受)。正如您正确指出的那样,性能(以及内存要求)将成为现实世界图(1k + 节点)的问题
  • 在我的实际用例中,这是一个相当线性的图,只有几个循环和约 1k 个节点,此解决方案不会在有限时间内计算。这就是为什么我没有将其标记为已接受。
  • 出于好奇,是哪一部分? minsapply$which.max 都是高度优化的基本函数,它们此时仅使用数字列表,它们应该能够轻松处理。 igraph::all_simple_paths 是一些我不理解的魔法,所以我不知道它的性能应该如何。您的用例中有多少个简单路径?可能是igraph::Esapply中边的提取?
  • 帮助文件警告:“请注意,图的两个顶点之间可能存在指数级路径,如果您的图是格状的,则使用此函数时可能会耗尽内存。”
  • 我完全同意。我也看到了帮助警告。它永远不会从枚举所有路径的igraph::all_simple_paths 返回,如果有循环等,对于较大的有向图将失败。如前所述,我也认为该解决方案只是一种解决方法。正确的解决方案是采用 dijstra(又名最短路径)实现,将问题的性质考虑在内(参见相关参考文献)。
【解决方案2】:

您可以尝试与IGRAPH IN R: Find the path between vertices that maximizes the product of edge attributes 相同的想法。反转权重,除以总数以保持权重

x<-shortest_paths(net,3,8, weights=-log(E(net)$weight/sum(E(net)$weight)), output="epath")[[2]]
E(net)[x[[1]]]
min(E(net)$weight[x[[1]]])

给了

+ 4/8 edges from 57589bc (vertex names):
[1] carbs      ->Fermenters  Fermenters ->H2          H2         ->Methanogens Methanogens->H2O
[1] 10

【讨论】:

  • 如(不幸的是作者删除的答案)中所讨论的,仅边缘重新缩放的最短路径不会计算最大瓶颈路径。为此,需要更改 dijkstra 以在最小宽度上使用不同的 argmax。有关详细信息,请参阅cs.cmu.edu/~avrim/451f08/lectures/lect1007.pdf 第 13.3 节。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-03
  • 2013-06-26
  • 1970-01-01
  • 2014-05-17
  • 2022-12-06
  • 2012-01-07
  • 1970-01-01
相关资源
最近更新 更多