Julia 如何删除光照图中的自循环
我不熟悉Julia和LightGraphs,我一直在努力寻找最有效的方法来检测和消除自循环。到目前为止,我找到的唯一方法是迭代Simplegraph中的所有节点,检查它是否有自循环,然后删除它们。有没有更好的方法像在Python NetworkX中使用这种组合:Julia 如何删除光照图中的自循环,julia,lightgraphs,Julia,Lightgraphs,我不熟悉Julia和LightGraphs,我一直在努力寻找最有效的方法来检测和消除自循环。到目前为止,我找到的唯一方法是迭代Simplegraph中的所有节点,检查它是否有自循环,然后删除它们。有没有更好的方法像在Python NetworkX中使用这种组合:G.remove\u edges\u from(G.selfloop\u edges()) 我现在的做法是: path = adrs\to\my\edgeList G = SimpleGraph(loadgraph(path, Graph
G.remove\u edges\u from(G.selfloop\u edges())
我现在的做法是:
path = adrs\to\my\edgeList
G = SimpleGraph(loadgraph(path, GraphIO.EdgeList.EdgeListFormat()))
for node in vertices(G)
if has_edge(G,node,node)
rem_edge!(G,node,node)
end
end
这可能是有条件地执行此操作的最佳方法,但您可以调用
rem\u edge!(G,node,node)
不带has_edge()
检查-它返回一个bool,指示是否删除了边,以便在没有实际边的情况下安全使用。您可以通过以下命令找到具有自循环的顶点:
vxs = Iterators.flatten(simplecycles_limited_length(g,1))
要删除它们,只需执行以下操作:
rem_edge!.(Ref(g), vxs, vxs)
我在我的解决方案(没有
has_edge()
,谢谢@sbromberger!)和@Przemyslaw提出的解决方案(看起来很整洁!)之间进行了快速基准测试。从记忆和时间的角度来看,我简单的方法仍然是最有效的方法。我很惊讶地看到simplecycles\u limited\u length()
比循环更糟糕,因为该函数似乎是为了这个特定的目的。如果你知道原因,请告诉我
以下是我的基准测试结果(我的_图有22470个节点和170823条边,有179个自循环):
编辑:按要求添加插值基准。谢谢,这看起来与我所寻找的非常接近,但奇怪的是,与我的简单解决方案相比,它效率不高(请参阅我发布的答案)。你知道这是为什么吗?在我的代码中,你有
flatte
,它进行额外的分配,但保持代码简短。你能用插值进行基准测试吗?作为@基准s11($myu图)
和@基准s12($myu图)
。当前的基准测试不正确。@AndrejOskin我添加了它们。我还保留了以前的那些作为参考。比较仍然给出相同的结果。但是你能告诉我为什么没有插值的基准测试是错误的吗?在这里你可以找到很好的解释:
using BenchmarkTools
function sl1(G)
for node in vertices(G)
rem_edge!(G,node,node)
end
end
function sl2(G)
vxs = Iterators.flatten(simplecycles_limited_length(G,1))
rem_edge!.(Ref(G), vxs, vxs)
end
@benchmark sl1(my_graph)
>>> BenchmarkTools.Trial:
memory estimate: 0 bytes
allocs estimate: 0
--------------
minimum time: 554.401 μs (0.00% GC)
median time: 582.899 μs (0.00% GC)
mean time: 592.032 μs (0.00% GC)
maximum time: 1.292 ms (0.00% GC)
--------------
samples: 8440
evals/sample: 1
@benchmark sl1($my_graph)
>>> BenchmarkTools.Trial:
memory estimate: 0 bytes
allocs estimate: 0
--------------
minimum time: 555.500 μs (0.00% GC)
median time: 603.501 μs (0.00% GC)
mean time: 616.309 μs (0.00% GC)
maximum time: 1.281 ms (0.00% GC)
--------------
samples: 8108
evals/sample: 1
@benchmark sl2(my_graph)
>>> BenchmarkTools.Trial:
memory estimate: 448 bytes
allocs estimate: 6
--------------
minimum time: 792.400 μs (0.00% GC)
median time: 836.000 μs (0.00% GC)
mean time: 855.634 μs (0.00% GC)
maximum time: 1.836 ms (0.00% GC)
--------------
samples: 5839
evals/sample: 1
@benchmark sl2($my_graph)
>>> BenchmarkTools.Trial:
memory estimate: 448 bytes
allocs estimate: 6
--------------
minimum time: 795.600 μs (0.00% GC)
median time: 853.250 μs (0.00% GC)
mean time: 889.450 μs (0.00% GC)
maximum time: 2.022 ms (0.00% GC)
--------------
samples: 5618
evals/sample: 1
@btime sl1(my_graph)
>>> 555.999 μs (0 allocations: 0 bytes)
@btime sl1($my_graph)
>>> 564.000 μs (0 allocations: 0 bytes)
@btime sl2(my_graph)
>>> 781.800 μs (6 allocations: 448 bytes)
@btime sl2($my_graph)
>>> 802.200 μs (6 allocations: 448 bytes)