def valid(model, valid_set, epoch, tsp_database_path): model.eval() valid_loss = 0 correct = 0 sum_duplicates = 0 sum_solution = 0 random.shuffle(valid_set) for data_file in valid_set: details = data_file.split('.')[0].split('_') nb_cities, instance_id = int(details[1]), int(details[2]) ordered_path, total_weight = read_tsp_choco_solution_file(nb_cities, instance_id, tsp_database_path) weight_matrix = ordered_path.get_weight_matrix() input_data = Variable(torch.tensor(normalize_weight_matrix(weight_matrix).reshape((1, nb_cities * nb_cities)), dtype=torch.float)) output = model(input_data) target = Variable(torch.tensor(ordered_path.to_ordered_path_binary_matrix().get_candidate(), dtype=torch.float), requires_grad=True) candidate = OrderedPath(np.array(torch.argmax(output.detach(), dim=1), dtype=int).transpose(), weight_matrix) valid_loss += model.loss_function(output, target) # sum up batch loss sum_duplicates += candidate.get_nb_duplicates() sum_solution += int(candidate.is_solution()) correct += int(candidate.is_solution()) valid_set_size = len(valid_set) sum_solution /= valid_set_size sum_duplicates /= valid_set_size print('Valid phase indicators : Solution: {}, Nb duplicates: {}'.format(sum_solution, sum_duplicates)) valid_loss /= valid_set_size print('Epoch {} - valid set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format( epoch, valid_loss, correct, valid_set_size, 100. * correct / valid_set_size)) return correct / valid_set_size, valid_loss, sum_duplicates
def test(model, test_set, tsp_database_path): model.eval() test_loss = 0 correct = 0 random.shuffle(test_set) for data_file in test_set: details = data_file.split('.')[0].split('_') nb_cities, instance_id = int(details[1]), int(details[2]) ordered_path, total_weight = read_tsp_choco_solution_file(nb_cities, instance_id, tsp_database_path) weight_matrix = ordered_path.get_weight_matrix() input_data = Variable(torch.tensor(normalize_weight_matrix(weight_matrix).reshape((1, nb_cities * nb_cities)), dtype=torch.float)) output = model(input_data) target = Variable(torch.tensor(ordered_path.to_ordered_path_binary_matrix().get_candidate(), dtype=torch.float), requires_grad=True) candidate = OrderedPath(np.array(torch.argmax(output.detach(), dim=1), dtype=int).transpose(), weight_matrix) test_loss += model.loss_function(output, target) # sum up batch loss correct += int(candidate.is_solution()) test_set_size = len(test_set) test_loss /= test_set_size print('\n' + "test" + ' set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format( test_loss, correct, test_set_size, 100. * correct / test_set_size)) return correct / test_set_size
def train(model, train_set, optimizer, tsp_database_path): model.train() sum_duplicates = 0 sum_solution = 0 random.shuffle(train_set) for data_file in train_set: details = data_file.split('.')[0].split('_') nb_cities, instance_id = int(details[1]), int(details[2]) ordered_path, total_weight = read_tsp_choco_solution_file(nb_cities, instance_id, tsp_database_path) weight_matrix = ordered_path.get_weight_matrix() input_data = Variable(torch.tensor(normalize_weight_matrix(weight_matrix).reshape((1, nb_cities * nb_cities)), dtype=torch.float), requires_grad=True) optimizer.zero_grad() output = model(input_data) # calls the forward function target = Variable(torch.tensor(ordered_path.to_ordered_path_binary_matrix().get_candidate(), dtype=torch.float), requires_grad=True) candidate = OrderedPath(np.array(torch.argmax(output.detach(), dim=1), dtype=int), weight_matrix) sum_duplicates += candidate.get_nb_duplicates() sum_solution += int(candidate.is_solution()) loss = model.loss_function(output, target) loss.backward() optimizer.step() train_set_size = len(train_set) print('Training indicators : Solution: {}, Nb duplicates: {}'.format(sum_solution / train_set_size, sum_duplicates / train_set_size)) return model
def test_to_ordered_path(self): self.assertEqual( neighbours_1.to_ordered_path(), OrderedPath(np.array([2, 3, 4, 0, 1]), distance_matrix_5)) self.assertEqual( neighbours_6.to_ordered_path(), OrderedPath(np.array([3, 1, 0, 4, 2]), distance_matrix_5)) with self.assertRaises(Exception): neighbours_2.to_ordered_path()
def test_nearest_neighbor_heuristic_case_1(self): # 1 _ _ 4 _ 3 _ 0 _ _ _ 2 ( "_" = 1 unit of distance) (symmetric case) distance_matrix_case_1 = np.array([[0, 4, 3, 1, 2], [4, 0, 7, 3, 2], [3, 7, 0, 4, 5], [1, 3, 4, 0, 1], [2, 2, 5, 1, 0]], dtype=int) ordered_path_case_1 = OrderedPath(np.array([0, 3, 4, 1, 2], dtype=int), distance_matrix_case_1) expected_total_weight_case_1 = 14 # d = 1+1+2+7+3 = 14 nearest_neighbor_case_1 = NearestNeighborHeuristic(distance_matrix_case_1) self.assertEqual(ordered_path_case_1.distance(), expected_total_weight_case_1) self.assertEqual(nearest_neighbor_case_1.get_ordered_path(), ordered_path_case_1) self.assertEqual(nearest_neighbor_case_1.get_total_weight(), expected_total_weight_case_1)
def test_comparison_functions_lt(self): self.assertFalse(neighbours_1 < ordered_path_1) self.assertFalse(ordered_path_1 < neighbours_binary_matrix_1) self.assertFalse( neighbours_binary_matrix_1 < ordered_path_binary_matrix_1) self.assertFalse(ordered_path_binary_matrix_1 < neighbours_1) self.assertTrue(ordered_path_1 < ordered_path_2) self.assertTrue( neighbours_1 < ordered_path_2.to_ordered_path_binary_matrix()) with self.assertRaises(Exception): var1 = ordered_path_1 < OrderedPath(np.array([2, 1, 3, 4, 0]), np.ones((5, 5), dtype=int)) var2 = neighbours_binary_matrix_1 < OrderedPath( np.array([0, 1, 0, 4, 0]), distance_matrix_5)
def test_two_opt_improvement_heuristic_case_2(self): # 1 _ _ 4 _ 3 _ 0 _ _ _ 2 ( "_" = 1 unit of distance) (symmetric case) (best result: d=14) distance_matrix_case_2 = np.array( [[0, 4, 3, 1, 2], [4, 0, 7, 3, 2], [3, 7, 0, 4, 5], [1, 3, 4, 0, 1], [2, 2, 5, 1, 0]], dtype=int) # d = 4+7+4+1+2 = 17 ordered_path_case_2 = OrderedPath(np.array([0, 1, 2, 3, 4], dtype=int), distance_matrix_case_2) case_2 = TwoOptImprovementHeuristic(ordered_path_case_2) self.assertTrue( case_2.get_total_weight() < ordered_path_case_2.distance()) ordered_path_case_1 = OrderedPath(np.array([0, 3, 4, 1, 2], dtype=int), distance_matrix_case_2) # d = 14 self.assertTrue(case_2.get_total_weight() >= 14)
def test_to_ordered_path(self): ordered_path_1 = OrderedPath(np.array([0, 1, 2, 3, 4]), distance_matrix_5) ordered_path_1b = OrderedPath(np.array([2, 3, 4, 0, 1]), distance_matrix_5) ordered_path_6 = OrderedPath(np.array([2, 3, 1, 0, 4]), distance_matrix_5) self.assertEqual(neighbours_binary_matrix_1.to_ordered_path(), ordered_path_1) self.assertEqual(neighbours_binary_matrix_1.to_ordered_path(), ordered_path_1b) self.assertEqual(neighbours_binary_matrix_6.to_ordered_path(), ordered_path_6) with self.assertRaises(Exception): neighbours_binary_matrix_3.to_ordered_path()
def test_read_tsp_choco_solution_file(self): choco_data = dT.read_tsp_choco_solution_file(10, 1, "test/database/") choco_weight_matrix = np.array([[0, 413, 578, 209, 203, 476, 429, 410, 232, 462], [413, 0, 471, 318, 209, 394, 29, 449, 552, 361], [578, 471, 0, 369, 488, 103, 498, 198, 507, 126], [209, 318, 369, 0, 174, 267, 345, 218, 239, 252], [203, 209, 488, 174, 0, 388, 226, 379, 368, 362], [476, 394, 103, 267, 388, 0, 422, 127, 422, 33], [429, 29, 498, 345, 226, 422, 0, 479, 576, 389], [410, 449, 198, 218, 379, 127, 479, 0, 309, 144], [232, 552, 507, 239, 368, 422, 576, 309, 0, 425], [462, 361, 126, 252, 362, 33, 389, 144, 425, 0]], dtype=int) choco_candidate = np.array([8, 6, 5, 7, 0, 9, 4, 2, 3, 1], dtype=int) choco_total_weight = 1842 choco_cartesian = np.array([[164, 189], [57, 588], [526, 640], [282, 362], [109, 385], [451, 569], [29, 597], [484, 446], [393, 150], [418, 575]], dtype=int) self.assertTrue(choco_data[0] == OrderedPath(choco_candidate, choco_weight_matrix, choco_cartesian)) self.assertTrue(choco_data[1] == choco_total_weight)
def test_two_opt_improvement_heuristic_non_symmetric(self): weight_matrix = np.array( [[0, 5, 1, 10, 1], [1, 0, 1, 8, 1], [1, 15, 0, 4, 6], [8, 1, 2, 0, 2], [9, 7, 0, 1, 0]], dtype=int) ordered_path = OrderedPath(np.array([0, 1, 2, 3, 4], dtype=int), weight_matrix) with self.assertRaises(Exception): TwoOptImprovementHeuristic(ordered_path)
def test_two_opt_improvement_heuristic_case_1(self): # 1 _ _ 4 _ 3 _ 0 _ _ _ 2 ( "_" = 1 unit of distance) (symmetric case) time_limit_case_1 = 0 distance_matrix_case_1 = np.array( [[0, 4, 3, 1, 2], [4, 0, 7, 3, 2], [3, 7, 0, 4, 5], [1, 3, 4, 0, 1], [2, 2, 5, 1, 0]], dtype=int) ordered_path_case_1 = OrderedPath(np.array([0, 3, 4, 1, 2], dtype=int), distance_matrix_case_1) # d = 14 case_1a = TwoOptImprovementHeuristic(ordered_path_case_1, time_limit_case_1) case_1b = TwoOptImprovementHeuristic( ordered_path_case_1.to_neighbours_binary_matrix(), time_limit_case_1) case_1c = TwoOptImprovementHeuristic( ordered_path_case_1.to_neighbours(), time_limit_case_1) case_1d = TwoOptImprovementHeuristic( ordered_path_case_1.to_neighbours(), time_limit_case_1) self.assertEqual(case_1a.get_ordered_path(), ordered_path_case_1) self.assertEqual(case_1b.get_ordered_path(), ordered_path_case_1) self.assertEqual(case_1c.get_ordered_path(), ordered_path_case_1) self.assertEqual(case_1d.get_ordered_path(), ordered_path_case_1) self.assertEqual(case_1a.get_total_weight(), 14) self.assertEqual(case_1b.get_total_weight(), 14) self.assertEqual(case_1c.get_total_weight(), 14) self.assertEqual(case_1d.get_total_weight(), 14) with self.assertRaises(Exception): TwoOptImprovementHeuristic(ordered_path_case_1.get_candidate(), time_limit_case_1) TwoOptImprovementHeuristic(ordered_path_2, time_limit_case_1)
def test_read_tsp_heuristic_solution_file(self): heuristic_data = dT.read_tsp_heuristic_solution_file(5, 0, "test/database/") self.assertTrue(heuristic_data[0] == OrderedPath(np.array([0, 4, 2, 1, 3], dtype=int), expected_weight_matrix_sym)) self.assertTrue(heuristic_data[1] == 12)
import unittest import numpy as np from src.heuristicsTSP.twoOptImprovementHeuristic import TwoOptImprovementHeuristic, two_opt_swap from src.objects.orderedPath import OrderedPath distance_matrix_5 = np.array( [[0, 5, 1, 10, 1], [1, 0, 1, 8, 1], [1, 15, 0, 4, 6], [8, 1, 2, 0, 2], [9, 7, 0, 1, 0]], dtype=int) ordered_path_1 = OrderedPath(np.array([0, 1, 2, 3, 4]), distance_matrix_5) # solution d = 5+1+4+2+9 = 21 ordered_path_2 = OrderedPath(np.array([0, 1, 0, 1, 4]), distance_matrix_5) class TestTwoOptImprovementHeuristicMethods(unittest.TestCase): def test_two_opt_swap(self): ordered_path_array = np.array([4, 5, 2, 3, 0, 1], dtype=int) expected_path_array = np.array([4, 0, 3, 2, 5, 1], dtype=int) self.assertFalse((ordered_path_array == expected_path_array).all()) two_opt_swap(ordered_path_array, 1, 4) self.assertTrue((ordered_path_array == expected_path_array).all()) ordered_path_array_1 = ordered_path_1.__copy__().get_candidate() self.assertTrue( (ordered_path_1.get_candidate() == ordered_path_array_1).all()) two_opt_swap(ordered_path_array_1, 0, 3) self.assertFalse( (ordered_path_1.get_candidate() == ordered_path_array_1).all()) def test_two_opt_improvement_heuristic_case_1(self): # 1 _ _ 4 _ 3 _ 0 _ _ _ 2 ( "_" = 1 unit of distance) (symmetric case) time_limit_case_1 = 0
from src.objects.neighbours import Neighbours from src.objects.neighboursBinaryMatrix import NeighboursBinaryMatrix from src.objects.orderedPath import OrderedPath from src.objects.orderedPathBinaryMatrix import OrderedPathBinaryMatrix distance_matrix_5 = np.array( [[0, 5, 1, 10, 1], [1, 0, 1, 8, 1], [1, 15, 0, 4, 6], [8, 1, 2, 0, 2], [9, 7, 0, 1, 0]], dtype=int) # solution d = 5+1+4+2+9 = 21 neighbours_1 = Neighbours(np.array([1, 2, 3, 4, 0]), distance_matrix_5) neighbours_binary_matrix_1 = NeighboursBinaryMatrix( np.array([[0, 0, 0, 0, 1], [1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0]], dtype=int), distance_matrix_5) ordered_path_1 = OrderedPath(np.array([0, 1, 2, 3, 4]), distance_matrix_5) ordered_path_binary_matrix_1 = \ OrderedPathBinaryMatrix(np.array([[1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1]], dtype=int), distance_matrix_5) # solution d = 8+1+0+15+8 = 32 ordered_path_2 = OrderedPath(np.array([3, 0, 4, 2, 1], dtype=int), distance_matrix_5) class TestCandidateTSPMethods(unittest.TestCase): def test_comparison_functions_le(self): self.assertTrue(neighbours_1 <= ordered_path_1) self.assertTrue(ordered_path_1 <= neighbours_binary_matrix_1)
for data in batch: wm = data[0].get_weight_matrix().reshape(100) wm = torch.tensor(wm, dtype=torch.float, requires_grad=True) if trained_net == 0: # Generator training label = [0] g_optimizer.zero_grad() input_g = generator(wm) can = np.array([ np.argmax(input_g.detach().numpy()[k * 10:(k + 1) * 10]) for k in range(10) ], dtype=int) op_can = OrderedPath( can, wm.detach().numpy().astype(int).reshape(10, 10)) nb_solutions += int(op_can.is_solution()) nb_duplicates += op_can.get_nb_duplicates() output_g = torch.tensor(label, dtype=torch.float, requires_grad=False) predicted_output_g = discriminator(input_g) g_loss = F.binary_cross_entropy(predicted_output_g, output_g) avg_g_loss += g_loss.item() nb_g_loss += 1 if net_switch or first_g_loss is None: nb_iterations = 1 first_g_loss = g_loss.item()
import unittest import numpy as np from src.objects.neighbours import Neighbours from src.objects.neighboursBinaryMatrix import NeighboursBinaryMatrix from src.objects.orderedPath import OrderedPath from src.objects.orderedPathBinaryMatrix import OrderedPathBinaryMatrix distance_matrix_5 = np.array( [[0, 5, 1, 10, 1], [1, 0, 1, 8, 1], [1, 15, 0, 4, 6], [8, 1, 2, 0, 2], [9, 7, 0, 1, 0]], dtype=int) ordered_path_1 = OrderedPath(np.array([0, 1, 2, 3, 4]), distance_matrix_5) # solution d = 5+1+4+2+9 = 21 ordered_path_1b = OrderedPath(np.array([0, 1, 2, 3, 4]), distance_matrix_5) # solution d = 5+1+4+2+9 = 21 ordered_path_1c = OrderedPath(np.array([2, 3, 4, 0, 1]), distance_matrix_5) # solution d = 5+1+4+2+9 = 21 ordered_path_2 = OrderedPath([0, 1, 2, 0, 4], distance_matrix_5) ordered_path_2b = OrderedPath(np.array([0, 1, 2, 0, 4]), distance_matrix_5) ordered_path_3 = OrderedPath(np.array([4, 5, 2, 3, 0]), distance_matrix_5) ordered_path_4 = OrderedPath(np.array([1, 0, 2, 3, -1]), distance_matrix_5) ordered_path_5 = OrderedPath(np.array([1, "c", 2, 3, 0]), distance_matrix_5) ordered_path_6 = OrderedPath(np.array([1, 4, 2, 3, 0]), distance_matrix_5[:2, :3]) ordered_path_7 = OrderedPath(np.array([4, 2, 3, 1, 1]), distance_matrix_5) ordered_path_8 = OrderedPath(np.array([3, 0, 4, 2, 1], dtype=int), distance_matrix_5) # solution d = 8+1+0+15+8 = 32 ordered_path_9 = OrderedPath(np.array([3, 0, 0, 0, 3], dtype=int), distance_matrix_5)