-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
144 lines (121 loc) · 4.5 KB
/
main.py
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
import pandas as pd
from pymoo.algorithms.soo.nonconvex.ga import GA
from gen_order_data import gen_order_data
from job_shop_scheduling_problem import JSSP
from pymoo.optimize import minimize
from pymoo.termination import get_termination
from JSSP_initialization import JSSP_initial
import matplotlib.pyplot as plt
import plotly as py
import plotly.express as px
import plotly.figure_factory as ff
import datetime
pyplt = py.offline.plot
import time
import os
from JSSP_operator import *
if __name__ == "__main__":
cur_time = datetime.datetime.now().strftime("%Y-%m-%d %H")
dt = datetime.datetime.strptime(cur_time, "%Y-%m-%d %H")
print(cur_time)
t1 = time.time()
# problem
job_list = ["A"] * 5 + ["B"] * 5 + ["C"] * 5 + ["D"] * 2
proc_data, ope_num_list, proc_tab_array = gen_order_data(job_list)
ins_data = (proc_data, ope_num_list)
problem = JSSP(ins_data)
# initialize population
Pop_size = 100
X = JSSP_initial(problem, Pop_size)
# algorithm
algorithm = GA(
pop_size=100,
sampling=X,
crossover=JSSP_Crossover(pc=0.8, problem=problem),
mutation=JSSP_Mutation(pm=0.05, problem=problem),
eliminate_duplicates=True)
termination = get_termination("n_gen", 10)
# optimize process
res = minimize(problem,
algorithm,
termination,
seed=1,
save_history=True,
verbose=True)
t2 = time.time()
spend_time = t2 - t1
F = res.F
optim_solution = res.X
print(f"optimized makespan: {F[0]}, spend time: {spend_time}")
# plot res
hist = res.history
n_iter = [] # corresponding number of function evaluations\
Fitness = [] # the objective space values in each generation
for idx, algo in enumerate(hist):
n_iter.append(idx)
opt = algo.opt
Fitness.append(opt.get("F")[0])
plt.figure(figsize=(7, 5))
plt.plot(n_iter, Fitness, color='black', lw=0.7, label="Avg. CV of Pop")
plt.scatter(n_iter, Fitness, facecolor="none", edgecolor='black', marker="p")
plt.title("Convergence")
plt.xlabel("Function iteration")
plt.ylabel("makespan")
plt.show()
# plot gantt
problem = JSSP(ins_data)
optim_makespan = problem.decode(optim_solution)
mch_proc_info = dict()
for i in range(problem.JS.m):
mch_proc_info[f"M {i+1}"] = []
gantt_data = []
job_type_num_dict = {
"A": 0,
"B": 0,
"C": 0,
"D": 0,
}
for job_idx, job in enumerate(problem.JS.Jobs):
job_type = job_list[job_idx]
job_type_num_dict[job_type] += 1
op_idx = 1
for m_idx, start, end in zip(job._on, job.start, job.end):
task = f"task {job_type}{job_type_num_dict[job_type]}"
task_ = task + f"-{op_idx}"
mch_proc_info[f"M {m_idx + 1}"].append([task_,
start,
end])
op_idx += 1
start_ = (dt + datetime.timedelta(minutes=start)).strftime("%Y-%m-%d %H")
end_ = (dt + datetime.timedelta(minutes=end)).strftime("%Y-%m-%d %H")
gantt_data.append(dict(Task=task, Start=start_, Finish=end_, Resource=f"Machine {m_idx + 1}"))
df = pd.DataFrame(gantt_data)
# fig = ff.create_gantt(df, index_col='')
fig = px.timeline(df, x_start="Start", x_end="Finish", y="Resource", color="Task")
fig.update_yaxes(autorange="reversed") # otherwise tasks are listed from the bottom up
fig.show()
if not os.path.exists("images"):
os.mkdir("images")
fig.write_image("images/fig1.png")
output = ""
for key, machine_info in mch_proc_info.items():
# Sort by starting time.
# if len(machine_info) == 0:
# continue
machine_info = sorted(machine_info, key= lambda x: x[1])
sol_line_tasks = "Machine " + str(key[2:]) + ": "
sol_line = " "
for assigned_task in machine_info:
name = assigned_task[0]
# Add spaces to output to align columns.
sol_line_tasks += f"{name:15}"
start = assigned_task[1]
duration = assigned_task[2] - assigned_task[1]
sol_tmp = f"[{start},{start + duration}]"
# Add spaces to output to align columns.
sol_line += f"{sol_tmp:15}"
sol_line += "\n"
sol_line_tasks += "\n"
output += sol_line_tasks
output += sol_line
print(output)