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