def solve_undirected(): graphs = [] directed = False for i in (1, 25, 50, 75, 100, 125, 150, 175, 200, 225, 250): num_vertices, edges_list = graph.generate_connected_undirected_graph(i) graphs.append((num_vertices, edges_list)) b = bench("undirected") for num_vertices, edges_list in graphs: sm.solve(directed, num_vertices, edges_list) b(f"{num_vertices} vertices, {len(edges_list)} edges") b.stop() b.display()
def test_solve_undirected_3(self): is_oriented = False num_vertices = 4 edges_list = [(0, 3, 2), (0, 1, 1), (1, 2, 12), (2, 0, 4)] cycle = sm.solve(is_oriented, num_vertices, edges_list) self.assertEqual(sa.is_valid(num_vertices, edges_list, is_oriented, cycle), True)
def test_solve_already_directed_eulerian(self): is_oriented = True num_vertices = 5 edges_list = [(0, 1, 1), (1, 2, 2), (2, 3, 3), (3, 4, 4), (4, 0, 5)] cycle = sm.solve(is_oriented, num_vertices, edges_list) self.assertEqual(sa.is_valid(num_vertices, edges_list, is_oriented, cycle), True)
def test_undirected_star_odd_n(self): n = 7 edges = [(0, 1, 10), (0, 3, 10), (0, 4, 10), (0, 5, 10), (0, 2, 10), (0, 6, 10)] cycle = solve(False, n, edges) res = [0, 2, 0, 5, 0, 4, 0, 3, 0, 6, 0, 1, 0] self.assertEqual(cycle, res)
def test_solve_undirected_square(self): is_oriented = False num_vertices = 5 edges_list = [(0, 1, 3), (1, 2, 1), (2, 3, 6), (3, 0, 2), (0, 4, 8), (1, 4, 1), (2, 4, 3), (3, 4, 4)] cycle = sm.solve(is_oriented, num_vertices, edges_list) self.assertEqual(sa.is_valid(num_vertices, edges_list, is_oriented, cycle), True)
def test_solve_undirected_4(self): is_oriented = False num_vertices = 5 edges_list = [(0, 1, 7), (1, 0, 3), (3, 2, 1), (1, 4, 4), (4, 3, 3), (3, 4, 2), (0, 3, 1)] cycle = sm.solve(is_oriented, num_vertices, edges_list) self.assertEqual(sa.is_valid(num_vertices, edges_list, is_oriented, cycle), True)
def test_solve_undirected_5(self): is_oriented = False num_vertices = 9 edges_list = [(1, 2, 3), (1, 7, 8), (2, 3, 6), (2, 4, 4), (3, 4, 1), (3, 5, 2), (3, 7, 1), (4, 8, 4), (5, 6, 3), (5, 0, 1), (6, 0, 2), (6, 7, 6)] cycle = sm.solve(is_oriented, num_vertices, edges_list) self.assertEqual(sa.is_valid(num_vertices, edges_list, is_oriented, cycle), True)
def test_undirected_small(self): n = 4 edges = [(0, 1, 10), (1, 2, 20), (2, 3, 30), (1, 3, 2)] cycle = solve(False, n, edges) self.assertEqual(cycle[0], 0) self.assertEqual(cycle[1], 1) self.assertEqual(cycle[2], 3) self.assertEqual(cycle[3], 2) self.assertEqual(cycle[4], 1) self.assertEqual(cycle[5], 0)
def test_undirected_fractale(self): n = 21 edges = [(0, 1, 10), (0, 3, 10), (0, 4, 10), (0, 5, 10), (0, 2, 10), (1, 3, 10), (1, 6, 10), (1, 7, 10), (1, 16, 10), (1, 2, 10), (2, 14, 10), (2, 15, 10), (2, 20, 10), (3, 8, 10), (3, 9, 10), (3, 17, 10), (3, 4, 10), (4, 10, 10), (4, 11, 10), (4, 18, 10), (5, 12, 10), (5, 13, 10), (5, 19, 10), (4, 5, 10), (5, 2, 10)] cycle = solve(False, n, copy.deepcopy(edges)) #res = [0, 1, 6, 1, 16, 1, 7, 1, 2, 5, 13, 5, 12, 5, 19, 5, 2, 20, 2, 15,2, 14, 2, 0, 5, 4, 11, 4, 10, 4, 18, 4, 3, 17, 3, 9, 3, 8, 3, 4,0, 3, 1, 0] self.assertTrue(is_eulerian_cycle(edges, cycle))
def test_directed_small(self): n = 7 edges = [(0, 1, 25), (0, 5, 20), (1, 2, 20), (2, 6, 17), (2, 0, 65536), (3, 0, 10), (3, 4, 30), (4, 6, 3), (5, 3, 18), (5, 4, 42), (6, 5, 50), (0, 7, 3), (7, 5, 10), (0, 7, 4)] expected = [ 0, 7, 5, 3, 0, 1, 2, 0, 7, 5, 3, 0, 5, 4, 6, 5, 3, 4, 6, 5, 3, 0, 1, 2, 6, 5, 3, 0 ] res = solve(True, n, edges) self.assertEqual(expected, res)
def test_undirected_hard(self): n = 10 edges = [(1, 2, 3), (1, 3, 4), (1, 5, 10), (1, 6, 18), (2, 3, 1), (2, 4, 5), (2, 5, 9), (3, 4, 4), (4, 5, 7), (4, 7, 9), (4, 8, 9), (5, 6, 8), (5, 7, 8), (5, 9, 9), (6, 9, 9), (6, 10, 9), (7, 8, 2), (7, 9, 2), (8, 9, 4), (8, 10, 6), (9, 10, 3)] cycle = solve(False, n, edges) res = [ 1, 6, 10, 9, 10, 8, 9, 7, 8, 4, 7, 5, 9, 6, 5, 4, 3, 4, 2, 5, 1, 3, 2, 1 ] self.assertEqual(cycle, res)
def test_undirected_bug(self): is_oriented = False edges_list =\ [(0, 29, 355), (1, 6, 864), (1, 29, 296), (2, 17, 710), (2, 21, 661), (2, 5, 542), (2, 19, 933), (3, 9, 9), (3, 26, 1011), (3, 18, 1173), (4, 18, 20.198), (4, 17, 243.967), (4, 23, 611), (5, 11, 869), (6, 26, 3), (7, 14, 25), (7, 9, 211), (7, 10, 110), (8, 10, 216), (9, 10, 168), (11, 12, 281), (13, 14, 176), (15, 18, 247), (16, 17, 271.433), (19, 20, 314), (21, 24, 1493), (22, 24, 261.903), (23, 25, 294.418), (23, 26, 954.615), (24, 25, 60.786), (25, 27, 215), (28, 29, 275.92)] num_vertices = 30 cycle = sm.solve(is_oriented, num_vertices, edges_list) self.assertEqual(sa.is_valid(num_vertices, edges_list, is_oriented, cycle), True)
def test_undirected_pentagone(self): n = 5 edges = [(10, 20, 0), (10, 30, 0), (10, 40, 0), (10, 50, 0), (20, 30, 0), (20, 40, 0), (20, 50, 0), (30, 40, 0), (30, 50, 0), (40, 50, 0)] cycle = solve(False, n, edges) self.assertEqual(cycle[0], 10) self.assertEqual(cycle[1], 50) self.assertEqual(cycle[2], 40) self.assertEqual(cycle[3], 30) self.assertEqual(cycle[4], 50) self.assertEqual(cycle[5], 20) self.assertEqual(cycle[6], 40) self.assertEqual(cycle[7], 10) self.assertEqual(cycle[8], 30) self.assertEqual(cycle[9], 20) self.assertEqual(cycle[10], 10)
def test_directed_empty(self): n = 0 edges = [] res = solve(True, n, edges) self.assertEqual([], res)
def test_directed_tronquay(self): n, edges = graph_from_location('Le Tronquay, France', 'drive') res = solve(True, n, edges) self.assertTrue(is_eulerian_cycle_directed(edges, res))
import argparse import osmnx as ox from snowymontreal import solve from utils.osmnx_utils import * from utils.eulerian_utils import is_eulerian_cycle, is_eulerian_cycle_directed import copy if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--oriented", help="use directed graph", action="store_true") parser.add_argument("location", help="location (example: 'Le Tronquay, France')") args = parser.parse_args() nxgraph = nxgraph_from_location(args.location, 'drive') ox.plot_graph(nxgraph) n, edges = nxgraph_to_graph(nxgraph) res = solve(args.oriented, n, copy.deepcopy(edges)) print(res) if args.oriented: print(is_eulerian_cycle_directed(edges, res)) else: print(is_eulerian_cycle(edges, res))
help='solve for a directed graph') parser.add_argument('-u', '--undirected', action='store_true', help='solve for a undirected graph') args = parser.parse_args() is_oriented = False if args.directed: is_oriented = True elif args.undirected: is_oriented = False city = args.city G = ox.graph_from_place(city, network_type='drive', simplify=True) G = ox.add_edge_bearings(G) num_vertices, edges_list = graph.to_reg_graph(G, is_oriented) print(f"city: {city}, oriented: {is_oriented}") print(f"number of vertices: {num_vertices}") print(f"number of edges: {len(edges_list)}") assert (sa.is_edge_connected(num_vertices, edges_list, is_oriented)) b = bench(city) b(city) path = nm.solve(is_oriented, num_vertices, edges_list) b.stop() print("time: ", "{0:.5f}".format(b.times[city][0]), "s", sep='') print(f"solved: {sa.is_valid(num_vertices, edges_list, is_oriented, path)}")