Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b67f47e

Browse files
Adds NEH Implementation to flowshop methods
1 parent e729b04 commit b67f47e

File tree

1 file changed

+98
-36
lines changed

1 file changed

+98
-36
lines changed

‎flowshop.py‎

Lines changed: 98 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -129,47 +129,108 @@ def palmer_f(x): return -(self.nb_machines - (2*x - 1))
129129
opt_makespan = int(schedules[self.nb_machines-1][-1]["end_time"])
130130
return h_seq, schedules, opt_makespan
131131

132-
def neh(self):
133-
raise NotImplementedError
132+
def _get_makespan(self, seq, data):
133+
c = np.zeros((self.nb_machines, len(seq)), dtype=object)
134+
c[0][0] = (0, data[0][seq[0]])
135+
for m_id in range(1, self.nb_machines):
136+
s_t = c[m_id-1][0][1]
137+
e_t = s_t + data[m_id][0]
138+
c[m_id][0] = (s_t, e_t)
139+
if len(seq) > 1:
140+
for i, job_id in enumerate(seq[1::]):
141+
s_t = c[0][i][1]
142+
e_t = s_t + data[0][job_id]
143+
c[0][i+1] = (s_t, e_t)
144+
for m_id in range(1, self.nb_machines):
145+
s_t = max(c[m_id][i][1], c[m_id-1][i+1][1])
146+
e_t = s_t + data[m_id][job_id]
147+
c[m_id][i+1] = (s_t, e_t)
148+
149+
return c[self.nb_machines-1][-1][1]
150+
151+
152+
def neh_heuristic(self):
153+
sums = []
154+
for job_id in range(self.nb_jobs):
155+
p_ij = sum([self.data[j][job_id]
156+
for j in range(self.nb_machines)])
157+
sums.append((job_id, p_ij))
158+
sums.sort(key=lambda x: x[1], reverse=True)
159+
order_seq = [x[0] for x in sums]
160+
seq = [order_seq[0]]
161+
for i in range(1, self.nb_jobs):
162+
min_mkspan = float("inf")
163+
for j in range(0, i+1):
164+
tempo_seq = seq[:]
165+
tempo_seq.insert(j, order_seq[i])
166+
max_mkspn = self._get_makespan(tempo_seq, self.data)
167+
if min_mkspan > max_mkspn:
168+
max_mkspn = min_mkspan
169+
b_seq = tempo_seq
170+
seq = b_seq
171+
172+
schedules = np.zeros((self.nb_machines, self.nb_jobs), dtype=dict)
173+
# schedule first job alone first
174+
task = {"name": "job_{}".format(
175+
seq[0]+1), "start_time": 0, "end_time": self.data[0][seq[0]]}
176+
schedules[0][0] = task
177+
for m_id in range(1, self.nb_machines):
178+
start_t = schedules[m_id-1][0]["end_time"]
179+
end_t = start_t + self.data[m_id][0]
180+
task = {"name": "job_{}".format(
181+
seq[0]+1), "start_time": start_t, "end_time": end_t}
182+
schedules[m_id][0] = task
183+
184+
for index, job_id in enumerate(seq[1::]):
185+
start_t = schedules[0][index]["end_time"]
186+
end_t = start_t + self.data[0][job_id]
187+
task = {"name": "job_{}".format(
188+
job_id+1), "start_time": start_t, "end_time": end_t}
189+
schedules[0][index+1] = task
190+
for m_id in range(1, self.nb_machines):
191+
start_t = max(schedules[m_id][index]["end_time"],
192+
schedules[m_id-1][index+1]["end_time"])
193+
end_t = start_t + self.data[m_id][job_id]
194+
task = {"name": "job_{}".format(
195+
job_id+1), "start_time": start_t, "end_time": end_t}
196+
schedules[m_id][index+1] = task
197+
198+
max_mkspn = int(schedules[self.nb_machines-1][-1]["end_time"])
199+
return seq, schedules, max_mkspn
200+
134201

135202
@lru_cache(maxsize=128)
136203
def brute_force_exact(self):
137204
jobs_perm = permutations(range(self.nb_jobs))
138-
opt_makespan = float("inf")
139-
for seq in jobs_perm:
140-
schedules = np.zeros((self.nb_machines, self.nb_jobs), dtype=dict)
205+
seq = min(jobs_perm, key=lambda x: self._get_makespan(x, self.data))
206+
schedules = np.zeros((self.nb_machines, self.nb_jobs), dtype=dict)
141207
# schedule first job alone first
208+
task = {"name": "job_{}".format(
209+
seq[0]+1), "start_time": 0, "end_time": self.data[0][seq[0]]}
210+
schedules[0][0] = task
211+
for m_id in range(1, self.nb_machines):
212+
start_t = schedules[m_id-1][0]["end_time"]
213+
end_t = start_t + self.data[m_id][0]
142214
task = {"name": "job_{}".format(
143-
seq[0]+1), "start_time": 0, "end_time": self.data[0][seq[0]]}
144-
schedules[0][0] = task
145-
for m_id in range(1, self.nb_machines):
146-
start_t = schedules[m_id-1][0]["end_time"]
147-
end_t = start_t + self.data[m_id][0]
148-
task = {"name": "job_{}".format(
149-
seq[0]+1), "start_time": start_t, "end_time": end_t}
150-
schedules[m_id][0] = task
215+
seq[0]+1), "start_time": start_t, "end_time": end_t}
216+
schedules[m_id][0] = task
151217

152-
for index, job_id in enumerate(seq[1::]):
153-
start_t = schedules[0][index]["end_time"]
154-
end_t = start_t + self.data[0][job_id]
218+
for index, job_id in enumerate(seq[1::]):
219+
start_t = schedules[0][index]["end_time"]
220+
end_t = start_t + self.data[0][job_id]
221+
task = {"name": "job_{}".format(
222+
job_id+1), "start_time": start_t, "end_time": end_t}
223+
schedules[0][index+1] = task
224+
for m_id in range(1, self.nb_machines):
225+
start_t = max(schedules[m_id][index]["end_time"],
226+
schedules[m_id-1][index+1]["end_time"])
227+
end_t = start_t + self.data[m_id][job_id]
155228
task = {"name": "job_{}".format(
156229
job_id+1), "start_time": start_t, "end_time": end_t}
157-
schedules[0][index+1] = task
158-
for m_id in range(1, self.nb_machines):
159-
start_t = max(schedules[m_id][index]["end_time"],
160-
schedules[m_id-1][index+1]["end_time"])
161-
end_t = start_t + self.data[m_id][job_id]
162-
task = {"name": "job_{}".format(
163-
job_id+1), "start_time": start_t, "end_time": end_t}
164-
schedules[m_id][index+1] = task
165-
makespan = int(schedules[self.nb_machines-1][-1]["end_time"])
166-
if makespan < opt_makespan:
167-
opt_makespan = makespan
168-
best_schedule = np.copy(schedules)
169-
best_seq = np.copy(seq)
230+
schedules[m_id][index+1] = task
231+
makespan = int(schedules[self.nb_machines-1][-1]["end_time"])
170232

171-
return best_seq, best_schedule, opt_makespan
172-
233+
return seq, schedules, makespan
173234

174235

175236
class RandomFlowshop:
@@ -184,7 +245,7 @@ class RandomFlowshop:
184245
def __init__(self, nb_machines, nb_jobs):
185246
self.nb_machines = nb_machines
186247
self.nb_jobs = nb_jobs
187-
self.data = self.get_random_p_times(100)
248+
self.data = self.get_random_p_times(10)
188249

189250
def get_random_p_times(self, p_times_ub):
190251
"""
@@ -242,12 +303,13 @@ def get_problem_instance(self):
242303

243304

244305
if __name__ == "__main__":
245-
random_problem = RandomFlowshop(6, 8)
306+
random_problem = RandomFlowshop(5, 8)
246307
random_problem_instance = random_problem.get_problem_instance()
247-
seq, scheds, opt_makespan = random_problem_instance.palmer_heuristic()
308+
seq, neh_sched, mkspn = random_problem_instance.neh_heuristic()
248309
b_seq, b_scheds, b_opt_makespan = random_problem_instance.brute_force_exact()
249-
250-
print("Brute Force: {}, Palmer heuristic: {}".format(b_opt_makespan, opt_makespan))
310+
print(b_opt_makespan, mkspn)
311+
#print(seq)
312+
#print("Brute Force: {}, Palmer heuristic: {}".format(b_seq, seq))
251313

252314
#seq, jobs, opt_makespan = random_problem_instance.solve_johnson()
253315
# print("Sequence: {} \nJobs on Machine 1: \n {} \n Jobs on machine 2:\n {} \n".format(

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /