def _test_breadth_first_search_parallel(ds): import pydatastructs.utils.misc_util as utils GraphNode = getattr(utils, "Adjacency" + ds + "GraphNode") V1 = GraphNode(0) V2 = GraphNode(1) V3 = GraphNode(2) V4 = GraphNode(3) V5 = GraphNode(4) V6 = GraphNode(5) V7 = GraphNode(6) V8 = GraphNode(7) G1 = Graph(V1, V2, V3, V4, V5, V6, V7, V8) edges = [(V1.name, V2.name), (V1.name, V3.name), (V1.name, V4.name), (V2.name, V5.name), (V2.name, V6.name), (V3.name, V6.name), (V3.name, V7.name), (V4.name, V7.name), (V4.name, V8.name)] for edge in edges: G1.add_edge(*edge) parent = dict() def bfs_tree(curr_node, next_node, parent): if next_node != "": parent[next_node] = curr_node return True breadth_first_search_parallel(G1, V1.name, 5, bfs_tree, parent) assert (parent[V2.name] == V1.name and parent[V3.name] == V1.name and parent[V4.name] == V1.name and parent[V5.name] == V2.name and (parent[V6.name] in (V2.name, V3.name)) and (parent[V7.name] in (V3.name, V4.name)) and (parent[V8.name] == V4.name))
def _test_breadth_first_search(ds): import pydatastructs.utils.misc_util as utils GraphNode = getattr(utils, "Adjacency" + ds + "GraphNode") V1 = GraphNode(0) V2 = GraphNode(1) V3 = GraphNode(2) G1 = Graph(V1, V2, V3) edges = [(V1.name, V2.name), (V2.name, V3.name), (V1.name, V3.name)] for edge in edges: G1.add_edge(*edge) parent = dict() def bfs_tree(curr_node, next_node, parent): if next_node != "": parent[next_node] = curr_node return True breadth_first_search(G1, V1.name, bfs_tree, parent) assert (parent[V3.name] == V1.name and parent[V2.name] == V1.name) or \ (parent[V3.name] == V2.name and parent[V2.name] == V1.name) V4 = GraphNode(0) V5 = GraphNode(1) V6 = GraphNode(2) V7 = GraphNode(3) V8 = GraphNode(4) edges = [(V4.name, V5.name), (V5.name, V6.name), (V6.name, V7.name), (V6.name, V4.name), (V7.name, V8.name)] G2 = Graph(V4, V5, V6, V7, V8) for edge in edges: G2.add_edge(*edge) path = [] def path_finder(curr_node, next_node, dest_node, parent, path): if next_node != "": parent[next_node] = curr_node if curr_node == dest_node: node = curr_node path.append(node) while node is not None: if parent.get(node, None) is not None: path.append(parent[node]) node = parent.get(node, None) path.reverse() return False return True parent.clear() breadth_first_search(G2, V4.name, path_finder, V7.name, parent, path) assert path == [V4.name, V5.name, V6.name, V7.name]
def _test_minimum_spanning_tree(func, ds, algorithm, *args): import pydatastructs.utils.misc_util as utils GraphNode = getattr(utils, "Adjacency" + ds + "GraphNode") a, b, c, d, e = [GraphNode(x) for x in [0, 1, 2, 3, 4]] graph = Graph(a, b, c, d, e) graph.add_edge(a.name, c.name, 10) graph.add_edge(c.name, a.name, 10) graph.add_edge(a.name, d.name, 7) graph.add_edge(d.name, a.name, 7) graph.add_edge(c.name, d.name, 9) graph.add_edge(d.name, c.name, 9) graph.add_edge(d.name, b.name, 32) graph.add_edge(b.name, d.name, 32) graph.add_edge(d.name, e.name, 23) graph.add_edge(e.name, d.name, 23) mst = func(graph, algorithm, *args) expected_mst = [('0_3', 7), ('2_3', 9), ('3_4', 23), ('3_1', 32), ('3_0', 7), ('3_2', 9), ('4_3', 23), ('1_3', 32)] assert len(expected_mst) == len(mst.edge_weights.items()) for k, v in mst.edge_weights.items(): assert (k, v.value) in expected_mst
def _test_shortest_paths_negative_edges(ds, algorithm): import pydatastructs.utils.misc_util as utils GraphNode = getattr(utils, "Adjacency" + ds + "GraphNode") vertices = [ GraphNode('s'), GraphNode('a'), GraphNode('b'), GraphNode('c'), GraphNode('d') ] graph = Graph(*vertices) graph.add_edge('s', 'a', 3) graph.add_edge('s', 'b', 2) graph.add_edge('a', 'c', 1) graph.add_edge('b', 'd', 1) graph.add_edge('b', 'a', -2) graph.add_edge('c', 'd', 1) dist, pred = shortest_paths(graph, algorithm, 's') assert dist == {'s': 0, 'a': 0, 'b': 2, 'c': 1, 'd': 2} assert pred == {'s': None, 'a': 'b', 'b': 's', 'c': 'a', 'd': 'c'} dist, pred = shortest_paths(graph, algorithm, 's', 'd') assert dist == 2 assert pred == {'s': None, 'a': 'b', 'b': 's', 'c': 'a', 'd': 'c'}
def _test_topological_sort(func, ds, algorithm, threads=None): import pydatastructs.utils.misc_util as utils GraphNode = getattr(utils, "Adjacency" + ds + "GraphNode") vertices = [ GraphNode('2'), GraphNode('3'), GraphNode('5'), GraphNode('7'), GraphNode('8'), GraphNode('10'), GraphNode('11'), GraphNode('9') ] graph = Graph(*vertices) graph.add_edge('5', '11') graph.add_edge('7', '11') graph.add_edge('7', '8') graph.add_edge('3', '8') graph.add_edge('3', '10') graph.add_edge('11', '2') graph.add_edge('11', '9') graph.add_edge('11', '10') graph.add_edge('8', '9') if threads is not None: l = func(graph, algorithm, threads) else: l = func(graph, algorithm) assert all([(l1 in l[0:3]) for l1 in ('3', '5', '7')] + [(l2 in l[3:5]) for l2 in ('8', '11')] + [(l3 in l[5:]) for l3 in ('10', '9', '2')])
def _test_shortest_paths(ds, algorithm): import pydatastructs.utils.misc_util as utils GraphNode = getattr(utils, "Adjacency" + ds + "GraphNode") vertices = [ GraphNode('S'), GraphNode('C'), GraphNode('SLC'), GraphNode('SF'), GraphNode('D') ] graph = Graph(*vertices) graph.add_edge('S', 'SLC', 2) graph.add_edge('C', 'S', 4) graph.add_edge('C', 'D', 2) graph.add_edge('SLC', 'C', 2) graph.add_edge('SLC', 'D', 3) graph.add_edge('SF', 'SLC', 2) graph.add_edge('SF', 'S', 2) graph.add_edge('D', 'SF', 3) dist, pred = shortest_paths(graph, algorithm, 'SLC') assert dist == {'S': 6, 'C': 2, 'SLC': 0, 'SF': 6, 'D': 3} assert pred == { 'S': 'C', 'C': 'SLC', 'SLC': None, 'SF': 'D', 'D': 'SLC' } dist, pred = shortest_paths(graph, algorithm, 'SLC', 'SF') assert dist == 6 assert pred == { 'S': 'C', 'C': 'SLC', 'SLC': None, 'SF': 'D', 'D': 'SLC' } graph.remove_edge('SLC', 'D') graph.add_edge('D', 'SLC', -10) assert raises(ValueError, lambda: shortest_paths(graph, 'bellman_ford', 'SLC'))
def _test_strongly_connected_components(func, ds, algorithm, *args): import pydatastructs.utils.misc_util as utils GraphNode = getattr(utils, "Adjacency" + ds + "GraphNode") a, b, c, d, e, f, g, h = \ [GraphNode(chr(x)) for x in range(ord('a'), ord('h') + 1)] graph = Graph(a, b, c, d, e, f, g, h) graph.add_edge(a.name, b.name) graph.add_edge(b.name, c.name) graph.add_edge(b.name, f.name) graph.add_edge(b.name, e.name) graph.add_edge(c.name, d.name) graph.add_edge(c.name, g.name) graph.add_edge(d.name, h.name) graph.add_edge(d.name, c.name) graph.add_edge(e.name, f.name) graph.add_edge(e.name, a.name) graph.add_edge(f.name, g.name) graph.add_edge(g.name, f.name) graph.add_edge(h.name, d.name) graph.add_edge(h.name, g.name) comps = func(graph, algorithm) expected_comps = [{'e', 'a', 'b'}, {'d', 'c', 'h'}, {'g', 'f'}] assert comps == expected_comps
def _test_shortest_paths_negative_edges(ds, algorithm): import pydatastructs.utils.misc_util as utils GraphNode = getattr(utils, "Adjacency" + ds + "GraphNode") vertices = [ GraphNode('1'), GraphNode('2'), GraphNode('3'), GraphNode('4') ] graph = Graph(*vertices) graph.add_edge('1', '3', -2) graph.add_edge('2', '1', 4) graph.add_edge('2', '3', 3) graph.add_edge('3', '4', 2) graph.add_edge('4', '2', -1) dist, next_v = shortest_paths(graph, algorithm, 's') assert dist == { '1': { '3': -2, '1': 0, '4': 0, '2': -1 }, '2': { '1': 4, '3': 2, '2': 0, '4': 4 }, '3': { '4': 2, '3': 0, '1': 5, '2': 1 }, '4': { '2': -1, '4': 0, '1': 3, '3': 1 } } assert next_v == { '1': { '3': '1', '1': '1', '4': None, '2': None }, '2': { '1': '2', '3': None, '2': '2', '4': None }, '3': { '4': '3', '3': '3', '1': None, '2': None }, '4': { '2': '4', '4': '4', '1': None, '3': None } }