我有一个由强连通分量(蓝色)和一组节点(橙色)组成的有向图。挑战是尽可能地打破循环,同时最少删除边。此外,每个橙色节点必须存在一条路径到达每个蓝色节点。
我用蛮力法解决了这个问题:
- 删除随机边
- 检查每个橙色节点到每个蓝色节点的路径。如果一切正常,我将添加一个边到列表中并计算循环数。
- 将边返回到图形中并继续执行步骤1,直到迭代所有边
- 接下来,从结果列表(长度为n)中生成组合C(n,k),其中k = {2 ... n}
- 对所有边缘组合执行操作1,2,3
代码核心如下:
for level in range(2, len(edges)):
stop = True
edges2 = combinations(edges,level)
for i, e in enumerate(edges2):
g.remove_edges_from(e)
test = True
for node in orange_nodes:
d = nx.algorithms.descendants(g, node)
test = blue_nodes == d
if not test:
break
if test:
stop = False
cycles_count = len(list(nx.simple_cycles(g)))
print(f'{i}\t{level}\t{cycles_count}\t{e}')
g.add_edges_from(e)
if stop:
break
问题:
- 是否有可能通过使用生成树或反馈弧集来重写代码,从而优化代码(nx.algorithms.descendants()和nx.simple_cycles()速度极慢)?
- 也许有快速搜索算法可用于不是最佳解决方案但是较好的解决方案吗?
此外: 我已经使用graph-tool重写了代码,这使得速度提高了约20倍...50倍。但这仍然无法满足实际任务的要求 =(
edges2 = combinations(edges,level)
中,combinations
函数的作用是什么? - aak318