Skip to content

Commit 867dada

Browse files
committed
Implements CDS heuristic and adds new johnson's variation
1 parent 09a8915 commit 867dada

File tree

1 file changed

+73
-13
lines changed

1 file changed

+73
-13
lines changed

flowshop.py

Lines changed: 73 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#!/usr/bin/env python
22
# -*- coding: utf-8 -*-
33

4+
from functools import lru_cache
45
from itertools import permutations
6+
57
import numpy as np
6-
from functools import lru_cache
8+
79
from geneticFunctions import *
810

911

@@ -30,7 +32,7 @@ def __init__(self, data=None, nb_machines=2, nb_jobs=6):
3032
self.nb_machines, self.nb_jobs).get_data()
3133

3234
def solve_johnson(self):
33-
"""Solves a permutation flowshop problem using johnson's rule for a permutation problem of 2 machines and N jobs
35+
"""Solves a permutation flowshop problem using johnson's rule for a permutation problem of 2 machines and N jobs
3436
3537
Raises:
3638
Exception: Raises exception when given a problem with more than 2 machines
@@ -98,8 +100,72 @@ def johnson_seq(data):
98100
seq = machine_1_sequence + machine_2_sequence
99101
return seq
100102

103+
@staticmethod
104+
def johnson_seq_var_2(data):
105+
job_count = len(data)
106+
job_ids = list(range(0, job_count))
107+
108+
l1 = []
109+
l2 = []
110+
for job_info in sorted(zip(job_ids, data), key=lambda t: min(t[1])):
111+
job_id = job_info[0]
112+
job_times = job_info[1]
113+
if job_times[0] < job_times[1]:
114+
l1.append(job_id)
115+
else:
116+
l2.insert(0, job_id)
117+
118+
return l1 + l2
119+
120+
121+
101122
def cds(self):
102-
raise NotImplementedError
123+
if type(self.data) is not np.ndarray:
124+
data_ndarray = np.array(self.data)
125+
else:
126+
data_ndarray = self.data
127+
data_transposed = data_ndarray.T
128+
merged_times = [[0, sum(j_t)] for j_t in data_transposed]
129+
perms = []
130+
for i in range(0, self.nb_machines-1):
131+
for j in range(0, self.nb_jobs):
132+
merged_times[j][0] += data_transposed[j][i]
133+
merged_times[j][1] -= data_transposed[j][i]
134+
perms.append(Flowshop.johnson_seq_var_2(merged_times))
135+
136+
seq = min(perms, key=lambda p: self._get_makespan(p, self.data))
137+
138+
schedules = np.zeros((self.nb_machines, self.nb_jobs), dtype=dict)
139+
# schedule first job alone first
140+
task = {"name": "job_{}".format(
141+
seq[0]+1), "start_time": 0, "end_time": self.data[0][seq[0]]}
142+
schedules[0][0] = task
143+
for m_id in range(1, self.nb_machines):
144+
start_t = schedules[m_id-1][0]["end_time"]
145+
end_t = start_t + self.data[m_id][0]
146+
task = {"name": "job_{}".format(
147+
seq[0]+1), "start_time": start_t, "end_time": end_t}
148+
schedules[m_id][0] = task
149+
150+
for index, job_id in enumerate(seq[1::]):
151+
start_t = schedules[0][index]["end_time"]
152+
end_t = start_t + self.data[0][job_id]
153+
task = {"name": "job_{}".format(
154+
job_id+1), "start_time": start_t, "end_time": end_t}
155+
schedules[0][index+1] = task
156+
for m_id in range(1, self.nb_machines):
157+
start_t = max(schedules[m_id][index]["end_time"],
158+
schedules[m_id-1][index+1]["end_time"])
159+
end_t = start_t + self.data[m_id][job_id]
160+
task = {"name": "job_{}".format(
161+
job_id+1), "start_time": start_t, "end_time": end_t}
162+
schedules[m_id][index+1] = task
163+
max_mkspn = int(schedules[self.nb_machines-1][-1]["end_time"])
164+
return seq, schedules, max_mkspn
165+
166+
167+
168+
103169

104170
def palmer_heuristic(self):
105171
"""solves an N machines M jobs pfsp problem using Palmer's Heuristic
@@ -401,15 +467,9 @@ def get_problem_instance(self):
401467

402468

403469
if __name__ == "__main__":
404-
random_problem = RandomFlowshop(4, 5)
470+
random_problem = RandomFlowshop(3, 8)
405471
random_problem_instance = random_problem.get_problem_instance()
406-
seq, _, g_mkspan = random_problem_instance.genetic_algorithm()
472+
seq = random_problem_instance.cds()
407473
b_seq, b_scheds, b_opt_makespan = random_problem_instance.brute_force_exact()
408-
print(type(seq))
409-
print(type(seq[0]))
410-
print(b_opt_makespan, g_mkspan)
411-
# print(seq)
412-
#print("Brute Force: {}, Palmer heuristic: {}".format(b_seq, seq))
413-
#seq, jobs, opt_makespan = random_problem_instance.solve_johnson()
414-
# print("Sequence: {} \nJobs on Machine 1: \n {} \n Jobs on machine 2:\n {} \n".format(
415-
# seq, jobs[0], jobs[1]))
474+
cds_seq, cds_scheds, cds_makespan = random_problem_instance.cds()
475+
print("[Bruteforce] makespan: {} \n [CDS] makespan: {}".format(b_opt_makespan, cds_makespan))

0 commit comments

Comments
 (0)