1+ # Implementasi Algoritma Penjadwalan Genetic-Algorithm
2+ # 1. Impor modul eksternal
3+ import csv
4+
5+ # 2. Definisi variabel global
6+ ROUTING = []
7+ PROCESSING_TIME = []
8+ MESIN = []
9+ JOB_DONE = []
10+ SCHEDULE = []
11+
12+ # 3. Prosedur untuk melakukan pembacaan data dari file
13+ def read_data ():
14+ # Menggunakan variabel global
15+ global ROUTING , PROCESSING_TIME , MESIN
16+ print ("Sedang membaca data..." )
17+
18+ # Pembacaan data mesin dari file dan exception handling
19+ try :
20+ mesin_file = open (f"test3/Mesin.txt" , "r" )
21+ except :
22+ print (f"File Mesin.txt tidak ditemukan!" )
23+ exit ()
24+
25+ # Konversi ke tabel
26+ mesin_data = csv .reader (mesin_file )
27+
28+ # Pengolahan isi tabel
29+ for row in mesin_data :
30+ for i in range (len (row )):
31+ row [i ] = float (row [i ])
32+ if row [i ] % 1.0 == 0 :
33+ row [i ] = int (row [i ])
34+ MESIN .append (row )
35+
36+ print ("Data mesin berhasil dibaca!" )
37+
38+ # Pembacaan data job dari file
39+ n_jobs = int (input ("Masukkan jumlah job: " ))
40+ for j in range (n_jobs ):
41+ # Exception handling
42+ try :
43+ time_file = open (f"test3/Job{ j + 1 } _Time.txt" , "r" )
44+ except :
45+ print (f"File Job{ j + 1 } _Time.txt tidak ditemukan!" )
46+ exit ()
47+
48+ # Konversi ke tabel
49+ time_data = csv .reader (time_file )
50+
51+ # Pengolahan isi tabel
52+ for row in time_data :
53+ for i in range (len (row )):
54+ row [i ] = float (row [i ])
55+ if row [i ] % 1.0 == 0 :
56+ row [i ] = int (row [i ])
57+ PROCESSING_TIME .append (row )
58+
59+ # Exception handling
60+ try :
61+ routing_file = open (f"test3/Job{ j + 1 } _Routing.txt" , "r" )
62+ except :
63+ print (f"File Job{ j + 1 } _Routing.txt tidak ditemukan!" )
64+ exit ()
65+
66+ # Konversi ke tabel
67+ routing_data = csv .reader (routing_file )
68+
69+ # Pengolahan isi tabel
70+ for row in routing_data :
71+ for i in range (len (row )):
72+ row [i ] = float (row [i ])
73+ if row [i ] % 1.0 == 0 :
74+ row [i ] = int (row [i ])
75+ ROUTING .append (row )
76+
77+ print ("Data time dan routing berhasil dibaca!" )
78+
79+ # 4. Prosedur Eksekusi
80+ def do_genetic_algo ():
81+ # xx. Menggunakan variabel global
82+ global MESIN , JOB_DONE , SCHEDULE , CJ , TJ , RJ , ST
83+
84+ # a. Mengambil nilai cj terkecil dari data masukan, job dengan cj terkecil akan diproses duluan
85+ min_c = min (CJ )
86+
87+ # b. Inisiasi senarai temporari
88+ temp_list = []
89+
90+ # c. Kalau misal ada lebih dari 1 yang punya nilai minimum, digunakan skema penanganan
91+ if CJ .count (min_c ) > 1 :
92+ # Inisiasi senarai yang berisi semua job dengan nilai min_c
93+ index_c_in_cj = [i for i in range (len (CJ )) if CJ [i ] == min_c ]
94+
95+ # Cek nilai rj dan pilih yang mempunyai nilai rj terkecil
96+ # Prioritaskan yang jumlah operasinya masih banyak
97+ machine_list = [] # machine list
98+
99+ # Isi list dengan semua data yang ada di index_c_in_cj
100+ for i in index_c_in_cj :
101+ # Kalau belum ada di machine list, tambahkan
102+ if len (temp_list ) == 0 or ST [i ][2 ] not in machine_list :
103+ temp_list .append (ST [i ])
104+ machine_list .append (ST [i ][2 ])
105+ # print("masuk sini?", ST[i][2])
106+ print ("i, stvals" , i , ST [i ][2 ])
107+ mach_on_ST = []
108+ # print("ST", ST)
109+ for k in range (len (ST )):
110+ mach_on_ST .append (ST [k ][2 ])
111+ k = mach_on_ST .index (ST [i ][2 ])
112+ MESIN [0 ][ST [i ][2 ] - 1 ] = RJ [k ]
113+ print ("ST" , ST )
114+ # Kalau sudah ada, lakukan filtering sesuai kriteria diatas
115+ elif ST [i ][2 ] in machine_list :
116+ index_mac = machine_list .index (ST [i ][2 ])
117+ job = ST [i ][0 ]
118+ # Kalo mesinnya kosong, atau bisa selesai lebih cepat, masukin di
119+ # tempat yang memungkinkan, proses genetikasi
120+ if (ST [i ][2 ] >= 1 and ST [i ][2 ] <= 4 ):
121+ minimum = MESIN [0 ][0 ]
122+ idx_mesin = 0
123+ for j in range (4 ):
124+ if (minimum > MESIN [0 ][j ]):
125+ idx_mesin = j
126+ minimum = MESIN [0 ][j ]
127+
128+ if (MESIN [0 ][ST [i ][2 ] - 1 ] > minimum ):
129+ ST [job - 1 ] = [job , ST [job - 1 ][1 ], idx_mesin + 1 ]
130+ temp_list .append (ST [job - 1 ])
131+
132+ print ("ST" , ST )
133+ elif (ST [i ][2 ] >= 5 and ST [i ][2 ] <= 6 ):
134+ minimum = MESIN [0 ][4 ]
135+ idx_mesin = 0
136+ for j in range (4 , 5 ):
137+ if (minimum > MESIN [0 ][j ]):
138+ idx_mesin = j
139+ minimum = MESIN [0 ][j ]
140+
141+ if (MESIN [0 ][ST [i ][2 ] - 1 ] > minimum ):
142+ ST [i ] = [job , ST [i ][1 ], idx_mesin + 1 ]
143+ temp_list .append (ST [i ])
144+ else :
145+ # Prioritas nilai rj
146+ if (RJ [i ] < RJ [ST .index (temp_list [index_mac ])]):
147+ temp_list [index_mac ] = ST [i ]
148+ # Prioritas jumlah operasi
149+ elif ST [i ][1 ] < temp_list [index_mac ][1 ]:
150+ temp_list [index_mac ] = ST [i ]
151+
152+ MESIN [0 ][ST [i ][2 ] - 1 ] = RJ [ST [i ][2 ] - 1 ]
153+
154+ # Sekarang temp_list isinya job yang mau dijalankan (dalam sebuah list)
155+ retval = temp_list
156+
157+ # Kalau tidak, kembalikan saja nilai st dari cj tersebut dalam sebuah list
158+ else :
159+ retval = [ST [CJ .index (min_c )]]
160+
161+ # d. Melakukan indexing terhadap jadwal yang ada dan telah selesai
162+ print ("retval?" , retval )
163+ job = []
164+ instance = []
165+ machine = []
166+ for i in range (len (retval )):
167+ job .append (retval [i ][0 ])
168+ instance .append (retval [i ][1 ])
169+ machine .append (retval [i ][2 ])
170+
171+ print ("job, retval" , job , machine )
172+ job_on_ST = []
173+ # print("ST", ST)
174+ for i in range (len (ST )):
175+ job_on_ST .append (ST [i ][0 ])
176+
177+ print ("job_on_st" , job_on_ST )
178+ for value in job :
179+ i = job_on_ST .index (value )
180+ print ("i" , i )
181+ SCHEDULE .append ([ST [i ][0 ], ST [i ][1 ], ST [i ][2 ], CJ [i ], RJ [i ]])
182+ if ST [i ][1 ] == len (ROUTING [ST [i ][0 ] - 1 ]):
183+ JOB_DONE .append ([ST [i ][0 ], RJ [i ]])
184+
185+ # e. Lanjutan pemrosesan indexing untuk dikemas dalam senarai job dan machine
186+ index_job = [job_on_ST .index (value ) for value in job ]
187+ index_mac = machine
188+
189+ # f. Melakukan penyalinan nilai st dan cj untuk digunakan lebih lanjut pada bagian bawah
190+ COPY_OF_ST = [i for i in ST ]
191+ COPY_OF_CJ = [i for i in CJ ]
192+
193+ # g. Melakukan perubahan terhadap nilai isi mesin, tj dan st
194+ # bias untuk membantu skema penghapusan berdasar indeks
195+ bias = 0
196+ for i , j in zip (index_job , index_mac ):
197+ # Memperbaharui nilai MESIN
198+ # MESIN[0][j] = RJ[i]
199+ try :
200+ # Memperbaharui nilai tj
201+ TJ [i ] = PROCESSING_TIME [ST [i ][0 ] - 1 ][ST [i ][1 ]]
202+ # Memperbaharui nilai st
203+ ST [i ] = [ST [i ][0 ], ST [i ][1 ] + 1 , ROUTING [ST [i ][0 ] - 1 ][ST [i ][1 ]]]
204+ except :
205+ # Exception handling jika tidak ada, maka saatnya dihapus
206+ TJ .pop (i - bias )
207+ ST .pop (i - bias )
208+ CJ .pop (i - bias )
209+ bias += 1
210+
211+ # h. Memperbaharui nilai cj pada COPY_OF_CJ (salinan cj)
212+ for i in range (len (COPY_OF_ST )):
213+ try :
214+ # Jika nilai iterator berada pada index_job,
215+ # maka update dengan nilai data proses selanjutnya, lakukan perbandingan dengan
216+ # nilai proses pada mesin
217+ if i in index_job :
218+ ready_time = MESIN [0 ][ST [i ][2 ] - 1 ]
219+ recent_rjx = RJ [i ]
220+ if COPY_OF_ST [i ][1 ] != len (ROUTING [COPY_OF_ST [i ][0 ] - 1 ]):
221+ if ready_time > recent_rjx :
222+ COPY_OF_CJ [i ] = ready_time
223+ else :
224+ COPY_OF_CJ [i ] = recent_rjx
225+ # Jika tidak ada, lakukan pembaharuan dengan nilai yang ada di mesin
226+ # Mengingat tidak ada job yang saling overlap
227+ else :
228+ if (COPY_OF_CJ [i ] <= MESIN [0 ][COPY_OF_ST [i ][2 ] - 1 ]):
229+ COPY_OF_CJ [i ] = MESIN [0 ][COPY_OF_ST [i ][2 ] - 1 ]
230+ except :
231+ # Exception handling, skip jika tidak memenuhi kondisi diatas
232+ continue
233+
234+ # i. Pembahruan terhadap nilai cj berdasar pemrosesan COPY_OF_CJ dan COPY_OF_ST
235+ # dilakukan hanya jika panjang keduanya sudah beda (akibat proses penghapusan)
236+ if (len (CJ ) < len (COPY_OF_CJ )):
237+ for i in range (len (COPY_OF_CJ ) - 1 , - 1 , - 1 ):
238+ # Proses penyesuaian dengan cj yang sudah baru dengan menghapus
239+ if i in index_job and COPY_OF_ST [i ][1 ] == len (ROUTING [COPY_OF_ST [i ][0 ] - 1 ]):
240+ COPY_OF_CJ .pop (i )
241+ else :
242+ continue
243+
244+ # Penyalinan kembali nilai cj yang telah diperbaharui
245+ CJ = COPY_OF_CJ
246+
247+ print ("fin cj" , CJ )
248+
249+ # j. Pembaharuan terhadap nilai rj
250+ RJ = [0 for i in range (len (ST ))]
251+ for i in range (len (ST )):
252+ RJ [i ] = CJ [i ] + TJ [i ]
253+
254+ # k. Pengembalian nilai ST apakah sudah kosong (semua job sudah diproses)
255+ return ST
256+
257+ # 5. Melakukan pencetakan form hasil pemrosesan ke terminal
258+ def print_schedule (schedule = SCHEDULE , lateness = None ):
259+ global PROCESSING_TIME
260+ makespan = max (schedule , key = lambda x : x [4 ])[4 ]
261+ for i in range (len (PROCESSING_TIME )):
262+ j = max (filter (lambda a : a [0 ] == i + 1 , schedule ), key = lambda x : x [4 ])[4 ]
263+ print (f'Job { i + 1 } telah selesai dengan waktu selesai { round (j ,2 )} ' )
264+ for s in sorted (schedule , key = lambda x : x [0 ]):
265+ if s [0 ] == i + 1 :
266+ print (f'{ s [0 ]} { s [1 ]} { s [2 ]} : Start { round (s [3 ],2 )} End { round (s [4 ],2 )} ' )
267+ if lateness is not None :
268+ print (f"Earliness: { round (lateness [i ],2 ) * - 1 } " if lateness [i ] <= 0 else f"Tardiness: { round (lateness [i ],2 )} " )
269+ print (f'---\n makespan: { round (makespan ,2 )} ' )
270+
271+ # 6. Program utama
272+ if __name__ == '__main__' :
273+ # xx. Membaca data
274+ read_data ()
275+
276+ # a. Mendefinisikan posisi melalui routing
277+ CJ = [MESIN [0 ][ROUTING [i ][0 ] - 1 ] for i in range (len (ROUTING ))]
278+
279+ # b. Mendefinisikan waktu pemrosesan
280+ TJ = [PROCESSING_TIME [i ][0 ] for i in range (len (ROUTING ))]
281+
282+ # c. Mendefinisikan waktu berakhir
283+ RJ = [0 for i in range (len (ROUTING ))]
284+ for i in range (len (ROUTING )):
285+ RJ [i ] = CJ [i ] + TJ [i ]
286+
287+ # d. Mendefinisikan id st (job, operasi, mesin)
288+ ST = [[i + 1 , 1 , ROUTING [i ][0 ]] for i in range (len (ROUTING ))]
289+
290+ # e. Melakukan pemrosesan pembuatan jadwal
291+ # Proses selesai dilaksanakan jika semua job selesai terjadwal
292+ print ("Pemrosesan sedang dilakukan..." )
293+ print ("===== initial check ======" )
294+ print ("mesin " , MESIN )
295+ print ("processing_time " , PROCESSING_TIME )
296+ print ("routing " , ROUTING )
297+ print ("CJ" , CJ )
298+ print ("TJ" , TJ )
299+ print ("RJ" , RJ )
300+ print ("ST" , ST )
301+ print ("----lesgo-----" )
302+ while do_genetic_algo () != []:
303+ print ("===== initial check ======" )
304+ print ("mesin " , MESIN )
305+ print ("processing_time " , PROCESSING_TIME )
306+ print ("routing " , ROUTING )
307+ print ("CJ" , CJ )
308+ print ("TJ" , TJ )
309+ print ("RJ" , RJ )
310+ print ("ST" , ST )
311+ print ("----lesgo-----" )
312+ pass
313+
314+ # f. Semua job seledai dan hasil dicetak pada terminal
315+ print ('\n ---- Semua job telah selesai ----' )
316+ print_schedule ()
317+
318+
319+ input ("\n Press Enter to Exit" )
0 commit comments