You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
3.2 KiB
106 lines
3.2 KiB
import csv
|
|
import networkx as nx
|
|
import matplotlib.pyplot as plt
|
|
from typing import Dict, Tuple
|
|
|
|
pert = nx.DiGraph()
|
|
|
|
with open('tasks-sae.csv') as csvfile:
|
|
tasks = list(csv.reader(csvfile, delimiter=','))
|
|
for task, duration, predecessors, label, _ in tasks:
|
|
pert.add_node(task, duration=int(duration))
|
|
|
|
for task, duration, predecessors, label, _ in tasks:
|
|
if predecessors == '':
|
|
continue
|
|
for predecessor in predecessors.split('-'):
|
|
pert.add_edge(predecessor, task)
|
|
|
|
layout = nx.nx_pydot.graphviz_layout(pert, prog='dot')
|
|
nx.draw(pert, pos=layout)
|
|
nx.draw_networkx_labels(pert, pos=layout)
|
|
|
|
labels: Dict[Tuple[str, str], int] = {}
|
|
for task in pert.nodes:
|
|
for edge in pert.out_edges(task):
|
|
labels[edge] = pert.nodes[task]['duration']
|
|
|
|
nx.draw_networkx_edge_labels(pert, pos=layout, edge_labels=labels)
|
|
plt.show()
|
|
|
|
sources = [task for task in pert.nodes if pert.in_degree(task) == 0]
|
|
puits = [task for task in pert.nodes if pert.out_degree(task) == 0]
|
|
|
|
asap: Dict[str, str] = dict()
|
|
for source in sources:
|
|
asap[source] = pert.nodes[source]['duration']
|
|
|
|
frontiere = []
|
|
for task in sources:
|
|
frontiere.extend(pert.successors(task))
|
|
|
|
while len(frontiere):
|
|
sucessors = []
|
|
for task in frontiere:
|
|
start = 0
|
|
stop = False
|
|
for predecessor in pert.predecessors(task):
|
|
if predecessor not in asap:
|
|
stop = True
|
|
break
|
|
start = max(start, asap[predecessor])
|
|
if stop:
|
|
continue
|
|
asap[task] = start + pert.nodes[task]['duration']
|
|
sucessors.extend(pert.successors(task))
|
|
frontiere = sucessors
|
|
|
|
total_duration = 0
|
|
for task in pert.nodes:
|
|
total_duration = max(asap[task], total_duration)
|
|
|
|
alap: Dict[str, str] = dict()
|
|
for puit in puits:
|
|
alap[puit] = total_duration - pert.nodes[puit]['duration']
|
|
|
|
frontiere = []
|
|
for task in puits:
|
|
frontiere.extend(pert.predecessors(task))
|
|
|
|
while len(frontiere):
|
|
predecessors = []
|
|
for task in frontiere:
|
|
end = total_duration
|
|
stop = False
|
|
for successor in pert.successors(task):
|
|
if successor not in alap:
|
|
stop = True
|
|
break
|
|
end = min(end, alap[successor])
|
|
if stop:
|
|
continue
|
|
alap[task] = end - pert.nodes[task]['duration']
|
|
predecessors.extend(pert.predecessors(task))
|
|
frontiere = predecessors
|
|
|
|
print('Durée totale :', total_duration, 'heures')
|
|
for task in pert.nodes:
|
|
duration = pert.nodes[task]['duration']
|
|
print('|', task, '|', duration, '|', '-'.join(pert.predecessors(task)), '|', asap[task] - duration, '|', asap[task], '|', alap[task], '|', alap[task] + duration, '|', alap[task] + duration - asap[task], '|', sep='')
|
|
|
|
|
|
nrow = pert.number_of_nodes()
|
|
plt.figure()
|
|
bar_width = 0.9
|
|
|
|
tasks = list(pert.nodes)
|
|
|
|
for i, task in enumerate(reversed(tasks)):
|
|
duration = pert.nodes[task]['duration']
|
|
plt.broken_barh([(asap[task] - duration, duration)], (i - bar_width / 2, bar_width))
|
|
#plt.broken_barh([(asap[task], alap[task] - asap[task])], (i - bar_width / 2, bar_width), color='green')
|
|
|
|
plt.yticks([i for i in range(nrow)], reversed(tasks))
|
|
|
|
plt.show()
|