生活随笔
收集整理的這篇文章主要介紹了
NetworkX系列教程(10)-算法之三:关键路径问题
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
小書匠Graph圖論重頭戲部分來(lái)了,寫到這里我感覺(jué)得仔細(xì)認(rèn)真點(diǎn)了,可能在NetworkX中,實(shí)現(xiàn)某些算法就一句話的事,但是這個(gè)算法是做什么的,用在什么地方,原理是怎么樣的,不清除,所以,我決定先把圖論中常用算法弄個(gè)明白在寫這部分.
圖論常用算法看我的博客:
下面我將使用NetworkX實(shí)現(xiàn)上面的算法,建議不清楚的部分打開(kāi)兩篇博客對(duì)照理解.
我將圖論的經(jīng)典問(wèn)題及常用算法的總結(jié)寫在下面兩篇博客中:
圖論---問(wèn)題篇
圖論---算法篇
目錄:
* 11.3關(guān)鍵路徑算法(CPA)
注意:如果代碼出現(xiàn)找不庫(kù),請(qǐng)返回第一個(gè)教程,把庫(kù)文件導(dǎo)入.
11.3關(guān)鍵路徑算法(CPA)
以下代碼從這里復(fù)制,由于版本問(wèn)題,將代碼中的:nx.topological_sort(self, reverse=True)改為list(reversed(list(nx.topological_sort(self))))
import networkx as nx?
import matplotlib.pyplot as plt?
from matplotlib.font_manager import * ?
?
?
myfont = FontProperties(fname='/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc') ?
?
matplotlib.rcParams['axes.unicode_minus']=False ?
?
class CPM(nx.DiGraph):?
?
def __init__(self):?
super().__init__()?
self._dirty = True?
self._critical_path_length = -1?
self._criticalPath = None?
?
def add_node(self, *args, **kwargs):?
self._dirty = True?
super().add_node(*args, **kwargs)?
?
def add_nodes_from(self, *args, **kwargs):?
self._dirty = True?
super().add_nodes_from(*args, **kwargs)?
?
def add_edge(self, *args): ?
self._dirty = True?
super().add_edge(*args) ?
?
def add_edges_from(self, *args, **kwargs):?
self._dirty = True?
super().add_edges_from(*args, **kwargs)?
?
def remove_node(self, *args, **kwargs):?
self._dirty = True?
super().remove_node(*args, **kwargs)?
?
def remove_nodes_from(self, *args, **kwargs):?
self._dirty = True?
super().remove_nodes_from(*args, **kwargs)?
?
def remove_edge(self, *args): ?
self._dirty = True?
super().remove_edge(*args) ?
?
def remove_edges_from(self, *args, **kwargs):?
self._dirty = True?
super().remove_edges_from(*args, **kwargs)?
?
?
def _forward(self):?
for n in nx.topological_sort(self):?
es = max([self.node[j]['EF'] for j in self.predecessors(n)], default=0)?
self.add_node(n, ES=es, EF=es + self.node[n]['duration'])?
?
?
def _backward(self):?
?
for n in list(reversed(list(nx.topological_sort(self)))):?
lf = min([self.node[j]['LS'] for j in self.successors(n)], default=self._critical_path_length)?
self.add_node(n, LS=lf - self.node[n]['duration'], LF=lf)?
?
?
def _compute_critical_path(self):?
graph = set()?
for n in self:?
if self.node[n]['EF'] == self.node[n]['LF']:?
graph.add(n)?
self._criticalPath = self.subgraph(graph)?
?
@property?
def critical_path_length(self):?
if self._dirty:?
self._update()?
return self._critical_path_length?
?
@property?
def critical_path(self):?
if self._dirty:?
self._update()?
return sorted(self._criticalPath, key=lambda x: self.node[x]['ES'])?
?
def _update(self):?
self._forward()?
self._critical_path_length = max(nx.get_node_attributes(self, 'EF').values())?
self._backward()?
self._compute_critical_path()?
self._dirty = False?
?
if __name__ == "__main__":?
?
?
G = CPM()?
G.add_node('A', duration=5)?
G.add_node('B', duration=2)?
G.add_node('C', duration=4)?
G.add_node('D', duration=4)?
G.add_node('E', duration=3)?
G.add_node('F', duration=7)?
G.add_node('G', duration=4)?
?
G.add_edges_from([?
('A', 'B'),?
('A', 'C'),?
('C','D'),?
('C','E'),?
('C','G'),?
('B','D'),?
('D','F'),?
('E','F'),?
('G','F'),?
]) ?
?
?
nx.draw_spring(G,with_labels=True)?
plt.title('AOE網(wǎng)絡(luò)',fontproperties=myfont)?
plt.axis('on')?
plt.xticks([])?
plt.yticks([])?
plt.show()?
?
?
print('關(guān)鍵活動(dòng)為:')?
print(G.critical_path_length, G.critical_path)?
?
G.add_node('D', duration=2)?
print('\n修改D活動(dòng)持續(xù)時(shí)間4為2后的關(guān)鍵活動(dòng)為:')?
print(G.critical_path_length, G.critical_path)?
關(guān)鍵路徑示例(該圖非黑色線為手工繪制,數(shù)字手工添加)
從graph中可以知道,有兩條關(guān)鍵路徑,分別是:A->C->G->F和A->C->D->F,長(zhǎng)度都是20.
輸出:
關(guān)鍵活動(dòng)為: 20 ['A', 'C', 'D', 'G', 'F']
修改D活動(dòng)持續(xù)時(shí)間4為2后的關(guān)鍵活動(dòng)為: 20 ['A', 'C', 'G', 'F']
關(guān)鍵活動(dòng)為: ['A', 'C', 'D', 'G', 'F'],可以構(gòu)成兩條邊.D活動(dòng)持續(xù)時(shí)間4為2后,關(guān)鍵路徑變化.
轉(zhuǎn)載于:https://www.cnblogs.com/wushaogui/p/9240634.html
總結(jié)
以上是生活随笔為你收集整理的NetworkX系列教程(10)-算法之三:关键路径问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。