11#!/usr/bin/env python
22# -*- coding: utf-8 -*-
33
4+ from functools import lru_cache
45from itertools import permutations
6+
57import numpy as np
6- from functools import lru_cache
8+
79from 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
403469if __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