【问题标题】:Calculate the longest path between two nodes NetworkX计算两个节点 NetworkX 之间的最长路径
【发布时间】:2020-12-08 20:09:56
【问题描述】:

我正在尝试使用 Networkx 制作甘特图。网络中的所有节点都是完成项目需要执行的“任务”。使用 Networkx 可以轻松计算项目的总时间。但是制作甘特图我需要每个节点的最新开始。

NetworkX 包含一个函数(dag_longest_path_length),但这会计算整个网络中最长的路径。另一个函数(astar_path_length)导致源和节点之间的最短路径,但没有可用的函数给出最长的路径,或者在我的情况下是最新的开始。 (如果一个节点作为两个前置节点,它将采取最快的路线,但实际上它也必须等待第二个才能启动。

我正在考虑一种选择。 评估先前连接的节点并选择最长的路径。非正式我没有成功。

start_time=[]
time=0
DD=nx.DiGraph()
for i in range(df.shape[0]):
        DD.add_edge(str(df.at[i,'blockT'])+'_'+df.at[i,'Task'], str(df.at[i,'blockS'])+'_'+df.at[i,'Succ'], weight=df.at[i,'duration'])


fig, ax = plt.subplots()  
labels=[]  
for i in range(df.shape[0]):
        labels.append(str(df.at[i,'blockT'])+'_'+df.at[i,'Task'])
        print(nx.astar_path_length(DD, '0_START', str(df.at[i,'blockT'])+'_'+df.at[i,'Task'])  ) 

ax.broken_barh([(nx.astar_path_length(DD, '0_START', str(df.at[i,'blockT'])+'_'+df.at[i,'Task']), heuristic=None, weight='weight'),df.at[i,'duration'] )],(i-0.4,0.8), facecolors='blue' )

【问题讨论】:

  • youtube.com/watch?v=a3ww0gwEszo 好吧,这个视频是关于无向图的,所以你的问题在计算上很容易解决,但我仍然喜欢它。

标签: python networkx


【解决方案1】:

看起来你正在使用 DAG。

您的问题很少见,因此 networkx 中没有内置功能。您应该手动完成:

max(nx.all_simple_paths(DAG, source, target), key=lambda x: len(x))

这是完整的测试代码:

import networkx as nx
import random
from itertools import groupby

# Create random DAG
G = nx.gnp_random_graph(50,0.3,directed=True)
DAG = nx.DiGraph([(u,v) for (u,v) in G.edges() if u<v])

# Get the longest path from node 1 to node 10
max(nx.all_simple_paths(DAG, 1, 10), key=lambda x: len(x))

【讨论】:

  • 感谢您的评论!但是这种方法不考虑节点的权重,只考虑节点的数量。所以它不会给出最新的开始,而是给出最长的路径。
  • 然后你可以使用类似的东西:max([(path, sum(DAG.edges[pair]['weight'] for pair in list(nx.utils.pairwise(path)))) for path in nx.all_simple_paths(DAG, 1, 10)], key=lambda x: x[1])
【解决方案2】:

这是我使用的一些代码。我同意它确实应该成为 NetworkX 的一部分,因为它经常出现在我身上。 graph 必须是 DiGraphs 是源节点,dist 是一个 dict,由具有与 s 的加权距离作为值的节点键控。

    def single_source_longest_dag_path_length(graph, s):
        assert(graph.in_degree(s) == 0)
        dist = dict.fromkeys(graph.nodes, -float('inf'))
        dist[s] = 0
        topo_order = nx.topological_sort(graph)
        for n in topo_order:
            for s in graph.successors(n):
                if dist[s] < dist[n] + graph.edges[n,s]['weight']:
                    dist[s] = dist[n] + graph.edges[n,s]['weight']
        return dist

【讨论】:

  • 这是一个很好的答案,并且比迭代所有简单路径要快得多。
  • 支持未加权图并从不在末尾的节点开始的更一般的答案。 def single_source_longest_dag_path_length(graph, s): dist = dict.fromkeys(graph.nodes, -float('inf')) dist[s] = 0 topo_order = nx.topological_sort(graph) for n in topo_order: for s in graph.successors(n): if dist[s] &lt; dist[n] + 1: dist[s] = dist[n] + 1 return dist
猜你喜欢
  • 2012-05-21
  • 1970-01-01
  • 2019-04-20
  • 1970-01-01
  • 2011-03-08
  • 1970-01-01
  • 1970-01-01
  • 2011-03-08
  • 2010-11-18
相关资源
最近更新 更多