def test_ascent_method_asymmetric_2(): """ Tests the ascent method using a truly asymmetric graph for which the solution has been brute forced """ import networkx.algorithms.approximation.traveling_salesman as tsp np = pytest.importorskip("numpy") G_array = np.array([ [0, 45, 39, 92, 29, 31], [72, 0, 4, 12, 21, 60], [81, 6, 0, 98, 70, 53], [49, 71, 59, 0, 98, 94], [74, 95, 24, 43, 0, 47], [56, 43, 3, 65, 22, 0], ]) solution_edges = [(0, 5), (5, 4), (1, 3), (3, 0), (2, 1), (4, 2)] G = nx.from_numpy_array(G_array, create_using=nx.DiGraph) opt_hk, z_star = tsp.held_karp_ascent(G) # Check that the optimal weights are the same assert round(opt_hk, 2) == 144.00 # Check that the z_stars match. solution = nx.DiGraph() solution.add_edges_from(solution_edges) assert nx.utils.edges_equal(z_star.edges, solution.edges)
def test_ascent_method_asymmetric(): """ Tests the ascent method using a truly asymmetric graph for which the solution has been brute forced """ import networkx.algorithms.approximation.traveling_salesman as tsp np = pytest.importorskip("numpy") G_array = np.array([ [0, 26, 63, 59, 69, 31, 41], [62, 0, 91, 53, 75, 87, 47], [47, 82, 0, 90, 15, 9, 18], [68, 19, 5, 0, 58, 34, 93], [11, 58, 53, 55, 0, 61, 79], [88, 75, 13, 76, 98, 0, 40], [41, 61, 55, 88, 46, 45, 0], ]) solution_edges = [(0, 1), (1, 3), (3, 2), (2, 5), (5, 6), (4, 0), (6, 4)] G = nx.from_numpy_array(G_array, create_using=nx.DiGraph) opt_hk, z_star = tsp.held_karp_ascent(G) # Check that the optimal weights are the same assert round(opt_hk, 2) == 190.00 # Check that the z_stars match. solution = nx.DiGraph() solution.add_edges_from(solution_edges) assert nx.utils.edges_equal(z_star.edges, solution.edges)
def test_held_karp_ascent(): """ Test the Held-Karp relaxation with the ascent method """ import networkx.algorithms.approximation.traveling_salesman as tsp np = pytest.importorskip("numpy") # Adjacency matrix from page 1153 of the 1970 Held and Karp paper # which have been edited to be directional, but also symmetric G_array = np.array([ [0, 97, 60, 73, 17, 52], [97, 0, 41, 52, 90, 30], [60, 41, 0, 21, 35, 41], [73, 52, 21, 0, 95, 46], [17, 90, 35, 95, 0, 81], [52, 30, 41, 46, 81, 0], ]) solution_edges = [(1, 3), (2, 4), (3, 2), (4, 0), (5, 1), (0, 5)] G = nx.from_numpy_array(G_array, create_using=nx.DiGraph) opt_hk, z_star = tsp.held_karp_ascent(G) # Check that the optimal weights are the same assert round(opt_hk, 2) == 207.00 # Check that the z_stars are the same solution = nx.DiGraph() solution.add_edges_from(solution_edges) assert nx.utils.edges_equal(z_star.edges, solution.edges)
def test_ascent_fractional_solution(): """ Test the ascent method using a modified version of Figure 2 on page 1140 in 'The Traveling Salesman Problem and Minimum Spanning Trees' by Held and Karp """ import networkx.algorithms.approximation.traveling_salesman as tsp np = pytest.importorskip("numpy") pytest.importorskip("scipy") # This version of Figure 2 has all of the edge weights multiplied by 100 # and is a complete directed graph with infinite edge weights for the # edges not listed in the original graph G_array = np.array([ [0, 100, 100, 100000, 100000, 1], [100, 0, 100, 100000, 1, 100000], [100, 100, 0, 1, 100000, 100000], [100000, 100000, 1, 0, 100, 100], [100000, 1, 100000, 100, 0, 100], [1, 100000, 100000, 100, 100, 0], ]) solution_z_star = { (0, 1): 5 / 12, (0, 2): 5 / 12, (0, 5): 5 / 6, (1, 0): 5 / 12, (1, 2): 1 / 3, (1, 4): 5 / 6, (2, 0): 5 / 12, (2, 1): 1 / 3, (2, 3): 5 / 6, (3, 2): 5 / 6, (3, 4): 1 / 3, (3, 5): 1 / 2, (4, 1): 5 / 6, (4, 3): 1 / 3, (4, 5): 1 / 2, (5, 0): 5 / 6, (5, 3): 1 / 2, (5, 4): 1 / 2, } G = nx.from_numpy_array(G_array, create_using=nx.DiGraph) opt_hk, z_star = tsp.held_karp_ascent(G) # Check that the optimal weights are the same assert round(opt_hk, 2) == 303.00 # Check that the z_stars are the same assert {key: round(z_star[key], 4) for key in z_star} == { key: round(solution_z_star[key], 4) for key in solution_z_star }
def test_held_karp_ascent_fractional_asymmetric(): """ Tests the ascent method using a truly asymmetric graph with a fractional solution for which the solution has been brute forced """ import networkx.algorithms.approximation.traveling_salesman as tsp np = pytest.importorskip("numpy") pytest.importorskip("scipy") G_array = np.array([ [0, 100, 150, 100000, 100000, 1], [150, 0, 100, 100000, 1, 100000], [100, 150, 0, 1, 100000, 100000], [100000, 100000, 1, 0, 150, 100], [100000, 2, 100000, 100, 0, 150], [2, 100000, 100000, 150, 100, 0], ]) solution_z_star = { (0, 1): 5 / 12, (0, 2): 5 / 12, (0, 5): 5 / 6, (1, 0): 5 / 12, (1, 2): 5 / 12, (1, 4): 5 / 6, (2, 0): 5 / 12, (2, 1): 5 / 12, (2, 3): 5 / 6, (3, 2): 5 / 6, (3, 4): 5 / 12, (3, 5): 5 / 12, (4, 1): 5 / 6, (4, 3): 5 / 12, (4, 5): 5 / 12, (5, 0): 5 / 6, (5, 3): 5 / 12, (5, 4): 5 / 12, } G = nx.from_numpy_array(G_array, create_using=nx.DiGraph) opt_hk, z_star = tsp.held_karp_ascent(G) # Check that the optimal weights are the same assert round(opt_hk, 2) == 304.00 # Check that the z_stars are the same assert {key: round(z_star[key], 4) for key in z_star} == { key: round(solution_z_star[key], 4) for key in solution_z_star }
def test_held_karp_ascent_asymmetric_3(): """ Tests the ascent method using a truly asymmetric graph with a fractional solution for which the solution has been brute forced. In this graph their are two different optimal, integral solutions (which are also the overall atsp solutions) to the Held Karp relaxation. However, this particular graph has two different tours of optimal value and the possible solutions in the held_karp_ascent function are not stored in an ordered data structure. """ import networkx.algorithms.approximation.traveling_salesman as tsp np = pytest.importorskip("numpy") pytest.importorskip("scipy") G_array = np.array([ [0, 1, 5, 2, 7, 4], [7, 0, 7, 7, 1, 4], [4, 7, 0, 9, 2, 1], [7, 2, 7, 0, 4, 4], [5, 5, 4, 4, 0, 3], [3, 9, 1, 3, 4, 0], ]) solution1_edges = [(0, 3), (1, 4), (2, 5), (3, 1), (4, 2), (5, 0)] solution2_edges = [(0, 3), (3, 1), (1, 4), (4, 5), (2, 0), (5, 2)] G = nx.from_numpy_array(G_array, create_using=nx.DiGraph) opt_hk, z_star = tsp.held_karp_ascent(G) assert round(opt_hk, 2) == 13.00 # Check that the z_stars are the same solution1 = nx.DiGraph() solution1.add_edges_from(solution1_edges) solution2 = nx.DiGraph() solution2.add_edges_from(solution2_edges) assert nx.utils.edges_equal(z_star.edges, solution1.edges) or nx.utils.edges_equal( z_star.edges, solution2.edges)