code reworking WIP

This commit is contained in:
Dario Mantegazza 2020-09-28 11:07:19 +02:00
parent a60ce57e19
commit a8277f8d87
5 changed files with 31 additions and 31 deletions

11
run.py
View file

@ -4,7 +4,7 @@ from src.TSP_solver import SolverTSP, available_improvers, available_solvers
import numpy as np import numpy as np
def add(solver, improve, index, results, name, verbose, show_plots): def use_solver_to_compute_solution(solver, improve, index, results, name, verbose, show_plots):
solver.bind(improve) solver.bind(improve)
solver.compute_solution(return_value=False, verbose=verbose) solver.compute_solution(return_value=False, verbose=verbose)
@ -39,19 +39,20 @@ def run(show_plots=False, verbose=False):
for solver_name in solvers_names: for solver_name in solvers_names:
for improve in improvers_names: for improve in improvers_names:
solver = SolverTSP(solver_name, prob_instance) solver = SolverTSP(solver_name, prob_instance)
add(solver, improve, index, results, problem_path, verbose, show_plots) use_solver_to_compute_solution(solver, improve, index, results, problem_path, verbose, show_plots)
for improve2 in [j for j in improvers_names if j not in [improve]]: for improve2 in [j for j in improvers_names if j not in [improve]]:
add(solver, improve2, index, results, problem_path, verbose, show_plots) use_solver_to_compute_solution(solver, improve2, index, results, problem_path, verbose, show_plots)
for improve3 in [j for j in improvers_names if j not in [improve, improve2]]: for improve3 in [j for j in improvers_names if j not in [improve, improve2]]:
add(solver, improve3, index, results, problem_path, verbose, show_plots) use_solver_to_compute_solution(solver, improve3, index, results, problem_path, verbose,
show_plots)
solver.pop() solver.pop()
solver.pop() solver.pop()
if prob_instance.exist_opt and show_plots: if prob_instance.exist_opt and show_plots:
solver.algorithm_name="optimal"
solver.solution = np.concatenate([prob_instance.optimal_tour, [prob_instance.optimal_tour[0]]]) solver.solution = np.concatenate([prob_instance.optimal_tour, [prob_instance.optimal_tour[0]]])
solver.method = "optimal"
solver.plot_solution() solver.plot_solution()
index = pd.MultiIndex.from_tuples(index, names=['problem', 'method']) index = pd.MultiIndex.from_tuples(index, names=['problem', 'method'])

View file

@ -31,6 +31,7 @@ class SolverTSP:
self.name_method = "initialized with " + algorithm_name self.name_method = "initialized with " + algorithm_name
self.solved = False self.solved = False
self.problem_instance = problem_instance self.problem_instance = problem_instance
self.solution = None
def bind(self, local_or_meta): def bind(self, local_or_meta):
assert local_or_meta in available_improvers, f"the {local_or_meta} method is not available currently." assert local_or_meta in available_improvers, f"the {local_or_meta} method is not available currently."
@ -79,11 +80,9 @@ class SolverTSP:
def check_if_solution_is_valid(self, solution): def check_if_solution_is_valid(self, solution):
# rights_values = np.sum( # rights_values = np.sum(
# [self.check_validation(i, solution[:-1]) for i in np.arange(self.problem_instance.nPoints)]) # [self.check_validation(i, solution[:-1]) for i in np.arange(self.problem_instance.nPoints)])
rights_values = np.sum([1 if np.sum(solution[:-1] == i) == 1 else 0 for i in np.arange(self.problem_instance.nPoints)]) rights_values = np.sum(
[1 if np.sum(solution[:-1] == i) == 1 else 0 for i in np.arange(self.problem_instance.nPoints)])
return rights_values == self.problem_instance.nPoints return rights_values == self.problem_instance.nPoints
# return True
# else:
# return False
# def check_validation(self, node, solution): # def check_validation(self, node, solution):
# if np.sum(solution == node) == 1: # if np.sum(solution == node) == 1:

View file

@ -25,16 +25,16 @@ def nearest_neighbor(instance_, starting_node=0):
def best_nearest_neighbor(instance_): def best_nearest_neighbor(instance_):
solutions, lens = [], [] solutions, lengths = [], []
for start in range(instance_.nPoints): for start in range(instance_.nPoints):
new_solution = nearest_neighbor(instance_, starting_node=start) new_solution = nearest_neighbor(instance_, starting_node=start)
solutions.append(new_solution) solutions.append(new_solution)
lens.append(compute_length(new_solution, instance_.dist_matrix)) lengths.append(compute_length(new_solution, instance_.dist_matrix))
if lens is []: if lengths is []:
return None # Todo understand this return return None
else: else:
solution = solutions[np.argmin(lens)] solution = solutions[np.argmin(lengths)]
return solution return solution
@ -52,21 +52,21 @@ def multi_fragment_check_if_not_close(edge_to_append, sol):
return True return True
partial_tour = [from_city] partial_tour = [from_city]
end = False end = False
iterazione = 0 iteration = 0
while not end: while not end:
if len(sol[str(from_city)]) == 1: if len(sol[str(from_city)]) == 1:
if from_city == n1: if from_city == n1:
return_value = False return_value = False
end = True end = True
elif iterazione > 1: elif iteration > 1:
# print(f"iterazione {iterazione}, elementi dentro partial {len(partial_tour)}", # print(f"iterazione {iteration}, elementi dentro partial {len(partial_tour)}",
# f"from city {from_city}") # f"from city {from_city}")
return_value = True return_value = True
end = True end = True
else: else:
from_city = sol[str(from_city)][0] from_city = sol[str(from_city)][0]
partial_tour.append(from_city) partial_tour.append(from_city)
iterazione += 1 iteration += 1
else: else:
# print(from_city, partial_tour, sol[str(from_city)]) # print(from_city, partial_tour, sol[str(from_city)])
for node_connected in sol[str(from_city)]: for node_connected in sol[str(from_city)]:
@ -75,7 +75,7 @@ def multi_fragment_check_if_not_close(edge_to_append, sol):
from_city = node_connected from_city = node_connected
partial_tour.append(node_connected) partial_tour.append(node_connected)
# print(node_connected, sol[str(from_city)]) # print(node_connected, sol[str(from_city)])
iterazione += 1 iteration += 1
return return_value return return_value
@ -85,17 +85,17 @@ def multi_fragment_create_solution(start_sol, sol, n):
n1, n2 = start_sol n1, n2 = start_sol
from_city = n2 from_city = n2
sol_list = [n1, n2] sol_list = [n1, n2]
iterazione = 0 iteration = 0
while not end: while not end:
for node_connected in sol[str(from_city)]: for node_connected in sol[str(from_city)]:
iterazione += 1 iteration += 1
if node_connected not in sol_list: if node_connected not in sol_list:
from_city = node_connected from_city = node_connected
sol_list.append(node_connected) sol_list.append(node_connected)
# print(f"prossimo {node_connected}", # print(f"prossimo {node_connected}",
# f"possibili {sol[str(from_city)]}", # f"possibili {sol[str(from_city)]}",
# f"ultim tour {sol_list[-5:]}") # f"ultim tour {sol_list[-5:]}")
if iterazione > 300: if iteration > 300:
if len(sol_list) == n: if len(sol_list) == n:
end = True end = True
sol_list.append(n1) sol_list.append(n1)

View file

@ -14,7 +14,7 @@ def sa(solution, instance, constant_temperature=0.95, iterations_for_each_temp=1
# main loop # main loop
while temperature > 0.001: while temperature > 0.001:
for it in range(iterations_for_each_temp): for it in range(iterations_for_each_temp):
next_sol, delta_E = random_sol_from_neig(current_sol, instance) next_sol, delta_E = random_sol_from_neigh(current_sol, instance)
if delta_E < 0: if delta_E < 0:
current_sol = next_sol current_sol = next_sol
current_len += delta_E current_len += delta_E
@ -32,13 +32,13 @@ def sa(solution, instance, constant_temperature=0.95, iterations_for_each_temp=1
return best_sol.tolist() return best_sol.tolist()
def random_sol_from_neig(solution, instance): def random_sol_from_neigh(solution, instance):
i, j = np.random.choice(np.arange(1, len(solution) - 1), 2, replace=False) i, j = np.random.choice(np.arange(1, len(solution) - 1), 2, replace=False)
i, j = np.sort([i, j]) i, j = np.sort([i, j])
return swap2opt(solution, i, j), gain(i, j, solution, instance.dist_matrix) return sa_swap2opt(solution, i, j), gain(i, j, solution, instance.dist_matrix)
def swap2opt(tsp_sequence, i, j): def sa_swap2opt(tsp_sequence, i, j):
new_tsp_sequence = np.copy(tsp_sequence) new_tsp_sequence = np.copy(tsp_sequence)
new_tsp_sequence[i:j + 1] = np.flip(tsp_sequence[i:j + 1], axis=0) # flip or swap ? new_tsp_sequence[i:j + 1] = np.flip(tsp_sequence[i:j + 1], axis=0) # flip or swap ?
return new_tsp_sequence return new_tsp_sequence

View file

@ -11,8 +11,8 @@ def step2dot5opt(solution, matrix_dist, distance):
for i in range(1, seq_length - 1): for i in range(1, seq_length - 1):
for j in range(i + 1, seq_length): for j in range(i + 1, seq_length):
# 2opt swap # 2opt swap
twoOpt_tsp_sequence = swap2opt(tsp_sequence, i, j) two_opt_tsp_sequence = swap2opt(tsp_sequence, i, j)
twoOpt_len = distance + gain(i, j, tsp_sequence, matrix_dist) two_opt_len = distance + gain(i, j, tsp_sequence, matrix_dist)
# node shift 1 # node shift 1
first_shift_tsp_sequence = shift1(tsp_sequence, i, j) first_shift_tsp_sequence = shift1(tsp_sequence, i, j)
first_shift_len = distance + shift_gain1(i, j, tsp_sequence, matrix_dist) first_shift_len = distance + shift_gain1(i, j, tsp_sequence, matrix_dist)
@ -20,9 +20,9 @@ def step2dot5opt(solution, matrix_dist, distance):
second_shift_tsp_sequence = shift2(tsp_sequence, i, j) second_shift_tsp_sequence = shift2(tsp_sequence, i, j)
second_shift_len = distance + shift_gain2(i, j, tsp_sequence, matrix_dist) second_shift_len = distance + shift_gain2(i, j, tsp_sequence, matrix_dist)
best_len, best_method = min([twoOpt_len, first_shift_len, second_shift_len]), np.argmin( best_len, best_method = min([two_opt_len, first_shift_len, second_shift_len]), np.argmin(
[twoOpt_len, first_shift_len, second_shift_len]) [two_opt_len, first_shift_len, second_shift_len])
sequences = [twoOpt_tsp_sequence, first_shift_tsp_sequence, second_shift_tsp_sequence] sequences = [two_opt_tsp_sequence, first_shift_tsp_sequence, second_shift_tsp_sequence]
if best_len < distance: if best_len < distance:
uncrosses += 1 uncrosses += 1
tsp_sequence = sequences[best_method] tsp_sequence = sequences[best_method]