def truck_ride_cost(locations: List, num_truck: int): # zwraca koszt dla jednej śmieciarki Raportowanie.used_function('truck_ride_cost') # print(locations) if locations == []: return 0 trucks_returns[num_truck] = 0 trucks_filled_volume = [0] * len(trucks_volume) ride_cost = bin_locations[0][locations[0]] # od bazy 0 do pierwszego na liscie # Dodanie kosztu uruchomienia ride_cost += koszty_uruchomienia_smieciarki[num_truck] mnoznik_zalezny_pojemnosci = trucks_volume[num_truck]/max(trucks_volume) powrotow = 0 for i in range(0, len(locations)): trucks_filled_volume[num_truck] += rubbish_in_location[locations[i]] # zaladowanie smieci if i + 1 >= len(locations): # jesli ostatni ride_cost += bin_locations[locations[i]][0] * mnoznik_zalezny_pojemnosci return ride_cost if trucks_volume[num_truck] < trucks_filled_volume[num_truck] + rubbish_in_location[locations[i+1]]: # wroc do bazy jesli smieciarka pelna powrotow += 1 ride_cost += bin_locations[locations[i]][0] * mnoznik_zalezny_pojemnosci trucks_filled_volume[num_truck] = 0 ride_cost += bin_locations[0][locations[i + 1]] * mnoznik_zalezny_pojemnosci trucks_returns[num_truck] = trucks_returns[num_truck] + 1 # Dodanie Kosztu rozladnuku # ride_cost += (powrotow - 1)**2 * koszty_rozladunku_smieciarki[num_truck] ride_cost += powrotow**3 * koszty_rozladunku_smieciarki[num_truck] else: ride_cost += bin_locations[locations[i]][locations[i + 1]] * mnoznik_zalezny_pojemnosci return ride_cost
def ch_connect_close(_solution: List): Raportowanie.used_function('ch_connect_close') new_solution = deepcopy(_solution) #print("\nnewsolution: ", new_solution) random_truck = random.randint(0, len(new_solution)-1) #print("random_truck",random_truck) if len(_solution[random_truck]) < 3: return solution random_bin_index = random.randint(0, len(_solution[random_truck])-1) random_bin = new_solution[random_truck][random_bin_index] #print("random_bin",random_bin) # znajdz najblizszy bins_distances_from_point = {} for bin_nr in _solution[random_truck]: #print("bin_nr",bin_nr) bins_distances_from_point[bin_nr] = bin_locations[random_bin][bin_nr] del bins_distances_from_point[random_bin] min_list_from_point = sorted(bins_distances_from_point.items(), key=lambda x: x[1]) #print("min_list_from_point",min_list_from_point) closest_bin1 = min_list_from_point[0][0] closest_bin2 = min_list_from_point[1][0] #closest_bin3 = min_list_from_point[2][0] #print("closest_bin1",closest_bin1) #print("closest_bin2", closest_bin2) new_solution[random_truck].remove(closest_bin1) new_solution[random_truck].remove(closest_bin2) #new_solution[random_truck].remove(closest_bin3) #print("\nnewsolution: ", new_solution) random_bin_index = new_solution[random_truck].index(random_bin) #print(random_bin_index) if random.randint(0, 1): new_solution[random_truck].insert(random_bin_index, closest_bin1) new_solution[random_truck].insert(random_bin_index + 2, closest_bin2) #new_solution[random_truck].insert(random_bin_index + 3, closest_bin3) else: new_solution[random_truck].insert(random_bin_index,closest_bin2) new_solution[random_truck].insert(random_bin_index + 2, closest_bin1) #new_solution[random_truck].insert(random_bin_index + 3, closest_bin3) #print("newsolution: ",new_solution) if check_ban_t1(random_bin) and check_ban_t1(closest_bin1) and check_ban_t1(closest_bin2): if check_ban_t2(new_solution) and check_ban_t3(new_solution): return new_solution if aspiration(solution, new_solution): # jesli aspiracja zadziala return new_solution return solution
def ch_truck(solution: List) -> List: #zamien smieciarki jesli ta o mniejszej pojemnosci wykonala wiecej powrotow Raportowanie.used_function('ch_truck') new_solution = deepcopy(solution) truck_max = trucks_returns.index(max(trucks_returns)) # zwraca ktora smieciarka wykonala najwiecej powrotow truck_min = trucks_returns.index(min(trucks_returns)) # zwraca ktora smieciarka wykonala najmniej powrotow new_solution[truck_max], new_solution[truck_min] = new_solution[truck_min], new_solution[truck_max] if trucks_volume[truck_max] < trucks_volume[truck_min]: if check_ban_t3(new_solution): return new_solution if (aspiration(solution,new_solution)): #jesli aspiracja zadziala return new_solution return solution
def ch_swap(solution: List) -> List: Raportowanie.used_function('ch_swap') new_solution = deepcopy(solution) for route in new_solution: if(len(route)>=2): pair = random.sample(range(0,len(route)), 2) route[pair[0]], route[pair[1]] = route[pair[1]], route[pair[0]] if check_ban_t1(route[pair[0]]) and check_ban_t1(route[pair[1]]): if check_ban_t2(new_solution) and check_ban_t3(new_solution): return new_solution if (aspiration(solution,new_solution)): #jesli aspiracja zadziala return new_solution return solution
def ban_min(_solution: List): # zabron zmeniac najkrotszych odcinkow Raportowanie.used_function('ban_min') for route in _solution: if len(route) > 2: p2p_values = [] for i in range(len(route) - 1): p2p_values.append(bin_locations[route[i]][route[i + 1]]) # print(p2p_values) od = route[p2p_values.index(min(p2p_values))] do = route[p2p_values.index(min(p2p_values)) + 1] # print(od, do) # print(p2p_values.index(max(p2p_values))) tabu_iteration = 100 add_to_TABU(TABU, [od, tabu_iteration], 1) # zabron add_to_TABU(TABU, [do, tabu_iteration], 1) # zabron
def ch_del_max(_solution: List): # usun najdalszy przejazd jaki wystepuje w rozwiazaniu Raportowanie.used_function('ch_del_max') new_solution = deepcopy(_solution) max_p2p_for_truck = [] # maksymalny przejazd dla kazdej smieciarki max_p2p_for_truck_value = [] # i jego wartość for route in _solution: # print("route: ", route) if len(route) > 2: p2p_values = [] for i in range( len(route) - 1): p2p_values.append(bin_locations[route[i]][route[i + 1]]) #print(p2p_values) od = route[p2p_values.index(max(p2p_values))] do = route[p2p_values.index(max(p2p_values)) + 1] max_p2p_for_truck.append([od, do]) max_p2p_for_truck_value.append(bin_locations[od][do]) elif len(route) == 2: max_p2p_for_truck.append([route[0], route[1]]) max_p2p_for_truck_value.append(bin_locations[route[0]][route[1]]) index_of_max = max_p2p_for_truck_value.index(max(max_p2p_for_truck_value)) #zwroci index najdluzszego przejazdu [od, do] = max_p2p_for_truck[index_of_max] # print(od,do) # przenies losowy kosz z wybranej pary [od do] do innej losowej smieciarki if random.randint(0, 1): random_bin = od else: random_bin = do bin_pos = [(index, row.index(random_bin)) for index, row in enumerate(new_solution) if random_bin in row][0] del(new_solution[bin_pos[0]][bin_pos[1]]) random_truck = random.randint(0,len(new_solution)-1) new_bin_pos = random.randint(0,len(new_solution[random_truck])) new_solution[random_truck].insert(new_bin_pos, random_bin) if check_ban_t1(random_bin): if check_ban_t2(new_solution) and check_ban_t3(new_solution): return new_solution if aspiration(_solution,new_solution): #jesli aspiracja zadziala return new_solution return new_solution
def ban_max(_solution: List): # zabron najdluższe przejazdy dla kazdej ze smieciarek Raportowanie.used_function('ban_max') for route in _solution: if len(route) > 2: p2p_values = [] for i in range(len(route) - 1): p2p_values.append(bin_locations[route[i]][route[i + 1]]) # print(p2p_values) od = route[p2p_values.index(max(p2p_values))] do = route[p2p_values.index(max(p2p_values)) + 1] # print(od, do) # print(p2p_values.index(max(p2p_values))) tabu_iteration = 5 # mozna wybrac na ile iteracji # zabroń i zmień(opcjonalnie) add_to_TABU(TABU, [od, do, tabu_iteration], 2) # zabron
def ban_max3(_solution: List): #zabron najdalszy kosz w smiecirce do ktorego najdlej z obydwu stron Raportowanie.used_function('ban_max3') random_truck = random.randint(0, len(_solution) - 1) if len(_solution[random_truck]) > 3 : do_od_max = 0 #max suma odcinków DO puntu i OD punktu isolated_point = -1 for i in range(1,len(_solution[random_truck])-1): do = bin_locations[_solution[random_truck][i-1]][_solution[random_truck][i]] od = bin_locations[_solution[random_truck][i]][_solution[random_truck][i+1]] do_od = do+od if do_od > do_od_max: do_od_max = do_od isolated_point = _solution[random_truck][i] if isolated_point != -1: tabu_iteration = 500 add_to_TABU(TABU, [isolated_point, random_truck ,tabu_iteration], 3) # zabron
def ch_bins(solution: List) -> List: Raportowanie.used_function('ch_bins') new_solution = deepcopy(solution) random_bin = random.randint(1, len(bin_locations)-1) bin_pos = [(index, row.index(random_bin)) for index, row in enumerate(new_solution) if random_bin in row][0] # bin_pos ->[ktora smieciarka, ktory kosz z kolei] - indexy elementu w macierzy # print("binpos",bin_pos) del(new_solution[bin_pos[0]][bin_pos[1]]) random_truck = random.randint(0,len(new_solution)-1) new_bin_pos = random.randint(0,len(new_solution[random_truck])) new_solution[random_truck].insert(new_bin_pos, random_bin) if check_ban_t1(random_bin): if check_ban_t2(new_solution) and check_ban_t3(new_solution): return new_solution if aspiration(solution,new_solution): # jesli aspiracja zadziala return new_solution return solution
def check_ban_t3(solution: List) -> bool: if czy_uzywac_tabu is False: return True Raportowanie.used_function('check_ban_t3') if TABU[3] == []: Raportowanie.used_function('check_ban_t3_True') return True for triple in TABU[3]: pos_point = [(index, row.index(triple[0])) for index, row in enumerate(solution) if triple[0] in row] if pos_point[0][0] == triple[1]: # czy kosz jest w zabronionej smieciarce Raportowanie.used_function('check_ban_t3_False') return False Raportowanie.used_function('check_ban_t3_True') return True
def check_ban_t1(point: int) -> bool: if czy_uzywac_tabu is False: return True Raportowanie.used_function('check_ban_t1') if TABU[1] == []: Raportowanie.used_function('check_ban_t1_True') return True banned_points = [] for pair in TABU[1]: banned_points.append(pair[0]) if point in banned_points: Raportowanie.used_function('check_ban_t1_False') return False else: Raportowanie.used_function('check_ban_t1_True') return True
def ch_returns(solution: List) -> List: Raportowanie.used_function('ch_returns') new_solution = deepcopy(solution) truck_max = trucks_returns.index(max(trucks_returns)) # zwraca ktora smieciarka wykonala najwiecej powrotow truck_min = trucks_returns.index(min(trucks_returns)) # zwraca ktora smieciarka wykonala najmniej powrotow if len(new_solution[truck_max]) < 1: return solution last_bin = new_solution[truck_max][-1] new_solution[truck_min].append(last_bin) # del (new_solution[truck_max][-1]) new_solution[truck_max].remove(last_bin) # sprawdz czy kosz ktory funkcja chce zmienic nie jest w TABU if check_ban_t1(last_bin): # Sprawdzanie czy nowe rozwiazanie jest dozwolone if check_ban_t2(new_solution) and check_ban_t3(new_solution): return new_solution if aspiration(solution, new_solution): # jesli aspiracja zadziala return new_solution return solution
def check_ban_t2(solution: List) -> bool: if czy_uzywac_tabu is False: return True Raportowanie.used_function('check_ban_t2') if TABU[2] == []: Raportowanie.used_function('check_ban_t2_True') return True for triple in TABU[2]: pos_point1 = [(index, row.index(triple[0])) for index, row in enumerate(solution) if triple[0] in row] pos_point2 = [(index, row.index(triple[1])) for index, row in enumerate(solution) if triple[1] in row] # print(pos_point1[0], pos_point2[0]) if pos_point1[0][0] == pos_point2[0][0]: # jesli w tej samej śmieciarce if abs(pos_point1[0][1] - pos_point2[0][1]) == 1: # jeśli sa obok siebie Raportowanie.used_function('check_ban_t2_False') return False Raportowanie.used_function('check_ban_t2_True') return True
def aspiration(solution: List, new_solution: List): # zwroci TRUE jesli aspiracja ma zadzialac Raportowanie.used_function('aspiracja') for j in range(0, len(solution)): cost_old = truck_ride_cost(solution[j], j) cost_new = truck_ride_cost(new_solution[j], j) if cost_new - cost_old < aspiration_procentowy_prog * cost_old: Raportowanie.used_function('aspiracja_True') return True # if truck_ride_cost(solution[j], j) < truck_ride_cost(new_solution[j], j): # Raportowanie.used_function('aspiracja_True') # return True Raportowanie.used_function('aspiracja_False') return False
def ch_move_tail(_solution: List): # usun najdalszy przejazd jaki wystepuje w rozwiazaniu Raportowanie.used_function('ch_move_tail') new_solution = deepcopy(_solution) max_p2p_for_truck = [] # maksymalny przejazd dla kazdej smieciarki max_p2p_for_truck_value = [] # i jego wartość for route in _solution: # print("route: ", route) if len(route) > 2: p2p_values = [] for i in range( len(route) - 1): p2p_values.append(bin_locations[route[i]][route[i + 1]]) # print(p2p_values) od = route[p2p_values.index(max(p2p_values))] do = route[p2p_values.index(max(p2p_values)) + 1] max_p2p_for_truck.append([od, do]) max_p2p_for_truck_value.append(bin_locations[od][do]) elif len(route) == 2: max_p2p_for_truck.append([route[0], route[1]]) max_p2p_for_truck_value.append(bin_locations[route[0]][route[1]]) index_of_max = max_p2p_for_truck_value.index(max(max_p2p_for_truck_value)) # zwroci index najdluzszego przejazdu [od, do] = max_p2p_for_truck[index_of_max] # print("od , do", od, do) # przenies koniec trasy do najblizszej smieciarki for i in range(len(new_solution)): if od in new_solution[i]: # print("solution[",i,"]",new_solution[i]) bin_start_index = new_solution[i].index(do) tail = new_solution[i][bin_start_index:] # head = new_solution[i][bin_start_index:] # print("tail", tail) first_point = do end_point = tail[-1] # znajdz najblizszy punkt do first_point distances_from_first_point = bin_locations[do] distances_from_end_point = bin_locations[end_point] bins_from_first_point = range(len(bin_locations[do])) bins_from_end_point = range(len(bin_locations[end_point])) # slownik klucz - nr kosza wartosc odleglosc od niego bins_distances_from_first_point = dict(zip(bins_from_first_point, distances_from_first_point)) bins_distances_from_end_point = dict(zip(bins_from_end_point,distances_from_end_point )) new_bins_distances_from_first_point = {} new_bins_distances_from_end_point = {} for bin_nr in bins_distances_from_first_point: if bin_nr not in new_solution[i]: new_bins_distances_from_first_point[bin_nr] = bins_distances_from_first_point[bin_nr] for bin_nr in bins_distances_from_end_point: if bin_nr not in new_solution[i]: new_bins_distances_from_end_point[bin_nr] = bins_distances_from_end_point[bin_nr] del new_bins_distances_from_first_point[0] del new_bins_distances_from_end_point[0] # znajdz min odleglosc min_from_end_point = min(new_bins_distances_from_first_point.items(), key=lambda x: x[1]) min_from_first_point = min(new_bins_distances_from_end_point.items(), key=lambda x: x[1]) if min_from_end_point[1] < min_from_first_point[1]: closest_bin = min_from_end_point[0] else: closest_bin = min_from_first_point[0] new_solution[i] = new_solution[i][:bin_start_index] bin_pos = [(index, row.index(closest_bin)) for index, row in enumerate(new_solution) if closest_bin in row][0] # bin_pos ->[ktora smieciarka, ktory kosz z kolei] new_truck = bin_pos[0] new_solution[new_truck] += deepcopy(tail) # sprawdz zabronienia # if check_ban_t1(random_bin): if check_ban_t2(new_solution) and check_ban_t3(new_solution): return new_solution if aspiration(_solution, new_solution): # jesli aspiracja zadziala return new_solution return new_solution
# ### END OF PART THREE #### print('Tabu -> ', TABU) print('Solution -> ', solution) print('Koszt rozwiazania -> ', count_cost(solution)) print('Aktualna iteracja -> ', Raportowanie.counter) print('koszty') ban_min(solution) print('Tabu po wywolaniu "ban_min(solution)"-> ', TABU) # ch_del_max(solution) real_route_dict = Raportowanie.real_route_from_solution( _solution=solution, cost_matrix=bin_locations, rubbish_in_location=rubbish_in_location, trucks_max_volumes=trucks_volume, xy_points=bin_point_list ) Raportowanie.show_trasa_z_powrotami(real_route_dict, title='Pierwsze rozwiazanie.') Raportowanie.show_wypelnienie_od_trasy(real_route_dict, title='Pierwsze rozwiazanie.') #xsolution = ch_connect_close(solution) #Raportowanie.real_route_from_solution( # _solution=xsolution, # cost_matrix=bin_locations, # rubbish_in_location=rubbish_in_location, # trucks_max_volumes=trucks_volume, # xy_points=bin_point_list #)