def simulated_annealing(init, init_cost, max_iter, probA, probB, probC, t_ini, alpha, problem): incumbent = init best_solution = init cheapest_cost = init_cost temp = t_ini for _ in range(max_iter): ran = random.uniform(0, 1) if ran < probA: current = operators.related_swap(incumbent, problem) elif ran < probA + probB: current = operators.related_three_exchange(incumbent, problem) else: current = operators.smart_one_reinsert(incumbent, problem) current_cost = cost_function(current, problem) incumbent_cost = cost_function(incumbent, problem) delta = current_cost - incumbent_cost feasible, _ = feasibility_check(current, problem) if feasible: if delta < 0: incumbent = current if current_cost < cheapest_cost: best_solution = incumbent cheapest_cost = current_cost elif random.uniform(0.01, 0.99) < np.exp(-delta / temp): incumbent = current temp = temp * alpha return best_solution, cheapest_cost
def local_search(init, init_cost, max_iter, probA, probB, probC, problem): current = init best_solution = init cheapest_cost = init_cost for _ in range(max_iter): ran = random.uniform(0, 1) if ran < probA: current = operators.swap(best_solution) elif ran < probA + probB: current = operators.three_exchange(best_solution) else: current = operators.one_reinsert(best_solution, problem) feasible, _ = feasibility_check(current, problem) current_cost = cost_function(current, problem) if feasible and current_cost < cheapest_cost: best_solution = current cheapest_cost = current_cost return best_solution, cheapest_cost
def escape_algorithm(init, cheapest_cost, feasible_solutions, infeasible_solutions, problem): new_solution = init probA, probB, probC, probD = 1 / 5, 1 / 5, 1 / 5, 1 / 5 for _ in range(20): ran = random.uniform(0, 1) if ran < probA: current = operators.swap(new_solution) elif ran < probA + probB: current = operators.three_exchange(new_solution) elif ran < probA + probB + probC: current = operators.related_swap(new_solution, problem) elif ran < probA + probB + probC + probD: current = operators.smart_k_reinsert(new_solution, problem) else: current = operators.smart_one_reinsert(new_solution, problem) if tuple(current) in feasible_solutions: feasible = True elif tuple(current) in infeasible_solutions: feasible = False else: feasible, _ = feasibility_check(current, problem) if feasible: new_solution = current if tuple(new_solution) not in feasible_solutions: feasible_solutions[tuple(new_solution)] = cost_function( new_solution, problem) if feasible_solutions[tuple(new_solution)] < cheapest_cost: break else: if tuple(current) not in infeasible_solutions: infeasible_solutions.add(tuple(current)) return new_solution
def local_search_memoization(init, init_cost, feasible_solutions, infeasible_solutions, max_iter, probA, probB, probC, problem): current = init best_solution = init cheapest_cost = init_cost for _ in range(max_iter): ran = random.uniform(0, 1) if ran < probA: current = operators.swap(best_solution) elif ran < probA + probB: current = operators.three_exchange(best_solution) else: current = operators.one_reinsert(best_solution, problem) if tuple(current) in feasible_solutions: feasible = True current_cost = feasible_solutions[tuple(current)] elif tuple(current) in infeasible_solutions: feasible = False else: feasible, _ = feasibility_check(current, problem) current_cost = cost_function(current, problem) if feasible: if tuple(current) not in feasible_solutions: feasible_solutions[tuple(current)] = current_cost if current_cost < cheapest_cost: best_solution = current cheapest_cost = current_cost else: if tuple(current) not in infeasible_solutions: infeasible_solutions.add(tuple(current)) return best_solution, cheapest_cost
def general_adaptative_metaheuristic(init, init_cost, max_iter, max_time, max_iter_ls, update, beta, problem): incumbent = init best_solution = init cheapest_cost = init_cost probA, probB, probC, probD, probE = 1 / 5, 1 / 5, 1 / 5, 1 / 5, 1 / 5 scores, times = [0, 0, 0, 0, 0], [0, 0, 0, 0, 0] current_op = -1 feasible_solutions = dict() infeasible_solutions = set() feasible_solutions[tuple(init)] = init_cost last_improvement = 0 history_probas = [(1 / 5, 1 / 5, 1 / 5, 1 / 5, 1 / 5)] i = 0 t_ini = time.time() while stopping_criterion(max_iter, max_time, i, time.time() - t_ini): if last_improvement > 1000: incumbent = escape_algorithm(incumbent, cheapest_cost, feasible_solutions, infeasible_solutions, problem) if feasible_solutions[tuple(incumbent)] < cheapest_cost: best_solution = incumbent cheapest_cost = feasible_solutions[tuple(incumbent)] last_improvement = 0 ran = random.uniform(0, 1) if ran < probA: current = operators.related_swap(incumbent, problem) current_op = 0 elif ran < probA + probB: current = operators.smart_one_reinsert(incumbent, problem) current_op = 1 elif ran < probA + probB + probC: current = operators.costly_one_reinsert(incumbent, problem) current_op = 2 elif ran < probA + probB + probC + probD: current = operators.smart_k_reinsert(incumbent, problem) current_op = 3 else: current = operators.related_three_exchange(incumbent, problem) current_op = 4 times[current_op] += 1 if tuple(current) in feasible_solutions: feasible = True elif tuple(current) in infeasible_solutions: feasible = False else: feasible, _ = feasibility_check(current, problem) if feasible: if tuple(current) not in feasible_solutions: feasible_solutions[tuple(current)] = cost_function( current, problem) scores[current_op] += 1 if feasible_solutions[tuple(current)] < feasible_solutions[tuple( incumbent)]: incumbent = current scores[current_op] += 2 if feasible_solutions[tuple(incumbent)] < cheapest_cost: best_solution = incumbent cheapest_cost = feasible_solutions[tuple(incumbent)] scores[current_op] += 2 last_improvement = 0 else: last_improvement += 1 elif feasible_solutions[tuple(current)] < cheapest_cost + 0.2 * ( (max_time - (time.time() - t_ini)) / max_time) * cheapest_cost: incumbent = current last_improvement += 1 else: last_improvement += 1 else: last_improvement += 1 if tuple(current) not in infeasible_solutions: infeasible_solutions.add(tuple(current)) if i % update == 0: probA, probB, probC, probD, probE = update_weights( probA, probB, probC, probD, probE, beta, scores, times) history_probas.append((probA, probB, probC, probD, probE)) i += 1 #Quick local search in order to find local optima if possible best_solution, cheapest_cost = local_search_memoization( best_solution, cheapest_cost, feasible_solutions, infeasible_solutions, max_iter_ls, 1 / 3, 1 / 3, 1 / 3, problem) return best_solution, cheapest_cost, history_probas
def main(): print("Loading datasets...") datasets = os.listdir('./datasets') print("Datasets loaded: ", datasets) parameters_gam = [-1, -1, 1600, 250, 0.05] parameters = parameters_gam file_name = './output/' + input("\nFile name: ") + '.txt' notes = input("Notes: ") notes = "No notes" if notes == "-" else notes num_iters = int(input("Number of rounds: ")) plot_weights = False if num_iters == 1: plot_r = input("Plot weights(y/n): ") plot_weights = True if plot_r == "y" else False print("\nRunning test...") results = {} all_runtimes = [] tg_1 = time.time() for dataset in datasets: prob = load_problem('./datasets/' + dataset) parameters_gam[1] = int(input("Total running time: ")) init = [0] * prob['n_vehicles'] for i in range(1, prob['n_calls'] + 1): init.append(i) init.append(i) init_cost = cost_function(init, prob) runtimes = [] costs = [] solutions = [] print("Current dataset: ", dataset) for i in range(num_iters): t_ini = time.time() best_solution, cheapest_cost, history_probas = algorithms.general_adaptative_metaheuristic( init, init_cost, parameters_gam[0], parameters_gam[1], parameters_gam[2], parameters_gam[3], parameters_gam[4], prob) t_end = time.time() feasible, _ = feasibility_check(best_solution, prob) if (cost_function(best_solution, prob) != cheapest_cost) or not feasible: print( "WARNING! EITHER CHEAPEST COST DOES NOT MATCH COST FUNCTION VALUE OR THE SOLUTION COMPUTED IS NOT FEASIBLE: ", dataset) exit() runtimes.append(t_end - t_ini) costs.append(cheapest_cost) solutions.append(best_solution) print(" Iteration: ", i + 1, "\n Iter. duration: ", t_end - t_ini, " seconds", "\n Total time elapsed: ", (time.time() - tg_1) / 60, " minutes", "\n Improvement: ", 100 * (init_cost - cheapest_cost) / init_cost, "% \n") cheapest_cost = min(costs) best_solution = solutions[costs.index(cheapest_cost)] all_runtimes.append(runtimes) results[dataset] = [ best_solution, np.mean(costs), 100 * (init_cost - np.mean(costs)) / init_cost, cheapest_cost, 100 * (init_cost - cheapest_cost) / init_cost, np.mean(runtimes) ] if plot_weights: name = dataset[:-4] with open('./weights_output/' + name + '_probas.csv', 'w') as f: print( "swap,one_reinsert,costly_reinsert,k_reinsert,three_exchange", file=f) for i in range(len(history_probas)): print(history_probas[i][0], ",", history_probas[i][1], ",", history_probas[i][2], ",", history_probas[i][3], ",", history_probas[i][4], file=f) tg_2 = time.time() mean_sum_runtimes = 0 print("Writing to file...") with open(file_name, 'w') as f: print("--- RESULTS --- \n", file=f) print("NOTES: ", notes, "\n", file=f) print("Parameters: ", parameters, "\n", file=f) for dataset in datasets: print(dataset, ": ", [ results[dataset][i] for i in range(len(results[dataset])) if i > 0 ], file=f) print(" Best found solution: ", results[dataset][0], "\n", file=f) mean_sum_runtimes += results[dataset][5] print("Total runtime: ", (tg_2 - tg_1) / 60, "minutes", file=f) print("Mean total runtime: ", mean_sum_runtimes, file=f)