我正在玩sukses
并注意到networkx
算法没有返回负循环,而是提升bellman_ford
。
如何返回第一个负循环而不是异常?
unbounded exception
此外,我用bellman_ford测试套利交易
谢谢,
答案 0 :(得分:2)
这是因为Bellman-Ford算法从单个源返回所有节点的最短路径。但是,如果存在任何负循环,则没有从源顶点到所有节点的最短路径(例如,该循环中的每个节点都没有最短路径,因为您可以再次迭代循环并获得较低的加权路径)。
你可能做的是使用nx.simple_cycles。它的作用是返回一个简单循环的生成器,即图中不同的循环而不重复节点(当然除了第一个和最后一个)。 然后,您可以迭代生成的输出并检查负循环。
我想它看起来像这样:
#import networx as nx
import networkx as nx
def find_path(digraph, start="USD"):
try:
path = nx.bellman_ford(digraph, start)
return path
except NetworkXUnbounded:
cycles = nx.simple_cycles(digraph)
for cycle in cycles:
print cycle # do whatever you prefer here of course
我没有尝试过。
答案 1 :(得分:0)
您仍然可以使用Bellman-Ford。在这里,我将finding-negative-cycle-in-graph的代码改编成python,并添加了一个正在运行的示例。
import matplotlib.pyplot as plt
import networkx as nx
import numpy as np
def getW(edge):
return edge[2]['weight']
def getNegativeCycle(g):
n = len(g.nodes())
edges = list(g.edges().data())
d = np.ones(n) * 10000
p = np.ones(n)*-1
x = -1
for i in range(n):
for e in edges:
if d[int(e[0])] + getW(e) < d[int(e[1])]:
d[int(e[1])] = d[int(e[0])] + getW(e)
p[int(e[1])] = int(e[0])
x = int(e[1])
if x == -1:
print("No negative cycle")
return None
for i in range(n):
x = p[int(x)]
cycle = []
v = x
while True:
cycle.append(str(int(v)))
if v == x and len(cycle) > 1:
break
v = p[int(v)]
return list(reversed(cycle))
G = nx.DiGraph()
G.add_edge('0', '1', weight=0.1)
G.add_edge('1', '2', weight=-1)
G.add_edge('2', '3', weight=-0.3)
G.add_edge('3', '0', weight=-0.4)
G.add_edge('4', '3', weight=0.7)
G.add_edge('4', '5', weight=0.9)
G.add_edge('3', '5', weight=-5)
cycle = getNegativeCycle(G)
这将输出一个负循环:
cycle
Out[68]: ['2', '3', '0', '1', '2']
请注意,为简单起见(数组位置),我使用的是数字顶点。
答案 2 :(得分:0)
因此,修改Or Dinari的代码以使用任意权重函数,例如networkx的其余部分...
def negative_cycle(g, weight_func=burns_advanced):
n = len(g.nodes())
d = defaultdict(lambda: 10000)
p = defaultdict(lambda: -1)
x = -1
for i in range(n):
for u, v in g.edges():
weight = weight_func(u, v, g[u][v])
if d[u] + weight < d[v]:
d[v] = d[u] + weight
p[v] = u
x = v
if x == -1:
print('No negative cycle')
return None
for i in range(n):
x = p[x]
cycle = []
v = x
while True:
cycle.append(v)
if v == x and len(cycle) > 1:
break
v = p[v]
return list(reversed(cycle))
像魅力一样工作!无论如何,我都会给您赏金,因为参考确实是我所需要的。谢谢!