code reworking WIP
This commit is contained in:
parent
a60ce57e19
commit
a8277f8d87
5 changed files with 31 additions and 31 deletions
11
run.py
11
run.py
|
@ -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'])
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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]
|
||||||
|
|
Reference in a new issue