我正在尝试使用 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' )
Run Code Online (Sandbox Code Playgroud)
小智 7
这是我使用的一些代码。我同意它确实应该成为 NetworkX 的一部分,因为它对我来说经常出现。 graph必须是一个DiGraph. s是源节点,并且dist是dict由具有到 as 值的加权距离的节点作为键控的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
Run Code Online (Sandbox Code Playgroud)
看起来您正在使用 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))
Run Code Online (Sandbox Code Playgroud)