def gene_alg(timelimit, avaliable_sol, fix, gen, per_month_dir=tl.DIR_PER_MONTH, fixed_dir=tl.DIR_PARA + 'fixed/', posibility=0.05): #avaliavle_sol 可行解列表 fix 不能移動的列表 if platform.system() == "Linux": os.system("g++ -o ./tool/c++/score_linux ./tool/c++/score.cpp") main = "./tool/c++/score_linux " print("使用的作業系統為:Linux") elif platform.system() == "Darwin": os.system("g++ -o ./tool/c++/score_mac ./tool/c++/score.cpp") main = "./tool/c++/score_mac " print("使用的作業系統為:Mac") elif platform.system() == "Windows": print("使用的作業系統為:Windows") os.system("g++ -o ./tool/c++/score.exe ./tool/c++/score.cpp") try: open('./tool/c++/score.exe', 'r') except FileNotFoundError: ERROR('找不到score.exe檔案,請用C++編譯生成一個執行檔。') director = str(os.getcwd()).replace("\\", "/") main = director + "/tool/c++/score.exe " A_t = pd.read_csv(fixed_dir + 'fix_class_time.csv', header=0, index_col=0) EMPLOYEE_t = tl.Employee_t Shift_name = tl.CLASS_list nightdaylimit = EMPLOYEE_t['night_perWeek'] year = tl.YEAR month = tl.MONTH nEMPLOYEE = tl.nE nDAY = tl.nD nK = tl.nK nT = tl.nT nR = tl.nR nW = tl.nW mDAY = tl.mDAY DEMAND = tl.DEMAND P0, P1, P2, P3, P4 = tl.P SHIFTset = tl.K_CLASS_set s_break = tl.K_BREAK_set DAY = [tmp for tmp in range(nDAY)] #DAY - 日子集合,J=0,…,nJ-1 DATES = tl.DATE_list #所有的日期 - 對照用 D_WEEK = tl.D_WEEK_set #D_WEEK - 第 w 週中所包含的日子集合 WEEK_of_DAY = tl.WEEK_list #WEEK_of_DAY - 日子j所屬的那一週\ #1 A_t_s = "" for i in A_t.values.tolist(): for j in i: A_t_s += str(j) A_t_s += "," A_t_s += "!" main += A_t_s main += " " #2 Shift_name_s = "" for i in Shift_name: Shift_name_s += i Shift_name_s += "," main += Shift_name_s main += " " #3 nightdaylimit_s = "" for i in nightdaylimit.values.tolist(): nightdaylimit_s += str(i) nightdaylimit_s += "," main += nightdaylimit_s main += " " #4 year_s = str(year) month_s = str(month) nEMPLOYEE_s = str(nEMPLOYEE) nDAY_s = str(nDAY) nK_s = str(nK) nT_s = str(nT) nR_s = str(nR) nW_s = str(nW) mDAY_s = str(mDAY) main += year_s main += " " main += month_s main += " " main += nEMPLOYEE_s main += " " main += nDAY_s main += " " main += nK_s main += " " main += nT_s main += " " main += nR_s main += " " main += nW_s main += " " main += mDAY_s main += " " #13 DEMAND_s = "" for i in DEMAND: for j in i: DEMAND_s += str(j) DEMAND_s += "," DEMAND_s += "!" main += DEMAND_s main += " " #14 P0_s = str(P0) P1_s = str(P1) P2_s = str(P2) P3_s = str(P3) P4_s = str(P4) main += P0_s main += " " main += P1_s main += " " main += P2_s main += " " main += P3_s main += " " main += P4_s main += " " #19 all_s = "" morning_s = "" noon_s = "" night_s = "" phone_s = "" other_s = "" for i in SHIFTset['all']: all_s += str(i) all_s += "," for i in SHIFTset['morning']: morning_s += str(i) morning_s += "," for i in SHIFTset['noon']: noon_s += str(i) noon_s += "," for i in SHIFTset['night']: night_s += str(i) night_s += "," for i in SHIFTset['phone']: phone_s += str(i) phone_s += "," for i in SHIFTset['other']: other_s += str(i) other_s += "," main += all_s main += " " main += morning_s main += " " main += noon_s main += " " main += night_s main += " " main += phone_s main += " " main += other_s main += " " #25 s_break_s = "" for i in s_break: for j in i: s_break_s += str(j) s_break_s += "," s_break_s += "!" main += s_break_s main += " " #26 DAY_s = "" for i in DAY: DAY_s += str(i) DAY_s += "," main += DAY_s main += " " #27 DATES_s = "" for i in DATES: DATES_s += str(i) DATES_s += "," main += DATES_s main += " " #28 D_WEEK_s = "" for i in D_WEEK: for j in i: D_WEEK_s += str(j) D_WEEK_s += "," if len(i) == 0: D_WEEK_s += "," D_WEEK_s += "!" main += D_WEEK_s main += " " #29 WEEK_of_DAY_s = "" for i in WEEK_of_DAY: WEEK_of_DAY_s += str(i) WEEK_of_DAY_s += "," main += WEEK_of_DAY_s main += " " #print(main) shiftset = [] shiftset.extend(SHIFTset['phone']) for i in SHIFTset['not_assigned']: if i in shiftset: shiftset.remove(i) print('per_month_dir =', per_month_dir) i_nb = [] tStart = time.time() #紀錄演算法開始的時間 for p in range(len(avaliable_sol)): #i_nb.append(np.vectorize({v: k for k, v in K_type_dict.items()}.get)(np.array(avaliable_sol[p])).tolist()) i_nb.append(avaliable_sol[p]) score_liz = [] gene_log = [] for i, j in zip(i_nb, fix): score_liz.append((i, j, score(i, main))) score_liz.sort(key=lambda s: s[2]) for i in range(gen): #重複指定的次數 if time.time() - tStart > timelimit: #如果時間已到,就跳出 print('限制時間已至,於第', i, '世代跳出') break score_liz = alg(score_liz, main, nDAY, nEMPLOYEE, shiftset, posibility) if i % 100 == 0: print('\n第', i + 1, '世代最佳分數:', score_liz[0][2], ' Time: ', int(time.time() - tStart), 's') else: sys.stdout.write("\r(" + str(float((i) * 100 / (gen))) + "%)") sys.stdout.flush() gene_log.append([i + 1, time.time() - tStart, score_liz[0][2]]) gene_log = pd.DataFrame(np.array(gene_log), columns=['generation', 'time', 'score']) gene_log.to_csv('gene_log.csv') result = score_liz[0][0] print('\n\n基因演算法最佳解:', score_liz[0][2]) return result
def alg(score_liz, main, nDAY, nEMPLOYEE, shiftset, posibility=0.05): org_len = len(score_liz) #sort = sorted(score_liz, key = lambda s: s[2]) #親代排名 new = np.copy(score_liz[:int(len(score_liz) / 3)]) #取出前1/3 num_list = list(range(len(new))) random.shuffle(num_list) #print(num_list[0],num_list[1], end=' ') union = np.logical_or(new[num_list[0]][1], new[num_list[1]][1]) one_not_avb = union * new[num_list[0]][0] one_avb = new[num_list[0]][0] - one_not_avb two_not_avb = union * new[num_list[1]][0] two_avb = new[num_list[1]][0] - two_not_avb one_org = np.array(new[num_list[0]][0]) #沒有fix的班表 two_org = np.array(new[num_list[1]][0]) #隨機決定切分點 sp_row = random.randint(0, nDAY - 1) sp_col = random.randint(0, nEMPLOYEE - 1) #第一組:依據員工、日期切分 one_col_left = one_avb[:sp_col] one_col_right = one_avb[sp_col:] one_row_up = one_avb.T[:sp_row].T one_row_down = one_avb.T[sp_row:].T one_org_col_left = one_org[:sp_col] one_org_col_right = one_org[sp_col:] one_org_row_up = one_org.T[:sp_row].T one_org_row_down = one_org.T[sp_row:].T #第二組:的切分 two_col_left = two_avb[:sp_col] two_col_right = two_avb[sp_col:] two_row_up = two_avb.T[:sp_row].T two_row_down = two_avb.T[sp_row:].T two_org_col_left = two_org[:sp_col] two_org_col_right = two_org[sp_col:] two_org_row_up = two_org.T[:sp_row].T two_org_row_down = two_org.T[sp_row:].T #將對應的一、二組片段重新組合 #上下黏合 a_one_one_two = np.concatenate( (one_row_up, two_row_down), axis=1) + one_not_avb a_two_one_two = np.concatenate( (one_row_up, two_row_down), axis=1) + two_not_avb a_one_two_one = np.concatenate( (two_row_up, one_row_down), axis=1) + one_not_avb a_two_two_one = np.concatenate( (two_row_up, one_row_down), axis=1) + two_not_avb a_org_one_two = np.concatenate((one_org_row_up, two_org_row_down), axis=1) a_org_two_one = np.concatenate((two_org_row_up, one_org_row_down), axis=1) #左右黏合 b_one_one_two = np.concatenate( (one_col_left, two_col_right), axis=0) + one_not_avb b_two_one_two = np.concatenate( (one_col_left, two_col_right), axis=0) + two_not_avb b_one_two_one = np.concatenate( (two_col_left, one_col_right), axis=0) + one_not_avb b_two_two_one = np.concatenate( (two_col_left, one_col_right), axis=0) + two_not_avb b_org_one_two = np.concatenate((one_org_col_left, two_org_col_right), axis=0) b_org_two_one = np.concatenate((two_org_col_left, one_org_col_right), axis=0) range_num = int(1 / posibility) - 1 #突變 if random.randint(0, range_num) == 0: a_one_one_two[random.randint( 0, a_one_one_two.shape[0] - 1)][random.randint( 0, a_one_one_two.shape[1] - 1)] = random.choice(shiftset) if random.randint(0, range_num) == 0: a_two_one_two[random.randint( 0, a_two_one_two.shape[0] - 1)][random.randint( 0, a_two_one_two.shape[1] - 1)] = random.choice(shiftset) if random.randint(0, range_num) == 0: a_one_two_one[random.randint( 0, a_one_two_one.shape[0] - 1)][random.randint( 0, a_one_two_one.shape[1] - 1)] = random.choice(shiftset) if random.randint(0, range_num) == 0: a_two_two_one[random.randint( 0, a_two_two_one.shape[0] - 1)][random.randint( 0, a_two_two_one.shape[1] - 1)] = random.choice(shiftset) if random.randint(0, range_num) == 0: a_org_one_two[random.randint( 0, a_org_one_two.shape[0] - 1)][random.randint( 0, a_org_one_two.shape[1] - 1)] = random.choice(shiftset) if random.randint(0, range_num) == 0: a_org_two_one[random.randint( 0, a_org_two_one.shape[0] - 1)][random.randint( 0, a_org_two_one.shape[1] - 1)] = random.choice(shiftset) if random.randint(0, range_num) == 0: b_one_one_two[random.randint( 0, b_one_one_two.shape[0] - 1)][random.randint( 0, b_one_one_two.shape[1] - 1)] = random.choice(shiftset) if random.randint(0, range_num) == 0: b_two_one_two[random.randint( 0, b_two_one_two.shape[0] - 1)][random.randint( 0, b_two_one_two.shape[1] - 1)] = random.choice(shiftset) if random.randint(0, range_num) == 0: b_one_two_one[random.randint( 0, b_one_two_one.shape[0] - 1)][random.randint( 0, b_one_two_one.shape[1] - 1)] = random.choice(shiftset) if random.randint(0, range_num) == 0: b_two_two_one[random.randint( 0, b_two_two_one.shape[0] - 1)][random.randint( 0, b_two_two_one.shape[1] - 1)] = random.choice(shiftset) if random.randint(0, range_num) == 0: b_org_one_two[random.randint( 0, b_org_one_two.shape[0] - 1)][random.randint( 0, b_org_one_two.shape[1] - 1)] = random.choice(shiftset) if random.randint(0, range_num) == 0: b_org_two_one[random.randint( 0, b_org_two_one.shape[0] - 1)][random.randint( 0, b_org_two_one.shape[1] - 1)] = random.choice(shiftset) #print(np.zeros(a_org_one_two.shape)) #判斷是否符合 if confirm(a_one_one_two) == 'All constraints are met.': #print('a_one_one_two',a_one_one_two) score_liz.append((a_one_one_two, new[num_list[0]][1], score(a_one_one_two.tolist(), main))) #print(score(a_one_one_two.tolist(), main)) if confirm(a_two_one_two) == 'All constraints are met.': #print('a_two_one_two',a_two_one_two) score_liz.append((a_two_one_two, new[num_list[1]][1], score(a_two_one_two.tolist(), main))) #print(score(a_two_one_two.tolist(), main)) if confirm(a_one_two_one) == 'All constraints are met.': #print('a_one_two_one',a_one_two_one) score_liz.append((a_one_two_one, new[num_list[0]][1], score(a_one_two_one.tolist(), main))) #print(score(a_one_two_one.tolist(), main)) if confirm(a_two_two_one) == 'All constraints are met.': #print('a_two_two_one',a_two_two_one) score_liz.append((a_two_two_one, new[num_list[1]][1], score(a_two_two_one.tolist(), main))) #print(score(a_two_two_one.tolist(), main)) if confirm(a_org_one_two) == 'All constraints are met.': #print('a_org_one_two',a_org_one_two) score_liz.append((a_org_one_two, np.zeros(a_org_one_two.shape), score(a_org_one_two.tolist(), main))) #print(score(a_org_one_two.tolist(), main)) if confirm(a_org_two_one) == 'All constraints are met.': #print('a_org_two_one',a_org_two_one) score_liz.append((a_org_two_one, np.zeros(a_org_two_one.shape), score(a_org_two_one.tolist(), main))) #print(score(a_org_two_one.tolist(), main)) if confirm(b_one_one_two) == 'All constraints are met.': #print('b_one_one_two',b_one_one_two) score_liz.append((b_one_one_two, new[num_list[0]][1], score(b_one_one_two.tolist(), main))) #print(score(b_one_one_two.tolist(), main)) if confirm(b_two_one_two) == 'All constraints are met.': #print('b_two_one_two',b_two_one_two) score_liz.append((b_two_one_two, new[num_list[1]][1], score(b_two_one_two.tolist(), main))) #print(score(b_two_one_two.tolist(), main)) if confirm(b_one_two_one) == 'All constraints are met.': #print('b_one_two_one',b_one_two_one) score_liz.append((b_one_two_one, new[num_list[0]][1], score(b_one_two_one.tolist(), main))) #print(score(b_one_two_one.tolist(), main)) if confirm(b_two_two_one) == 'All constraints are met.': #print('b_two_two_one',b_two_two_one) score_liz.append((b_two_two_one, new[num_list[1]][1], score(b_two_two_one.tolist(), main))) #print(score(b_two_two_one.tolist(), main)) if confirm(b_org_one_two) == 'All constraints are met.': #print('b_org_one_two',b_org_one_two) score_liz.append((b_org_one_two, np.zeros(b_org_one_two.shape), score(b_org_one_two.tolist(), main))) #print(score(b_org_one_two.tolist(), main)) if confirm(b_org_two_one) == 'All constraints are met.': #print('b_org_two_one',b_org_two_one) score_liz.append((b_org_two_one, np.zeros(b_org_two_one.shape), score(b_org_two_one.tolist(), main))) #print(score(b_org_two_one.tolist(), main)) # sort = sorted(sort, key = lambda s: s[2],reverse = True) #sort = sorted(sort, key = lambda s: s[2]) score_liz.sort(key=lambda s: s[2]) #print(len(sort)) #score_liz = score_liz[:len(score_liz)] #print(sort) #print(len(sort)) return score_liz[:org_len]