如何在Julia的LightGraphs中为图添加免费(零权重)边?
解决LightGraphs中SimpleWeightedDiGraph添加零权重边的问题
我之前也碰到过LightGraphs里SimpleWeightedDiGraph无法添加零权重边的情况,这是因为这个类型的实现默认会把权重0当作“无有效权重”的标识,导致添加操作失败,而且最短路径算法也不会识别这类边。给你几个简便的解决方案:
方法一:用极小正数替代零权重(最简便)
这是最快速的临时解决办法,用一个非常接近0的正数(比如1e-10)来模拟“免费”边,既不会影响最短路径的计算结果,又能被SimpleWeightedDiGraph正常识别和添加:
using LightGraphs, SimpleWeightedGraphs # 创建带权有向图 g = SimpleWeightedDiGraph(3) # 添加普通权重边 add_edge!(g, 1, 2, 5.0) # 添加"免费"边(用极小正数代替0) add_edge!(g, 2, 3, 1e-10) add_edge!(g, 1, 3, 10.0) # 计算最短路径,会优先走1->2->3这条路径 dijkstra_shortest_paths(g, 1).dists
这个方法不需要修改现有代码结构,只需要把0替换成极小值即可,对最短路径算法的结果几乎没有影响。
方法二:分离图结构与权重存储(严格零权重)
如果必须使用严格的0权重,可以用普通的DiGraph来维护图结构,然后用字典单独存储边的权重:
using LightGraphs # 创建普通有向图 g = DiGraph(3) # 用字典存储边权重,支持零权重 edge_weights = Dict{Tuple{Int,Int}, Float64}() # 添加边并设置权重 add_edge!(g, 1, 2) edge_weights[(1,2)] = 5.0 add_edge!(g, 2, 3) edge_weights[(2,3)] = 0.0 # 严格零权重 add_edge!(g, 1, 3) edge_weights[(1,3)] = 10.0 # 自定义权重函数,供最短路径算法使用 weight_func(u, v) = get(edge_weights, (u,v), Inf) # 使用支持自定义权重的最短路径算法(比如Dijkstra) dijkstra_shortest_paths(g, 1; edge_weight=weight_func).dists
这种方法完全支持零权重,但需要额外维护权重字典,适合必须严格区分“免费”和“有成本”边的场景。
方法三:升级到Graphs.jl(官方推荐)
注意:LightGraphs已经停止维护,官方推荐迁移到Graphs.jl及其配套的SimpleWeightedGraphs.jl。新版的实现对零权重边的支持更好,你可以尝试升级后直接添加零权重边:
using Graphs, SimpleWeightedGraphs g = SimpleWeightedDiGraph(3) add_edge!(g, 1, 2, 0.0) # 新版应该能正常添加零权重边
如果升级后还是有问题,再回到方法一或方法二即可。
内容的提问来源于stack exchange,提问作者Berni
相关产品推荐
相关产品推荐

