【问题标题】:The first 10 shortest paths in a graph - Igraph 0.6 - Python 2.7图中的前 10 条最短路径 - Igraph 0.6 - Python 2.7
【发布时间】:2013-04-04 08:31:22
【问题描述】:

自从我开始在我的编码中成功实现 Igraph 以来,我一直在想这个问题:你能用 get_all_shortest_paths 检索尽可能多的最短路径吗?假设是前 10 个。

到目前为止,我已经明白,在无向图中检索所有最短路径是没有意义的,因为在大多数情况下,它们的数量是无限的。

但是我可以只检索前 10 条最短路径吗?

我尝试使用无向的 g = Graph() 来实现这一点:

list = []
list.append(g.get_all_shortest_paths(index1,index2, "distance")[0])   # shortest path
list.append(g.get_all_shortest_paths(index1,index2, "distance")[1])   # second shortest path
list.append(g.get_all_shortest_paths(index1,index2, "distance")[2])   # third shortest path
list.append(g.get_all_shortest_paths(index1,index2, "distance")[3])   # forth shortest path
list.append(g.get_all_shortest_paths(index1,index2, "distance")[4])   # fifth shortest path
list.append(g.get_all_shortest_paths(index1,index2, "distance")[5])   # sixth shortest path
list.append(g.get_all_shortest_paths(index1,index2, "distance")[6])   # seventh shortest path
list.append(g.get_all_shortest_paths(index1,index2, "distance")[7])   # eigth shortest path
list.append(g.get_all_shortest_paths(index1,index2, "distance")[8])   # ninth shortest path
list.append(g.get_all_shortest_paths(index1,index2, "distance")[9])   # tenth shortest path

#"distance" is from g.es["distance"]

列表索引超出范围总是会给我错误。 实际上我什至无法获得list.append(g.get_all_shortest_paths(index1,index2, "distance")[1]),尽管我知道那里有超过 10 条路径。

图表没有什么特别之处。数以千计的顶点,都以某种方式连接,我的意思是各种顶点度数。

最后我想有一个 wx.spin 或 wx.ComboBox 在路径之间进行选择(即现实生活中最短的国道在冬天结冰,所以我想选择第二短的City1 和 City2 之间的道路......然后哦不......有袋鼠在上面跳,所以我选择第三条,或者更好的第四条路,因为我知道麦当劳,我真的很喜欢吃垃圾食品 bla bla)

我知道最短!= 短,但我需要类似的东西:如果最短不好,那么忽略它,转到第二个等等。 我已经在 Google 上搜索过,但我不清楚我该怎么做。

提前感谢您!

编辑:我可能会提到list.append(g.get_all_shortest_paths(index1,index2, "distance")[1]) 当然在有 2 条最短路径自然完全相同的距离时工作。

重要更新:

由于我不光彩地误解了g.get_all_shortest_paths,这部分将在我的代码中更改为g.get_shortest_paths(index1, index2, weights=distance, mode=ALL, output="vpath"),我还提到该图是加权的,但无论如何这一点很明显:

list = []
g.es["weight"] = distance
list.append(g.get_shortest_paths(index1, index2, weights=distance, mode=ALL, output="vpath")[0])   # shortest path
list.append(g.get_shortest_paths(index1, index2, weights=distance, mode=ALL, output="vpath")[1])   # second shortest path
list.append(g.get_shortest_paths(index1, index2, weights=distance, mode=ALL, output="vpath")[2])   # third shortest path
list.append(g.get_shortest_paths(index1, index2, weights=distance, mode=ALL, output="vpath")[3])   # forth shortest path
list.append(g.get_shortest_paths(index1, index2, weights=distance, mode=ALL, output="vpath")[4])   # fifth shortest path
list.append(g.get_shortest_paths(index1, index2, weights=distance, mode=ALL, output="vpath")[5])   # sixth shortest path
list.append(g.get_shortest_paths(index1, index2, weights=distance, mode=ALL, output="vpath")[6])   # seventh shortest path
list.append(g.get_shortest_paths(index1, index2, weights=distance, mode=ALL, output="vpath")[7])   # eigth shortest path
list.append(g.get_shortest_paths(index1, index2, weights=distance, mode=ALL, output="vpath")[8])   # ninth shortest path
list.append(g.get_shortest_paths(index1, index2, weights=distance, mode=ALL, output="vpath")[9])   # tenth shortest path

#"distance" is a list containing the weights
# graph is TRUE-ly weighted now

如何获取两个顶点之间的前 10 条或所有短路径?

这个问题仍在寻找被接受的答案。谢谢。

(P.S. 我在问题的第一部分中保留了错误的方法,因为可能有像我这样的其他巨大的 idiobooms 尝试同样的事情)

【问题讨论】:

  • 您可能会遗漏两件事: 1. 即使循环图中的 路径 的数量通常可能是无限的,但 shortest 的数量i> 任何两个节点之间的路径都是有限的,除非您有零权重的边、具有负总权重的循环或任何其他类似的邪恶。 2.get_all_shortest_paths不支持边权重,所以第三个参数不是保存距离的属性名。
  • 3.您计划做的事情将非常低效,因为您将计算同一节点对之间的所有最短路径 10 次。只需计算一次所有最短路径并将列表切片:paths = g.get_all_shortest_paths(index1, index2)[:10]
  • 啊,我明白了。我会试一试的。第三个论点似乎工作正常。这是一个错误的信念吗?严肃的问题,因为我有一系列属性,例如“道路代码”、“难度”等。我使用了g.get_all_shortest_paths(index1, index2,"difficulty"),它似乎是一个具有“难度”给出的值的权重。我这么说是因为它到目前为止有效。我不明白。
  • 第三个参数不能正常工作。该函数在那里接受任何字符串,但唯一有意义的值是inoutall;它们确定允许遍历有向边的方向。
  • +1 为您所有非常有用的 cmets Tamás。再次感谢你。不过我很震惊,因为我花了很多时间相信第三个论点正在按照我的想法工作。我现在需要改变那里的一切。已经在查找 is_weighted() 。您能否提出一些进一步的文档来从第三个属性中制作加权图并完成整个问题的相关内容?如果您想到它们,只需链接就足够了。我不想阻止你开发伟大的图书馆:)

标签: python graph path shortest-path igraph


【解决方案1】:

好的,我仍然不确定您所说的“前 10 条最短路径”是什么意思,但这是我认为您可能想要实现的目标。您有一个图表,其中边缘由两个端点的实际(例如,欧几里得)距离标记。你得到两点,你希望在它们之间找到一些替代路径,同时尽量保持这些路径尽可能短。请注意,由于您的图表是加权的,因此您不太可能在两点之间有许多 最短 路径 - 为了使所有路径成为 最短,它们总重量必须完全相同相同。如果您的权重“像乌鸦飞翔”那样测量实际距离,那么这种同时发生的情况就不太可能发生——您要寻找的十条路径的长度会略有不同。因此,get_all_shortest_paths 对您没有用处,不仅因为它不使用权重,还因为即使使用权重,您也不太可能在两点之间找到长度完全相同的多条路径。

另一种选择是get_shortest_paths,它可以考虑权重,但它只会返回一对顶点之间的一个路径。 (之所以称为get_shortest_paths 是因为如果您指定多个目标顶点,它会返回多个 路径——更准确地说,它为每个目标顶点提供一个路径)。所以,你不能用get_shortest_paths来获取你要找的十条路径。

经过一番谷歌搜索,我找到了一个可能对您有用的implementation of the k-shortest-paths algorithm。它不是igraph 的一部分,但您可以从igraph 保存图形,使用os.system 或Python 中的subprocess 模块调用k-shortest-paths 算法的编译可执行文件,然后解析结果以某种方式。

【讨论】:

  • 我明白了。我认为你在这方面做了很多工作。谢谢你。同时我也在谷歌上搜索并找到了这个All possible paths between one node to another...。我看到你也在这里评论了一个解决方案。我想我应该尝试检索那里的所有路径。让我们不要专注于最短路径,让我们以某种方式获取所有路径,然后对权重求和。我无法让那个例子为我工作。如果能够获得所有路径并仅在此之后使用它们,那就太好了。
  • 如果我有所有的路径(即上面例子中的那个路径上的顶点 ID),那么我可以将连接它们的边的属性相加,这会给我带来无限的机会。对不起,我没有清楚地表达我自己。这种方法可行吗?再次感谢塔马斯。真的。
  • stackoverflow.com/questions/3971876/… 这是我认为接近答案但无法实现的。它不适合我。
  • 这不适合你;该代码背后的假设是您的图是有向的和非循环的 - 换句话说,它不包含循环。您的图表确实如此,因此该算法将陷入无限循环。 真正的 解决方案是在 Python 中编写一个 k 最短路径算法。第二个最佳解决方案是尝试像我上面链接的那样的外部 k-shortest-paths 实现。
  • 第三个最佳解决方案是列出源点和目标点之间的所有简单路径(即不包含两次相同节点的路径),并取最短的十个;这可以通过 NetworkX 中的 all_simple_paths 例程来完成;见networkx.lanl.gov/reference/generated/…。这种方法的问题在于,除非您的图表非常小,否则此类路径的数量可能会很大。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-28
  • 2014-02-19
相关资源
最近更新 更多