任务:使用到igraph库的python接口,找到具有负权重的DAG(有向无环图)的最短路径,作为单源/单个中的边/顶点列表目标设置。
尝试:我在文档中找到的最接近的匹配是get_shortest_paths
。但是,尝试时该函数返回:
igraph._igraph.InternalError: Error at structural_properties.c:5220: Weight vector must be non-negative, Invalid value
似乎内部函数试图应用Dijkstra的算法并失败。同时,根据文档,其他最短路径函数(shortest_paths
,shortest_paths_dijkstra
)能够使算法适应图的属性。
问题:
get_shortest_paths
选择正确的内部算法?相关问题:
感谢。
PS。 Python 2.7,IGraph 0.6.5
答案 0 :(得分:1)
get_shortest_paths
无法处理负权重的图形,因为底层C库尚未具有相应的igraph_get_shortest_paths_bellman_ford
函数。它确实有一个igraph_get_shortest_paths_dijkstra
,因此Python界面只是检查你是否有权重,如果是,则将调用重定向到igraph_get_shortest_paths_dijkstra
,否则只调用igraph_get_shortest_paths
(这是未加权的版本) C层)。相反,shortest_paths
使用负权重,因为C库有一个名为igraph_shortest_paths_bellman_ford
的函数,因此当至少有一个边权重为负时,它会调用Bellman-Ford实现。
不幸的是,唯一的出路似乎是在C层实现igraph_get_shortest_paths_bellman_ford
,然后更新Python接口以适当地处理负权重。
相关问题的答案:
igraph在运行任何最短路径相关功能之前不检查图形是否为DAG。是的,在DAG中可以更快地找到最短路径,但是这个用例非常罕见,到目前为止还没有人为实施特殊情况而烦恼。
用纯Python编写的自定义代码可能比C实现慢,但这取决于您的问题。如果您特别指的是Bellman-Ford算法,那么纯Python实现非常可能会更慢,但它仍然可用于您拥有的图形。您可以在NetworkX中尝试实施;据我所知,NetworkX是纯Python,人们仍然将它用于具有数万个节点和边缘的图形。
答案 1 :(得分:0)
我也有一个缓慢的R版本。 200k边缘和30k顶点需要大约20分钟,所以我在R中实现get.shortest.paths()
(但不是Python;对不起)和igraph_get_shortest_paths_bellman_ford()
对于具有负边权重的图形。您可以尝试我的R igraph here。
从R实现切换到C时,我经历了100x到1000x的加速。