-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcpm.py
More file actions
210 lines (163 loc) · 5.37 KB
/
cpm.py
File metadata and controls
210 lines (163 loc) · 5.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
from graphviz import Digraph
import csv
import pandas as pd
from criticalpath import Node
from tkinter import *
#Class representing an activity
class activity:
def __init__(self, rows, activity_index):
self.activity_name = rows[activity_index][0]
self.predecessors_string = rows[activity_index][1]
self.duration = int(rows[activity_index][2])
self.start_event = (rows[activity_index][3])
self.end_event = (rows[activity_index][4])
self.predecessors = list()
for i in range(len(self.predecessors_string)):
self.predecessors.append(self.predecessors_string[i])
self.no_of_predecessors = len(self.predecessors)
self.ES = 0
self.EF = 0
self.LS = 0
self.LF = 0
self.TF = 0
#Getting the activities
def get_activities():
rows = []
with open('my_csv.csv','r') as csvfile:
csvreader = csv.reader(csvfile)
for row in csvreader:
rows.append(row)
return rows[1:]
#Function to get all attribs in the graph
def get_graph_attribs(activities):
nodes = set()
edges = []
for activity in activities:
label = activity.activity_name + " [ " + str(activity.ES) + "," + str(activity.LF) + " ] "
edges.append((activity.start_event,activity.end_event,label))
nodes.add(int(activity.start_event))
nodes.add(int(activity.end_event))
return sorted(nodes), edges
#Function to plot the graph
def plot_graph(nodes, _edges):
dot = Digraph()
graph_edges = []
for _edge in _edges:
dot.edge(_edge[0], _edge[1], _edge[2])
dot.render('Activity graph', view=True)
#Function to return the maximum previous Early Finish
def getMaxPrevEF(activities, predecessors):
max_val = 0
for pred in predecessors:
for act in activities:
if act.activity_name == pred:
if max_val < act.EF:
max_val = act.EF
break
return max_val
def get_freefloat_time(activity, nodes_list):
for node in nodes_list:
if str(node[0]) == str(activity.end_event):
head_slack = abs(node[1]-node[2])
elif str(node[0]) == str(activity.start_event):
tail_slack = abs(node[1]-node[2])
return int(head_slack), int(tail_slack)
def display_table(activities, nodes_list):
print("------------------------------------------------------------------------\n")
df = pd.read_csv('my_csv.csv')
df.insert(5,'ES', 0)
df.insert(6,'EF', 0)
df.insert(7,'LS', 0)
df.insert(8,'LF', 0)
df.insert(9, 'TF', 0)
for i in range(len(activities)):
df.loc[df.index[i], 'Activity'] = activities[i].activity_name
df.loc[df.index[i], 'Predecessors'] = activities[i].predecessors_string
df.loc[df.index[i], 'Duration'] = activities[i].duration
df.loc[df.index[i], 'ES'] = activities[i].ES
df.loc[df.index[i], 'EF'] = activities[i].EF
df.loc[df.index[i], 'LS'] = activities[i].LS
df.loc[df.index[i], 'LF'] = activities[i].LF
activities[i].TF = activities[i].LF - activities[i].EF
df.loc[df.index[i], 'TF'] = activities[i].TF
print(df)
df.to_csv('result.csv')
def get_critical_path(activities, nodes, edges):
p = Node('Activity')
links = []
p.add(Node(activities[0].activity_name, duration=activities[0].duration))
for i in range(1, len(activities)):
p.add(Node(activities[i].activity_name, duration=activities[i].duration, lag=0))
for act in activities:
if act.no_of_predecessors != 0:
if len(act.predecessors_string) > 1:
for pred in act.predecessors:
links.append((pred, act.activity_name))
else:
links.append((act.predecessors_string,act.activity_name))
for lk in links:
if lk[0] != ' ':
p.link(lk[0], lk[1])
p.update_all()
print("Critical Path = ", p.get_critical_path())
print("Critical Path Duration = ", p.duration)
return p.get_critical_path(), p.duration
def solution(CP,CP_duration):
root = Tk()
T = Text(root, height=2, width=30)
T.pack()
CP.append("Total Duration:")
CP.append(CP_duration)
T.insert(END, CP)
mainloop()
if __name__ == '__main__':
data = get_activities()
n = len(data)
activities = []
for i in range(n):
activities.append(activity(data, i))
for i in range(n):
if activities[i].no_of_predecessors == 0:
activities[i].ES = 0
activities[i].EF = activities[i].duration
else:
activities[i].ES = getMaxPrevEF(activities, activities[i].predecessors)
activities[i].EF = activities[i].ES + activities[i].duration
last_value = activities[n-1].EF
nodes, edges = get_graph_attribs(activities)
#Calculate the ES from the first node and put them in the left box
nodes_list = [[nodes[0], 0, 0]]
for i in range(1, len(nodes)):
max = 0
for act in activities:
if (int(act.end_event) == int(nodes[i])):
if(act.ES + act.duration > max):
max = act.ES + act.duration
nodes_list.append([nodes[i], max, max])
'''
for i in range(n-1, -1, -1):
if int(activities[i].end_event) == len(nodes):
activities[i].LF = last_value
else:
min_value = 100000000
for j in range(i+1, n):
if activities[j].start_event == activities[i].end_event:
if activities[j].ES < min_value:
min_value = activities[j].ES
activities[i].LF = min_value
activities[i].LS = activities[i].LF - activities[i].duration
'''
CP, CP_duration = get_critical_path(activities, nodes, edges)
CP = [str(cp) for cp in CP]
print(CP)
node_num = 1
for act in activities:
for node in nodes_list:
if str(act.end_event) == str(node[0]):
act.LF = node[2]
act.LS = act.LF - act.duration
break
nodes, edges = get_graph_attribs(activities)
display_table(activities, nodes_list)
plot_graph(nodes, edges)
solution(CP,CP_duration)