class TestBoruvkaDisconnectedGraph(unittest.TestCase): def setUp(self): # The modified graph (unique weights) from Cormen. self.N = 9 # number of nodes self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [ Edge(0, 1, 4), Edge(0, 7, 8), Edge(1, 7, 11), Edge(1, 2, 12), Edge(7, 8, 7), Edge(8, 2, 2), Edge(8, 6, 6), Edge(7, 6, 1), Edge(3, 5, 14), Edge(3, 4, 9), Edge(5, 4, 10)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #print self.G def test_boruvka(self): self.assertEqual(self.G.v(), self.N) algorithm = BoruvkaMST(self.G) algorithm.run() self.assertEqual(algorithm.mst.v(), self.N) self.assertEqual(algorithm.mst.e(), self.N-2) # 2 components mst_weight_expected = 40 mst_weight = sum(edge.weight for edge in algorithm.mst.iteredges()) self.assertEqual(mst_weight, mst_weight_expected) mst_edges_expected = [ Edge(0, 1, 4), Edge(0, 7, 8), Edge(8, 2, 2), Edge(7, 6, 1), Edge(6, 8, 6), Edge(3, 4, 9), Edge(5, 4, 10)] for edge in mst_edges_expected: self.assertTrue(algorithm.mst.has_edge(edge)) def tearDown(self): pass
class TestStronglyConnectedComponents(unittest.TestCase): def setUp(self): self.N = 8 # number of nodes self.G = Graph(self.N, directed=True) self.nodes = range(self.N) self.edges = [ Edge(0, 1), Edge(1, 4), Edge(4, 0), Edge(4, 5), Edge(1, 5), Edge(1, 2), Edge(5, 6), Edge(6, 5), Edge(2, 6), Edge(2, 3), Edge(3, 2), Edge(6, 7), Edge(3, 7)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() self.expected_scc = {0: 0, 1: 0, 2: 1, 3: 1, 4: 0, 5: 2, 6: 2, 7: 3} self.expected_n_scc = 4 def test_scc(self): algorithm = StronglyConnectedComponents(self.G) algorithm.run() self.assertEqual(algorithm.n_scc, self.expected_n_scc) self.assertEqual(algorithm.scc, self.expected_scc) self.assertRaises( ValueError, StronglyConnectedComponents, Graph(1, False)) def tearDown(self): pass
class TestFordFulkerson(unittest.TestCase): def setUp(self): self.N = 4 # number of nodes self.G = Graph(self.N, directed=True) self.nodes = range(self.N) self.edges = [Edge(0, 1, 10), Edge(0, 2, 10), Edge(1, 2, 1), Edge(1, 3, 10), Edge(2, 3, 10)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) # self.G.show() def test_fordfulkerson(self): algorithm = FordFulkerson(self.G) algorithm.run(0, 3) expected_max_flow = 20 expected_flow = { 0: {0: 0, 2: 10, 1: 10, 3: 0}, 1: {0: -10, 2: 0, 1: 0, 3: 10}, 2: {0: -10, 2: 0, 1: 0, 3: 10}, 3: {0: 0, 2: -10, 1: -10, 3: 0}, } self.assertEqual(algorithm.max_flow, expected_max_flow) self.assertEqual(algorithm.flow, expected_flow) def test_fordfulkerson_sparse(self): algorithm = FordFulkersonSparse(self.G) algorithm.run(0, 3) expected_max_flow = 20 expected_flow = {0: {2: 10, 1: 10}, 1: {0: -10, 3: 10}, 2: {0: -10, 3: 10}, 3: {2: -10, 1: -10}} self.assertEqual(algorithm.max_flow, expected_max_flow) self.assertEqual(algorithm.flow, expected_flow)
class TestBellmanFordCormen(unittest.TestCase): def setUp(self): # The graph from Cormen p.666, negative weights. self.N = 5 # number of nodes self.G = Graph(self.N, directed=True) self.nodes = range(self.N) self.edges = [ Edge(0, 1, 6), Edge(0, 3, 7), Edge(1, 3, 8), Edge(1, 2, 5), Edge(1, 4, -4), Edge(2, 1, -2), Edge(3, 2, -3), Edge(3, 4, 9), Edge(4, 0, 2), Edge(4, 2, 7)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_shortest_path_cormen(self): source = 0 target = 4 algorithm = BellmanFord(self.G) algorithm.run(source) distance_expected = {3: 7, 2: 4, 0: 0, 4: -2, 1: 2} self.assertEqual(algorithm.distance, distance_expected) parent_expected = {3: 0, 2: 3, 0: None, 4: 1, 1: 2} self.assertEqual(algorithm.parent, parent_expected) path_expected = [0, 3, 2, 1, 4] self.assertEqual(algorithm.path(target), path_expected) def tearDown(self): pass
def test_halin16(self): N = 16 G = Graph(N, False) edges = [Edge(0, 1), Edge(0, 2), Edge(0, 15), Edge(1, 2), Edge(1, 6), Edge(2, 3), Edge(3, 4), Edge(3, 5), Edge(4, 5), Edge(4, 10), Edge(5, 6), Edge(6, 7), Edge(7, 8), Edge(7, 15), Edge(8, 9), Edge(8, 13), Edge(9, 10), Edge(9, 11), Edge(10, 11), Edge(11, 12), Edge(12, 13), Edge(12, 14), Edge(13, 14), Edge(14, 15)] for node in range(N): G.add_node(node) for edge in edges: G.add_edge(edge) #print "halin16" algorithm = HalinNodeColoring(G, outer=set([0, 2, 3, 4, 10, 11, 12, 14, 15])) algorithm.run() #print "halin16 outer", algorithm.outer parent = {0: 1, 1: None, 2: 1, 3: 5, 4: 5, 5: 6, 6: 1, 7: 6, 8: 7, 9: 8, 10: 9, 11: 9, 12: 13, 13: 8, 14: 13, 15: 7} self.assertEqual(algorithm.parent, parent) for node in G.iternodes(): self.assertNotEqual(algorithm.color[node], None) for edge in G.iteredges(): self.assertNotEqual(algorithm.color[edge.source], algorithm.color[edge.target]) all_colors = set(algorithm.color[node] for node in G.iternodes()) self.assertEqual(len(all_colors), 3)
class TestBellmanFord(unittest.TestCase): def setUp(self): self.N = 4 # number of nodes self.G = Graph(self.N, directed=True) # directed graph self.nodes = range(self.N) self.edges = [ Edge(0, 1, 1), Edge(0, 2, 5), Edge(1, 2, 1), Edge(1, 3, 3), Edge(2, 3, 1)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_shortest_path(self): source = 0 target = 3 algorithm = BellmanFord(self.G) algorithm.run(source) distance_expected = {0: 0, 2: 2, 1: 1, 3: 3} self.assertEqual(algorithm.distance, distance_expected) parent_expected = {0: None, 2: 1, 1: 0, 3: 2} self.assertEqual(algorithm.parent, parent_expected) path_expected = [0, 1, 2, 3] self.assertEqual(algorithm.path(target), path_expected) def tearDown(self): pass
class TestEdmondsKarpWiki(unittest.TestCase): def setUp(self): self.N = 7 # number of nodes self.G = Graph(self.N, directed=True) self.nodes = range(self.N) self.edges = [ Edge(0, 1, 3), Edge(0, 3, 3), Edge(1, 2, 4), Edge(2, 0, 3), Edge(2, 3, 1), Edge(2, 4, 2), Edge(3, 4, 2), Edge(3, 5, 6), Edge(4, 1, 1), Edge(4, 6, 1), Edge(5, 6, 9)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_wiki_sparse(self): algorithm = EdmondsKarpSparse(self.G) algorithm.run(0, 6) expected_max_flow = 5 expected_flow = { 0: {1: 2, 3: 3}, 1: {0: -2, 2: 2}, 2: {1: -2, 4: 1, 3: 1}, 3: {0: -3, 2: -1, 4: 0, 5: 4}, 4: {2: -1, 3: 0, 6: 1}, 5: {3: -4, 6: 4}, 6: {4: -1, 5: -4}} self.assertEqual(algorithm.max_flow, expected_max_flow) self.assertEqual(algorithm.flow, expected_flow) def tearDown(self): pass
def test_frucht12(self): N = 10 G = Graph(N, False) edges = [Edge(0, 1), Edge(0, 4), Edge(0, 11), Edge(1, 2), Edge(1, 10), Edge(2, 3), Edge(2, 7), Edge(3, 4), Edge(3, 5), Edge(4, 5), Edge(5, 6), Edge(6, 7), Edge(6, 8), Edge(7, 8), Edge(8, 9), Edge(9, 10), Edge(9, 11), Edge(10, 11)] for node in range(N): G.add_node(node) for edge in edges: G.add_edge(edge) #print "frucht12" algorithm = HalinNodeColoring(G, outer=set([0, 4, 5, 6, 8, 9, 11])) algorithm.run() #print "frucht12 outer", algorithm.outer parent = {0: 1, 1: None, 2: 1, 3: 2, 4: 3, 5: 3, 6: 7, 7: 2, 8: 7, 9: 10, 10: 1, 11: 10} self.assertEqual(algorithm.parent, parent) for node in G.iternodes(): self.assertNotEqual(algorithm.color[node], None) for edge in G.iteredges(): self.assertNotEqual(algorithm.color[edge.source], algorithm.color[edge.target]) all_colors = set(algorithm.color[node] for node in G.iternodes()) self.assertEqual(len(all_colors), 3)
class TestMatchingWithWeights(unittest.TestCase): def setUp(self): # Graf pelny z kolejnymi wagami. self.N = 4 self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [Edge(0, 1, 5), Edge(0, 2, 7), Edge(0, 3, 2), Edge(1, 2, 3), Edge(1, 3, 6), Edge(2, 3, 4)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_min_weight_matching(self): algorithm = MinimumWeightMatchingWithEdges(self.G) algorithm.run() expected_cardinality = 2 expected_weight = 5 expected_mate = {0: Edge(0, 3, 2), 1: Edge(1, 2, 3), 2: Edge(2, 1, 3), 3: Edge(3, 0, 2)} self.assertEqual(algorithm.cardinality, expected_cardinality) # Krawedzie sa po dwa razy w slowniku. weight = sum(algorithm.mate[node].weight for node in algorithm.mate if algorithm.mate[node]) / 2 self.assertEqual(weight, expected_weight) self.assertEqual(algorithm.mate, expected_mate) # Is it matching? for source in algorithm.mate: if algorithm.mate[source] is not None: edge = algorithm.mate[source] self.assertEqual(algorithm.mate[edge.target], ~edge) def tearDown(self): pass
class TestMatching3(unittest.TestCase): def setUp(self): self.N = 6 self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [Edge(0, 1), Edge(1, 2), Edge(2, 3), Edge(3, 4), Edge(4, 5)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_matching(self): algorithm = BorieMatching(self.G) algorithm.run() expected1 = set([Edge(0, 1), Edge(2, 3), Edge(4, 5)]) self.assertEqual(algorithm.cardinality, len(expected1)) self.assertEqual(algorithm.mate_set, expected1) # Testing matching. S = set() for edge in algorithm.mate_set: S.add(edge.source) S.add(edge.target) self.assertEqual(len(S), 2 * len(algorithm.mate_set)) def tearDown(self): pass
class TestBoruvkaWiki(unittest.TestCase): def setUp(self): # The graph (unique weights) from # http://en.wikipedia.org/wiki/Boruvka's_algorithm self.N = 7 # number of nodes self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [ Edge(0, 1, 7), Edge(1, 2, 11), Edge(0, 3, 4), Edge(3, 1, 9), Edge(4, 1, 10), Edge(2, 4, 5), Edge(3, 4, 15), Edge(3, 5, 6), Edge(5, 4, 12), Edge(5, 6, 13), Edge(4, 6, 8)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #print self.G def test_boruvka(self): self.assertEqual(self.G.v(), self.N) algorithm = BoruvkaMST(self.G) algorithm.run() self.assertEqual(algorithm.mst.v(), self.N) self.assertEqual(algorithm.mst.e(), self.N-1) mst_weight_expected = 40 mst_weight = sum(edge.weight for edge in algorithm.mst.iteredges()) self.assertEqual(mst_weight, mst_weight_expected) mst_edges_expected = [ Edge(0, 1, 7), Edge(0, 3, 4), Edge(2, 4, 5), Edge(1, 4, 10), Edge(4, 6, 8), Edge(3, 5, 6)] for edge in mst_edges_expected: self.assertTrue(algorithm.mst.has_edge(edge)) def tearDown(self): pass
def test_center_two2(self): T = Graph(2) T.add_edge(Edge(0, 1)) algorithm = TreeCenter(T) algorithm.run() self.assertEqual(algorithm.tree_center, [0, 1]) self.assertEqual(algorithm.tree_radius, 1)
class TestFloydWarshallAllGraphs(unittest.TestCase): def setUp(self): self.N = 5 # number of nodes self.G = Graph(self.N, directed=False) self.nodes = range(self.N) self.edges = [ Edge(0, 2, 6), Edge(0, 3, 3), Edge(1, 0, 3), Edge(2, 3, 2), Edge(3, 1, 1), Edge(4, 1, 4), Edge(4, 3, 2)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_floydwarshall(self): algorithm = FloydWarshallAllGraphs(self.G) algorithm.run() expected_distance = { 0: {0: 0, 1: 3, 2: 5, 3: 3, 4: 5}, 1: {0: 3, 1: 0, 2: 3, 3: 1, 4: 3}, 2: {0: 5, 1: 3, 2: 0, 3: 2, 4: 4}, 3: {0: 3, 1: 1, 2: 2, 3: 0, 4: 2}, 4: {0: 5, 1: 3, 2: 4, 3: 2, 4: 0}} self.assertEqual(algorithm.distance, expected_distance) def test_negative_edge(self): # An edge with the negative weight gives a negative cycle. self.G.add_edge(Edge(2, 4, -1)) algorithm = FloydWarshallAllGraphs(self.G) self.assertRaises(ValueError, algorithm.run)
class TestJohnsonWiki(unittest.TestCase): def setUp(self): self.N = 4 # number of nodes self.G = Graph(self.N, directed=True) self.nodes = range(self.N) self.edges = [ Edge(0, 1, 3), Edge(0, 3, 6), Edge(1, 3, 4), Edge(1, 2, 5), Edge(3, 2, 2), Edge(2, 0, -7), Edge(2, 1, -3)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) def test_johnson(self): algorithm = Johnson(self.G) algorithm.run() expected_distance = { 0: {1: 3, 0: 0, 2: 8, 3: 6}, 1: {1: 0, 0: -2, 2: 5, 3: 4}, 2: {1: -4, 0: -7, 2: 0, 3: -1}, 3: {1: -2, 0: -5, 2: 2, 3: 0}} self.assertEqual(algorithm.distance, expected_distance) def test_johnson_faster(self): algorithm = JohnsonFaster(self.G) algorithm.run() expected_distance = { 0: {1: 3, 0: 0, 2: 8, 3: 6}, 1: {1: 0, 0: -2, 2: 5, 3: 4}, 2: {1: -4, 0: -7, 2: 0, 3: -1}, 3: {1: -2, 0: -5, 2: 2, 3: 0}} self.assertEqual(algorithm.distance, expected_distance)
class TestNodeColoring(unittest.TestCase): def setUp(self): self.N = 6 self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [ Edge(0, 1), Edge(0, 3), Edge(1, 3), Edge(1, 4), Edge(1, 2), Edge(2, 4), Edge(2, 5), Edge(3, 4), Edge(4, 5)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_us_node_coloring(self): algorithm = UnorderedSequentialNodeColoring(self.G) algorithm.run() for node in self.G.iternodes(): self.assertNotEqual(algorithm.color[node], None) for edge in self.G.iteredges(): self.assertNotEqual(algorithm.color[edge.source], algorithm.color[edge.target]) #print algorithm.color all_colors = set(algorithm.color[node] for node in self.G.iternodes()) self.assertEqual(len(all_colors), 4) def test_exceptions(self): self.assertRaises(ValueError, UnorderedSequentialNodeColoring, Graph(5, directed=True)) def tearDown(self): pass
def test_tree_three_nodes(self): T = Graph(3) for node in (0, 1, 2): T.add_node(node) for edge in (Edge(0, 1), Edge(1, 2)): T.add_edge(edge) algorithm = TreePlot(T) algorithm.run() self.assertEqual(len(algorithm.point_dict), 3)
class TestIndependentSet3(unittest.TestCase): def setUp(self): self.N = 6 self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [Edge(0, 1), Edge(1, 2), Edge(2, 3), Edge(3, 4), Edge(4, 5)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_borie_iset(self): algorithm = BorieIndependentSet(self.G) algorithm.run() expected1 = set([0, 2, 5]) expected2 = set([0, 3, 5]) expected3 = set([0, 2, 4]) expected4 = set([1, 3, 5]) self.assertEqual(algorithm.cardinality, len(expected1)) self.assertEqual(algorithm.independent_set, expected3) # Testing iset. for edge in self.G.iteredges(): self.assertFalse(edge.source in algorithm.independent_set and edge.target in algorithm.independent_set) def test_tree_iset1(self): algorithm = TreeIndependentSet1(self.G) algorithm.run() expected1 = set([0, 2, 5]) expected2 = set([0, 3, 5]) expected3 = set([0, 2, 4]) expected4 = set([1, 3, 5]) self.assertEqual(algorithm.cardinality, len(expected1)) self.assertEqual(algorithm.independent_set, expected1) # Testing iset. for edge in self.G.iteredges(): self.assertFalse(edge.source in algorithm.independent_set and edge.target in algorithm.independent_set) def test_tree_iset2(self): algorithm = TreeIndependentSet2(self.G) algorithm.run() expected1 = set([0, 2, 5]) expected2 = set([0, 3, 5]) expected3 = set([0, 2, 4]) expected4 = set([1, 3, 5]) self.assertEqual(algorithm.cardinality, len(expected1)) self.assertEqual(algorithm.independent_set, expected1) # Testing iset. for edge in self.G.iteredges(): self.assertFalse(edge.source in algorithm.independent_set and edge.target in algorithm.independent_set) def tearDown(self): pass
class TestNodeCover3(unittest.TestCase): def setUp(self): self.N = 6 self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [Edge(0, 1), Edge(1, 2), Edge(2, 3), Edge(3, 4), Edge(4, 5)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_borie_node_cover(self): algorithm = BorieNodeCover(self.G) algorithm.run() expected1 = set([1, 2, 4]) expected2 = set([1, 3, 4]) expected3 = set([0, 2, 4]) expected4 = set([1, 3, 5]) self.assertEqual(algorithm.cardinality, len(expected1)) self.assertEqual(algorithm.node_cover, expected3) # Testing cover. for edge in self.G.iteredges(): self.assertTrue(edge.source in algorithm.node_cover or edge.target in algorithm.node_cover) def test_tree_node_cover1(self): algorithm = TreeNodeCover1(self.G) algorithm.run() expected1 = set([1, 2, 4]) expected2 = set([1, 3, 4]) expected3 = set([0, 2, 4]) expected4 = set([1, 3, 5]) self.assertEqual(algorithm.cardinality, len(expected1)) self.assertEqual(algorithm.node_cover, expected2) # Testing cover. for edge in self.G.iteredges(): self.assertTrue(edge.source in algorithm.node_cover or edge.target in algorithm.node_cover) def test_tree_node_cover2(self): algorithm = TreeNodeCover2(self.G) algorithm.run() expected1 = set([1, 2, 4]) expected2 = set([1, 3, 4]) expected3 = set([0, 2, 4]) expected4 = set([1, 3, 5]) self.assertEqual(algorithm.cardinality, len(expected1)) self.assertEqual(algorithm.node_cover, expected2) # Testing cover. for edge in self.G.iteredges(): self.assertTrue(edge.source in algorithm.node_cover or edge.target in algorithm.node_cover) def tearDown(self): pass
class TestFleuryDirectedGraph(unittest.TestCase): def setUp(self): self.N = 6 # number of nodes self.G = Graph(self.N, directed=True) self.nodes = range(self.N) self.edges = [ Edge(0, 1), Edge(3, 0), Edge(1, 4), Edge(4, 3), Edge(2, 4), Edge(4, 5), Edge(5, 2)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) def test_fleury_dfs(self): algorithm = FleuryDFS(self.G) algorithm.run(0) expected_cycle = [0, 1, 4, 5, 2, 4, 3, 0] self.assertEqual(len(algorithm.eulerian_cycle), len(self.edges) + 1) self.assertEqual(algorithm.eulerian_cycle, expected_cycle) def test_fleury_bfs(self): algorithm = FleuryBFS(self.G) algorithm.run(0) expected_cycle = [0, 1, 4, 5, 2, 4, 3, 0] self.assertEqual(len(algorithm.eulerian_cycle), len(self.edges) + 1) self.assertEqual(algorithm.eulerian_cycle, expected_cycle) def test_fleury_dfs_with_edges(self): algorithm = FleuryDFSWithEdges(self.G) algorithm.run(0) #expected_cycle = [0, 1, 4, 5, 2, 4, 3, 0] expected_cycle = [ Edge(0, 1), Edge(1, 4), Edge(4, 5), Edge(5, 2), Edge(2, 4), Edge(4, 3), Edge(3, 0)] self.assertEqual(len(algorithm.eulerian_cycle), len(self.edges)) self.assertEqual(algorithm.eulerian_cycle, expected_cycle) def test_fleury_bfs_with_edges(self): algorithm = FleuryBFSWithEdges(self.G) algorithm.run(0) #expected_cycle = [0, 1, 4, 5, 2, 4, 3, 0] expected_cycle = [ Edge(0, 1), Edge(1, 4), Edge(4, 5), Edge(5, 2), Edge(2, 4), Edge(4, 3), Edge(3, 0)] self.assertEqual(len(algorithm.eulerian_cycle), len(self.edges)) self.assertEqual(algorithm.eulerian_cycle, expected_cycle) def test_eulerian(self): self.G.add_edge(Edge(1, 2)) self.assertRaises(ValueError, FleuryDFS, self.G) self.assertRaises(ValueError, FleuryBFS, self.G) self.assertRaises(ValueError, FleuryDFSWithEdges, self.G) self.assertRaises(ValueError, FleuryBFSWithEdges, self.G) def tearDown(self): pass
def test_add_graph_undirected(self): T = Graph(self.N) for node in self.nodes: T.add_node(node) T.add_edge(Edge("A", "D", 9)) self.assertEqual(T.v(), self.N) self.assertEqual(T.e(), 1) self.G.add_graph(T) self.assertEqual(self.G.v(), self.N) self.assertEqual(self.G.e(), 6)
class TestIndependentSet(unittest.TestCase): def setUp(self): self.N = 6 self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [ Edge(0, 1), Edge(0, 3), Edge(1, 3), Edge(1, 4), Edge(1, 2), Edge(2, 5), Edge(3, 4), Edge(4, 5)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_us_independent_set1(self): algorithm = UnorderedSequentialIndependentSet1(self.G) #algorithm.run() # przypadkiem znajduje najlepsze rozwiazanie algorithm.run(3) # znajduje set([2, 3]) for edge in self.G.iteredges(): self.assertFalse(edge.source in algorithm.independent_set and edge.target in algorithm.independent_set) self.assertEqual(algorithm.cardinality, len(algorithm.independent_set)) #print algorithm.independent_set def test_us_independent_set2(self): algorithm = UnorderedSequentialIndependentSet2(self.G) #algorithm.run() # przypadkiem znajduje najlepsze rozwiazanie algorithm.run(3) # znajduje set([2, 3]) for edge in self.G.iteredges(): self.assertFalse(edge.source in algorithm.independent_set and edge.target in algorithm.independent_set) self.assertEqual(algorithm.cardinality, len(algorithm.independent_set)) #print algorithm.independent_set def test_us_independent_set3(self): algorithm = UnorderedSequentialIndependentSet3(self.G) #algorithm.run() # przypadkiem znajduje najlepsze rozwiazanie algorithm.run(3) # znajduje set([2, 3]) for edge in self.G.iteredges(): self.assertFalse(algorithm.independent_set[edge.source] and algorithm.independent_set[edge.target]) cardinality = sum(1 for node in self.G if algorithm.independent_set[node]) self.assertEqual(algorithm.cardinality, cardinality) #print algorithm.independent_set def test_exceptions(self): self.assertRaises(ValueError, UnorderedSequentialIndependentSet1, Graph(5, directed=True)) self.assertRaises(ValueError, UnorderedSequentialIndependentSet2, Graph(5, directed=True)) self.assertRaises(ValueError, UnorderedSequentialIndependentSet3, Graph(5, directed=True)) def tearDown(self): pass
def test_wheel_true(self): v = 10 G = Graph(v, False) for node in range(v): G.add_node(node) hub = 0 for node in range(1, v): G.add_edge(Edge(hub, node)) G.add_edge(Edge(node, node+1 if node < v-1 else 1)) self.assertTrue(is_wheel(G)) algorithm = WheelGraph(G) algorithm.run() self.assertEqual(algorithm.hub, hub)
def test_4prism(self): N = 8 G = Graph(N, False) edges = [Edge(0, 1), Edge(1, 2), Edge(2, 3), Edge(3, 0), Edge(4, 5), Edge(5, 6), Edge(6, 7), Edge(7, 4), Edge(0, 4), Edge(1, 5), Edge(2, 6), Edge(3, 7)] for node in range(N): G.add_node(node) for edge in edges: G.add_edge(edge) #G.show() algorithm = HalinGraph(G) self.assertRaises(ValueError, algorithm.run)
def make_halin_cubic_outer(n=4): """Create a random weighted cubic Halin graph with the set of outer nodes.""" if n < 4: raise ValueError("number of nodes must be greater than 3") if n % 2: raise ValueError("odd number of nodes") graph = Graph(n) weights = list(range(1, 1 + 3 * n // 2)) random.shuffle(weights) for node in xrange(n): graph.add_node(node) # Teraz trzeba dodawac krawedzie, ale nie moze zostac wierzcholek # stopnia 2. Startuje od gwiazdy. graph.add_edge(Edge(1, 0, weights.pop())) graph.add_edge(Edge(2, 0, weights.pop())) graph.add_edge(Edge(3, 0, weights.pop())) nodes = set([1, 2, 3]) node = 4 while node < n: parent = random.sample(nodes, 1)[0] nodes.remove(parent) # to juz nie bedzie lisc nodes.add(node) # nowy lisc graph.add_edge(Edge(parent, node, weights.pop())) node += 1 nodes.add(node) # nowy lisc graph.add_edge(Edge(parent, node, weights.pop())) node += 1 # Method 1. Finding root without TreeCenter. for node in graph.iternodes(): if graph.degree(node) > 1: # always present root = node break # Method 2. Finding root with TreeCenter. # TreeCenter reduces floating point errors for points. #algorithm = TreeCenter(graph) #algorithm.run() #root = algorithm.tree_center[0] # Wyznaczam slownik z punktami. algorithm = TreePlotRadiusAngle(graph) algorithm.run(root) #print algorithm.point_dict L = list() # for leafs for node in algorithm.point_dict: if graph.degree(node) == 1: # leaf L.append(node) # Sortowanie lisci ze wzgledu na kat. L.sort(key=lambda node: algorithm.point_dict[node][1]) n_leafs = len(L) for i in range(n_leafs): graph.add_edge(Edge(L[i], L[(i + 1) % n_leafs], weights.pop())) return graph, set(L)
class TestMatching(unittest.TestCase): def setUp(self): # Wilson, ex. 25.1, bipartite graph # 0 : 4 5 6 # 1 : 3 5 # 2 : 3 4 # ... self.N = 7 self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [ Edge(0, 4), Edge(0, 5), Edge(0, 6), Edge(1, 3), Edge(1, 5), Edge(2, 3), Edge(2, 4)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_maximal_matching(self): algorithm = MaximalMatching(self.G) algorithm.run() # 5 solutions expected_cardinality = 2 # max 3 expected_mate = {0: 4, 4: 0, 1: 3, 3: 1, 2: None, 5: None, 6: None} self.assertEqual(algorithm.cardinality, expected_cardinality) self.assertEqual(algorithm.mate, expected_mate) # Is it matching? for source in algorithm.mate: if algorithm.mate[source] is not None: target = algorithm.mate[source] self.assertEqual(algorithm.mate[target], source) def test_maximal_matching_with_edges(self): algorithm = MaximalMatchingWithEdges(self.G) algorithm.run() # 5 solutions expected_cardinality = 2 # max 3 expected_mate = {0: Edge(0, 4), 1: Edge(1, 3), 2: None, 3: Edge(3, 1), 4: Edge(4, 0), 5: None, 6: None} self.assertEqual(algorithm.cardinality, expected_cardinality) self.assertEqual(algorithm.mate, expected_mate) # Is it matching? for source in algorithm.mate: if algorithm.mate[source] is not None: edge = algorithm.mate[source] self.assertEqual(algorithm.mate[edge.target], ~edge) def tearDown(self): pass
def test_tree_three_nodes_radius_angle(self): T = Graph(3) for node in (0, 1, 2): T.add_node(node) for edge in (Edge(0, 1), Edge(1, 2)): T.add_edge(edge) algorithm = TreePlotRadiusAngle(T) algorithm.run() self.assertEqual(len(algorithm.point_dict), 3) #print algorithm.point_dict self.assertEqual(algorithm.point_dict, {0: (1, Fraction(3, 2)), 1: (0, Fraction(3, 1)), 2: (1, Fraction(9, 2))})
def test_wheel5(self): N = 5 G = Graph(N, False) edges = [Edge(0, 1), Edge(0, 2), Edge(0, 3), Edge(0, 4), Edge(1, 2), Edge(2, 3), Edge(3, 4), Edge(4, 1)] for node in range(N): G.add_node(node) for edge in edges: G.add_edge(edge) algorithm = HalinGraph(G) algorithm.run() #print "wheel5 outer", algorithm.outer self.assertEqual(algorithm.outer, set([1, 2, 3, 4])) self.assertTrue(algorithm.is_outer_k4())
class TestTSP(unittest.TestCase): def setUp(self): self.N = 4 self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [ Edge(0, 1, 20), Edge(0, 3, 35), Edge(0, 2, 42), Edge(1, 2, 30), Edge(1, 3, 34), Edge(2, 3, 12)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) self.best_weight = 97 #self.G.show() def test_brute_force_with_edges(self): algorithm = BruteForceTSPWithEdges(self.G) algorithm.run(2) # Cycles for different starting nodes. expected_hamiltonian_cycle0 = [ Edge(0, 1, 20), Edge(1, 2, 30), Edge(2, 3, 12), Edge(3, 0, 35)] expected_hamiltonian_cycle1 = [ Edge(1, 0, 20), Edge(0, 3, 35), Edge(3, 2, 12), Edge(2, 1, 30)] expected_hamiltonian_cycle2 = [ Edge(2, 1, 30), Edge(1, 0, 20), Edge(0, 3, 35), Edge(3, 2, 12)] expected_hamiltonian_cycle3 = [ Edge(3, 0, 35), Edge(0, 1, 20), Edge(1, 2, 30), Edge(2, 3, 12)] expected_hamiltonian_cycle = expected_hamiltonian_cycle2 self.assertEqual(algorithm.hamiltonian_cycle, expected_hamiltonian_cycle) weight = sum(edge.weight for edge in algorithm.hamiltonian_cycle) self.assertEqual(weight, self.best_weight) def test_brute_force_with_cycle_graph(self): algorithm = BruteForceTSPWithGraph(self.G) algorithm.run(2) # Hamiltonian cycle as a graph. weight = sum(edge.weight for edge in algorithm.hamiltonian_cycle.iteredges()) self.assertEqual(weight, self.best_weight) #algorithm.hamiltonian_cycle.show() self.assertEqual(algorithm.hamiltonian_cycle.e(), algorithm.hamiltonian_cycle.v()) for node in algorithm.hamiltonian_cycle.iternodes(): self.assertEqual(algorithm.hamiltonian_cycle.degree(node), 2) def test_exceptions(self): self.assertRaises(ValueError, BruteForceTSPWithEdges, Graph(5, True)) self.assertRaises(ValueError, BruteForceTSPWithGraph, Graph(5, True)) def tearDown(self): pass
class TestFloydWarshall(unittest.TestCase): def setUp(self): self.N = 5 # number of nodes self.G = Graph(self.N, directed=True) self.nodes = range(self.N) self.edges = [ Edge(0, 2, 6), Edge(0, 3, 3), Edge(1, 0, 3), Edge(2, 3, 2), Edge(3, 1, 1), Edge(3, 2, 1), Edge(4, 1, 4), Edge(4, 3, 2)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_floydwarshall(self): algorithm = FloydWarshall(self.G) algorithm.run() expected_distance = { 0: {0: 0, 1: 4, 2: 4, 3: 3, 4: float("inf")}, 1: {0: 3, 1: 0, 2: 7, 3: 6, 4: float("inf")}, 2: {0: 6, 1: 3, 2: 0, 3: 2, 4: float("inf")}, 3: {0: 4, 1: 1, 2: 1, 3: 0, 4: float("inf")}, 4: {0: 6, 1: 3, 2: 3, 3: 2, 4: 0}} self.assertEqual(algorithm.distance, expected_distance) def test_floydwarshall_paths(self): algorithm = FloydWarshallPaths(self.G) algorithm.run() expected_distance = { 0: {0: 0, 1: 4, 2: 4, 3: 3, 4: float("inf")}, 1: {0: 3, 1: 0, 2: 7, 3: 6, 4: float("inf")}, 2: {0: 6, 1: 3, 2: 0, 3: 2, 4: float("inf")}, 3: {0: 4, 1: 1, 2: 1, 3: 0, 4: float("inf")}, 4: {0: 6, 1: 3, 2: 3, 3: 2, 4: 0}} expected_parent = { 0: {0: None, 2: 3, 1: 3, 4: None, 3: 0}, 1: {0: 1, 2: 3, 1: None, 4: None, 3: 0}, 2: {0: 1, 2: None, 1: 3, 4: None, 3: 2}, 3: {0: 1, 2: 3, 1: 3, 4: None, 3: None}, 4: {0: 1, 2: 3, 1: 3, 4: None, 3: 4}} self.assertEqual(algorithm.distance, expected_distance) self.assertEqual(algorithm.parent, expected_parent) self.assertEqual(algorithm.path(0, 1), [0, 3, 1]) def test_floydwarshall_negative_cycle(self): self.G.add_edge(Edge(1, 3, -2)) algorithm = FloydWarshall(self.G) self.assertRaises(ValueError, algorithm.run)
class TestNodeCover(unittest.TestCase): def setUp(self): self.N = 5 self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [Edge(0, 1), Edge(0, 2), Edge(1, 2), Edge(1, 3), Edge(1, 4)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() node1 = Node(0, 1, "edge") node2 = Node(0, 2, "edge") node3 = Node(2, 1, "edge") node4 = Node(1, 3, "edge") node5 = Node(1, 4, "edge") node6 = Node(0, 1, "series", node2, node3) node7 = Node(0, 1, "parallel", node1, node6) node8 = Node(0, 1, "jackknife", node7, node4) node9 = Node(0, 1, "jackknife", node8, node5) self.root = node9 def test_spgraph_node_cover(self): algorithm = SPGraphNodeCover(self.G, self.root) algorithm.run() expected1 = set([0, 1]) expected2 = set([1, 2]) self.assertEqual(algorithm.cardinality, len(expected1)) self.assertEqual(algorithm.node_cover, expected2) # Testing cover. for edge in self.G.iteredges(): self.assertTrue(edge.source in algorithm.node_cover or edge.target in algorithm.node_cover) def test_sptree_node_cover(self): algorithm = SPTreeNodeCover(self.root) algorithm.run() expected1 = set([0, 1]) expected2 = set([1, 2]) self.assertEqual(algorithm.cardinality, len(expected1)) self.assertEqual(algorithm.node_cover, expected2) # Testing cover. for edge in self.G.iteredges(): self.assertTrue(edge.source in algorithm.node_cover or edge.target in algorithm.node_cover) def tearDown(self): pass
class TestEdgeColoring(unittest.TestCase): def setUp(self): self.N = 6 self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [ Edge(0, 1), Edge(0, 3), Edge(1, 3), Edge(1, 4), Edge(1, 2), Edge(2, 4), Edge(2, 5), Edge(3, 4), Edge(4, 5)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_us_edge_coloring(self): algorithm = UnorderedSequentialEdgeColoring(self.G) algorithm.run() for edge in self.G.iteredges(): self.assertNotEqual(algorithm.color[edge], None) for node in self.G.iternodes(): color_set = set() for edge in self.G.iteroutedges(node): if edge.source > edge.target: color_set.add(algorithm.color[~edge]) else: color_set.add(algorithm.color[edge]) self.assertEqual(len(color_set), self.G.degree(node)) #print algorithm.color all_colors = set(algorithm.color[edge] for edge in self.G.iteredges()) self.assertEqual(len(all_colors), 5) def test_exceptions(self): self.assertRaises(ValueError, UnorderedSequentialEdgeColoring, Graph(5, directed=True)) def tearDown(self): pass
class TestEulerianCycleUndirected(unittest.TestCase): def setUp(self): self.N = 6 # number of nodes self.G = Graph(self.N, directed=False) self.nodes = range(self.N) self.edges = [ Edge(0, 1), Edge(0, 3), Edge(1, 4), Edge(3, 4), Edge(4, 2), Edge(4, 5), Edge(2, 5)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) def test_euler_dfs(self): algorithm = EulerianCycleDFS(self.G) algorithm.run(0) expected_cycle = [0, 1, 4, 2, 5, 4, 3, 0] self.assertEqual(len(algorithm.eulerian_cycle), len(self.edges) + 1) self.assertEqual(algorithm.eulerian_cycle, expected_cycle) def test_euler_dfs_with_edges(self): algorithm = EulerianCycleDFSWithEdges(self.G) algorithm.run(0) #expected_cycle = [0, 1, 4, 2, 5, 4, 3, 0] expected_cycle = [ Edge(0, 1), Edge(1, 4), Edge(4, 2), Edge(2, 5), Edge(5, 4), Edge(4, 3), Edge(3, 0)] self.assertEqual(len(algorithm.eulerian_cycle), len(self.edges)) self.assertEqual(algorithm.eulerian_cycle, expected_cycle) def test_eulerian(self): self.G.add_edge(Edge(1, 2)) self.assertRaises(ValueError, EulerianCycleDFS, self.G) self.assertRaises(ValueError, EulerianCycleDFSWithEdges, self.G) def tearDown(self): pass
class TestNodeColoring(unittest.TestCase): def setUp(self): self.N = 6 self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [ Edge(0, 1), Edge(0, 3), Edge(1, 3), Edge(1, 4), Edge(1, 2), Edge(2, 4), Edge(2, 5), Edge(3, 4), Edge(4, 5) ] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_brooks_node_coloring(self): algorithm = BrooksNodeColoring(self.G) algorithm.run() for node in self.G.iternodes(): self.assertNotEqual(algorithm.color[node], None) for edge in self.G.iteredges(): self.assertNotEqual(algorithm.color[edge.source], algorithm.color[edge.target]) #print algorithm.color all_colors = set(algorithm.color[node] for node in self.G.iternodes()) self.assertEqual(len(all_colors), 4) def test_brooks_node_coloring_regular(self): # Buduje graf 4-regularny planarny z Delta=4. # Graf jest 3-connected, dlatego algorytm dziala. self.G.add_edge(Edge(0, 2)) self.G.add_edge(Edge(3, 5)) self.G.add_edge(Edge(0, 5)) algorithm = BrooksNodeColoring(self.G) algorithm.run() for node in self.G.iternodes(): self.assertNotEqual(algorithm.color[node], None) for edge in self.G.iteredges(): self.assertNotEqual(algorithm.color[edge.source], algorithm.color[edge.target]) #print algorithm.color all_colors = set(algorithm.color[node] for node in self.G.iternodes()) self.assertEqual(len(all_colors), 3) # best def test_exceptions(self): self.assertRaises(ValueError, BrooksNodeColoring, Graph(5, directed=True)) def tearDown(self): pass
class TestEulerianCycleUndirected2(unittest.TestCase): def setUp(self): self.N = 7 # number of nodes self.G = Graph(self.N, directed=False) self.nodes = range(self.N) self.edges = [ Edge(0, 1), Edge(0, 4), Edge(1, 4), Edge(2, 3), Edge(2, 5), Edge(3, 5), Edge(4, 5), Edge(4, 6), Edge(5, 6)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) def test_hierholzer(self): algorithm = Hierholzer(self.G) algorithm.run(6) expected_cycle = [6, 4, 0, 1, 4, 5, 2, 3, 5, 6] self.assertEqual(len(algorithm.eulerian_cycle), len(self.edges) + 1) self.assertEqual(algorithm.eulerian_cycle, expected_cycle) def test_hierholzer_with_edges(self): algorithm = HierholzerWithEdges(self.G) algorithm.run(6) #expected_cycle = [6, 4, 0, 1, 4, 5, 2, 3, 5, 6] expected_cycle = [ Edge(6, 4), Edge(4, 0), Edge(0, 1), Edge(1, 4), Edge(4, 5), Edge(5, 2), Edge(2, 3), Edge(3, 5), Edge(5, 6)] self.assertEqual(len(algorithm.eulerian_cycle), len(self.edges)) self.assertEqual(algorithm.eulerian_cycle, expected_cycle) def test_eulerian(self): self.G.add_edge(Edge(1, 2)) self.assertRaises(ValueError, Hierholzer, self.G) def tearDown(self): pass
def make_random_ktree(n, k): # using list """Make a random k-tree with n vertices.""" if k >= n: raise ValueError("bad k") # run time error possible graph = Graph(n) if n < 1: raise ValueError("bad n") elif n == 1: graph.add_node(0) else: for node in xrange(n): graph.add_node(node) # Make {n-k-1, ..., n-1} into (k+1)-clique in graph. for source in xrange(n - k - 1, n): for target in xrange(n - k - 1, n): if source < target: graph.add_edge(Edge(source, target)) node = n - k - 2 while node >= 0: # Wybor source z przedzialu od node+1 do n-k-1. # To jest jakby wybor duzej (k+1)-kliki, source = random.choice(xrange(node + 1, n - k)) # Teraz zbieram wierzcholki tej kliki, ale one maja byc # wieksze od source, wieksze numery! neighbors = list(target for target in graph.iteradjacent(source) if source < target) neighbors.append(source) # closed neighborhood # Z duzej (k+1)-kliki wybieram mala k-klike. idx = random.randrange(0, len(neighbors)) swap(neighbors, idx, -1) neighbors.pop() # Connect node to all nodes from neighbors. for target in neighbors: graph.add_edge(Edge(node, target)) node -= 1 return graph
class TestNodeColoring3(unittest.TestCase): def setUp(self): self.N = 6 self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [ Edge(0, 1), Edge(0, 2), Edge(0, 5), Edge(1, 2), Edge(1, 4), Edge(2, 3), Edge(3, 4), Edge(3, 5), Edge(4, 5) ] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_brooks_node_coloring_regular(self): algorithm = BrooksNodeColoring(self.G) algorithm.run() for node in self.G.iternodes(): self.assertNotEqual(algorithm.color[node], None) for edge in self.G.iteredges(): self.assertNotEqual(algorithm.color[edge.source], algorithm.color[edge.target]) #print algorithm.color all_colors = set(algorithm.color[node] for node in self.G.iternodes()) self.assertEqual(len(all_colors), 3) def tearDown(self): pass
class TestTreeCenter(unittest.TestCase): def setUp(self): self.N = 7 # number of nodes self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [ Edge(0, 1), Edge(1, 2), Edge(1, 4), Edge(3, 4), Edge(4, 5), Edge(5, 6) ] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) def test_center_one(self): self.assertEqual(self.G.e(), self.N - 1) algorithm = TreeCenter(self.G) algorithm.run() self.assertEqual(algorithm.tree_center, [4]) self.assertEqual(algorithm.tree_radius, 2) def test_center_two(self): self.G.add_edge(Edge(6, 7)) algorithm = TreeCenter(self.G) algorithm.run() self.assertEqual(algorithm.tree_center, [4, 5]) self.assertEqual(algorithm.tree_radius, 3) def test_center_two2(self): T = Graph(2) T.add_edge(Edge(0, 1)) algorithm = TreeCenter(T) algorithm.run() self.assertEqual(algorithm.tree_center, [0, 1]) self.assertEqual(algorithm.tree_radius, 1) def test_cycle(self): self.G.add_edge(Edge(2, 4)) algorithm = TreeCenter(self.G) self.assertRaises(ValueError, algorithm.run) def test_directed_graph(self): self.G.directed = True self.assertRaises(ValueError, TreeCenter, self.G) def tearDown(self): pass
class TestAcyclicDirectedGraph(unittest.TestCase): def setUp(self): # The graph from self.N = 8 # number of nodes self.G = Graph(self.N, directed=True) self.nodes = range(self.N) self.edges = [ Edge(0, 1), Edge(1, 2), Edge(2, 3), Edge(0, 4), Edge(4, 5), Edge(5, 6), Edge(5, 7), Edge(5, 2), Edge(0, 7) ] self.cycle_edges = [Edge(3, 1), Edge(5, 4)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #print self.G #self.G.show() def test_detect_no_directed_cycles(self): self.assertEqual(self.G.v(), self.N) algorithm = AcyclicGraphDFS(self.G) algorithm.run(0) # in order to easy test parent_expected = {0: None, 2: 1, 1: 0, 4: 0, 3: 2, 6: 5, 5: 4, 7: 5} #parent_expected = {0: None, 2: 1, 1: 0, 4: 0, 3: 2, 6: 5, 5: 4, 7: 0} self.assertEqual(algorithm.parent, parent_expected) self.assertTrue(is_acyclic(self.G)) def test_detect_directed_cycle1(self): self.assertEqual(self.G.v(), self.N) self.G.add_edge(self.cycle_edges[0]) algorithm = AcyclicGraphDFS(self.G) self.assertRaises(ValueError, algorithm.run) self.assertFalse(is_acyclic(self.G)) def test_detect_directed_cycle2(self): self.assertEqual(self.G.v(), self.N) self.G.add_edge(self.cycle_edges[1]) algorithm = AcyclicGraphDFS(self.G) self.assertRaises(ValueError, algorithm.run) self.assertFalse(is_acyclic(self.G)) def tearDown(self): pass
class TestMaximumFlow3(unittest.TestCase): def setUp(self): self.N = 6 # number of nodes self.G = Graph(self.N, directed=True) self.nodes = range(self.N) self.edges = [ Edge(0, 1, 10), Edge(0, 2, 10), Edge(1, 2, 2), Edge(1, 3, 4), Edge(1, 4, 8), Edge(2, 4, 9), Edge(4, 3, 6), Edge(4, 5, 10), Edge(3, 5, 10) ] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_edmonds_karp(self): algorithm = EdmondsKarp(self.G) algorithm.run(0, 5) expected_max_flow = 19 expected_flow = { 0: { 0: 0, 1: 10, 2: 9, 3: 0, 4: 0, 5: 0 }, 1: { 0: -10, 1: 0, 2: 0, 3: 4, 4: 6, 5: 0 }, 2: { 0: -9, 1: 0, 2: 0, 3: 0, 4: 9, 5: 0 }, 3: { 0: 0, 1: -4, 2: 0, 3: 0, 4: -5, 5: 9 }, 4: { 0: 0, 1: -6, 2: -9, 3: 5, 4: 0, 5: 10 }, 5: { 0: 0, 1: 0, 2: 0, 3: -9, 4: -10, 5: 0 } } self.assertEqual(algorithm.max_flow, expected_max_flow) self.assertEqual(algorithm.flow, expected_flow) def test_edmonds_karp_sparse(self): algorithm = EdmondsKarpSparse(self.G) algorithm.run(0, 5) expected_max_flow = 19 expected_flow = { 0: { 1: 10, 2: 9 }, 1: { 0: -10, 2: 0, 3: 4, 4: 6 }, 2: { 0: -9, 1: 0, 4: 9 }, 3: { 1: -4, 4: -5, 5: 9 }, 4: { 1: -6, 2: -9, 3: 5, 5: 10 }, 5: { 3: -9, 4: -10 } } self.assertEqual(algorithm.max_flow, expected_max_flow) self.assertEqual(algorithm.flow, expected_flow) def test_exceptions(self): self.assertRaises(ValueError, EdmondsKarp, Graph()) self.assertRaises(ValueError, EdmondsKarpSparse, Graph()) self.assertRaises(ValueError, lambda: EdmondsKarp(self.G).run(0, 0)) self.assertRaises(ValueError, lambda: EdmondsKarpSparse(self.G).run(0, 0))
class TestPrim(unittest.TestCase): def setUp(self): # The graph (unique weights) from # http://en.wikipedia.org/wiki/Boruvka's_algorithm self.N = 7 # number of nodes self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [ Edge(0, 1, 7), Edge(1, 2, 11), Edge(0, 3, 4), Edge(3, 1, 9), Edge(4, 1, 10), Edge(2, 4, 5), Edge(3, 4, 15), Edge(3, 5, 6), Edge(5, 4, 12), Edge(5, 6, 13), Edge(4, 6, 8) ] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) def test_prim(self): self.assertEqual(self.G.v(), self.N) algorithm = PrimMST(self.G) algorithm.run() algorithm.to_tree() self.assertEqual(algorithm.mst.v(), self.N) self.assertEqual(algorithm.mst.e(), self.N - 1) mst_weight_expected = 40 mst_weight = sum(edge.weight for edge in algorithm.mst.iteredges()) self.assertEqual(mst_weight, mst_weight_expected) mst_edges_expected = [ Edge(0, 1, 7), Edge(0, 3, 4), Edge(2, 4, 5), Edge(1, 4, 10), Edge(4, 6, 8), Edge(3, 5, 6) ] for edge in mst_edges_expected: self.assertTrue(algorithm.mst.has_edge(edge)) def test_prim_with_edges(self): algorithm = PrimMSTWithEdges(self.G) algorithm.run() algorithm.to_tree() self.assertEqual(algorithm.mst.v(), self.N) self.assertEqual(algorithm.mst.e(), self.N - 1) mst_weight_expected = 40 mst_weight = sum(edge.weight for edge in algorithm.mst.iteredges()) self.assertEqual(mst_weight, mst_weight_expected) mst_edges_expected = [ Edge(0, 1, 7), Edge(0, 3, 4), Edge(2, 4, 5), Edge(1, 4, 10), Edge(4, 6, 8), Edge(3, 5, 6) ] for edge in mst_edges_expected: self.assertTrue(algorithm.mst.has_edge(edge)) def test_prim_matrix(self): self.assertEqual(self.G.v(), self.N) algorithm = PrimMatrixMST(self.G) algorithm.run() algorithm.to_tree() self.assertEqual(algorithm.mst.v(), self.N) self.assertEqual(algorithm.mst.e(), self.N - 1) mst_weight_expected = 40 mst_weight = sum(edge.weight for edge in algorithm.mst.iteredges()) self.assertEqual(mst_weight, mst_weight_expected) mst_edges_expected = [ Edge(0, 1, 7), Edge(0, 3, 4), Edge(2, 4, 5), Edge(1, 4, 10), Edge(4, 6, 8), Edge(3, 5, 6) ] for edge in mst_edges_expected: self.assertTrue(algorithm.mst.has_edge(edge)) def test_prim_matrix_with_edges(self): algorithm = PrimMatrixMSTWithEdges(self.G) algorithm.run() algorithm.to_tree() self.assertEqual(algorithm.mst.v(), self.N) self.assertEqual(algorithm.mst.e(), self.N - 1) mst_weight_expected = 40 mst_weight = sum(edge.weight for edge in algorithm.mst.iteredges()) self.assertEqual(mst_weight, mst_weight_expected) mst_edges_expected = [ Edge(0, 1, 7), Edge(0, 3, 4), Edge(2, 4, 5), Edge(1, 4, 10), Edge(4, 6, 8), Edge(3, 5, 6) ] for edge in mst_edges_expected: self.assertTrue(algorithm.mst.has_edge(edge)) def test_prim_connected(self): self.assertEqual(self.G.v(), self.N) algorithm = PrimConnectedMST(self.G) algorithm.run() algorithm.to_tree() self.assertEqual(algorithm.mst.v(), self.N) self.assertEqual(algorithm.mst.e(), self.N - 1) mst_weight_expected = 40 mst_weight = sum(edge.weight for edge in algorithm.mst.iteredges()) self.assertEqual(mst_weight, mst_weight_expected) mst_edges_expected = [ Edge(0, 1, 7), Edge(0, 3, 4), Edge(2, 4, 5), Edge(1, 4, 10), Edge(4, 6, 8), Edge(3, 5, 6) ] for edge in mst_edges_expected: self.assertTrue(algorithm.mst.has_edge(edge)) def test_prim_trivial(self): self.assertEqual(self.G.v(), self.N) algorithm = PrimTrivialMST(self.G) algorithm.run() algorithm.to_tree() self.assertEqual(algorithm.mst.v(), self.N) self.assertEqual(algorithm.mst.e(), self.N - 1) mst_weight_expected = 40 mst_weight = sum(edge.weight for edge in algorithm.mst.iteredges()) self.assertEqual(mst_weight, mst_weight_expected) mst_edges_expected = [ Edge(0, 1, 7), Edge(0, 3, 4), Edge(2, 4, 5), Edge(1, 4, 10), Edge(4, 6, 8), Edge(3, 5, 6) ] for edge in mst_edges_expected: self.assertTrue(algorithm.mst.has_edge(edge)) def tearDown(self): pass
class TestPrimDisconnectedGraph(unittest.TestCase): def setUp(self): # The modified graph (unique weights) from Cormen. self.N = 9 # number of nodes self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [ Edge(0, 1, 4), Edge(0, 7, 8), Edge(1, 7, 11), Edge(1, 2, 12), Edge(7, 8, 7), Edge(8, 2, 2), Edge(8, 6, 6), Edge(7, 6, 1), Edge(3, 5, 14), Edge(3, 4, 9), Edge(5, 4, 10) ] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #print self.G def test_prim(self): self.assertEqual(self.G.v(), self.N) algorithm = PrimMST(self.G) algorithm.run() algorithm.to_tree() self.assertEqual(algorithm.mst.v(), self.N) self.assertEqual(algorithm.mst.e(), self.N - 2) # 2 components mst_weight_expected = 40 mst_weight = sum(edge.weight for edge in algorithm.mst.iteredges()) self.assertEqual(mst_weight, mst_weight_expected) mst_edges_expected = [ Edge(0, 1, 4), Edge(0, 7, 8), Edge(8, 2, 2), Edge(7, 6, 1), Edge(6, 8, 6), Edge(3, 4, 9), Edge(5, 4, 10) ] for edge in mst_edges_expected: self.assertTrue(algorithm.mst.has_edge(edge)) def test_prim_with_edges(self): self.assertEqual(self.G.v(), self.N) algorithm = PrimMSTWithEdges(self.G) algorithm.run() algorithm.to_tree() self.assertEqual(algorithm.mst.v(), self.N) self.assertEqual(algorithm.mst.e(), self.N - 2) # 2 components mst_weight_expected = 40 mst_weight = sum(edge.weight for edge in algorithm.mst.iteredges()) self.assertEqual(mst_weight, mst_weight_expected) mst_edges_expected = [ Edge(0, 1, 4), Edge(0, 7, 8), Edge(8, 2, 2), Edge(7, 6, 1), Edge(6, 8, 6), Edge(3, 4, 9), Edge(5, 4, 10) ] for edge in mst_edges_expected: self.assertTrue(algorithm.mst.has_edge(edge)) def test_prim_matrix(self): self.assertEqual(self.G.v(), self.N) algorithm = PrimMatrixMST(self.G) algorithm.run() algorithm.to_tree() self.assertEqual(algorithm.mst.v(), self.N) self.assertEqual(algorithm.mst.e(), self.N - 2) # 2 components mst_weight_expected = 40 mst_weight = sum(edge.weight for edge in algorithm.mst.iteredges()) self.assertEqual(mst_weight, mst_weight_expected) mst_edges_expected = [ Edge(0, 1, 4), Edge(0, 7, 8), Edge(8, 2, 2), Edge(7, 6, 1), Edge(6, 8, 6), Edge(3, 4, 9), Edge(5, 4, 10) ] for edge in mst_edges_expected: self.assertTrue(algorithm.mst.has_edge(edge)) def test_prim_connected(self): self.assertRaises(ValueError, PrimConnectedMST, self.G) def test_prim_trivial(self): self.assertRaises(ValueError, PrimTrivialMST, self.G) def tearDown(self): pass
class TestGraphUndirected(unittest.TestCase): def setUp(self): self.N = 4 # number of nodes self.G = Graph(self.N) self.nodes = ["A", "B", "C", "D"] self.edges = [ Edge("A", "B", 2), Edge("B", "C", 4), Edge("C", "A", 6), Edge("C", "D", 3), Edge("D", "B", 5) ] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_undirected(self): self.assertFalse(self.G.is_directed()) self.assertEqual(self.G.v(), self.N) self.assertEqual(self.G.e(), 5) self.G.del_node("B") self.assertEqual(self.G.v(), 3) self.assertEqual(self.G.e(), 2) def test_iteredges(self): inedges_B = list(self.G.iterinedges("B")) outedges_B = list(self.G.iteroutedges("B")) #print inedges_B, outedges_B self.assertEqual(len(inedges_B), 3) self.assertEqual(len(outedges_B), 3) def test_iteredges_connected(self): start_edge = next(self.G.iteredges()) A = set([start_edge.source, start_edge.target]) for edge in self.G.iteredges_connected(start_edge): B = set([edge.source, edge.target]) self.assertTrue(len(A & B) > 0) A.update(B) #print ( A ) def test_copy(self): T = self.G.copy() self.assertEqual(T.v(), self.G.v()) self.assertEqual(T.e(), self.G.e()) for node in T.iternodes(): self.assertTrue(self.G.has_node(node)) for edge in T.iteredges(): self.assertTrue(self.G.has_edge(edge)) def test_transpose(self): T = self.G.transpose() self.assertEqual(T.v(), self.G.v()) self.assertEqual(T.e(), self.G.e()) for node in T.iternodes(): self.assertTrue(self.G.has_node(node)) for edge in T.iteredges(): self.assertTrue(self.G.has_edge(~edge)) def test_complement(self): T = self.G.complement() self.assertEqual(T.v(), self.G.v()) self.assertEqual(T.e(), self.N * (self.N - 1) / 2 - self.G.e()) for node in T.iternodes(): self.assertTrue(self.G.has_node(node)) for edge in T.iteredges(): self.assertFalse(self.G.has_edge(edge)) for edge in self.G.iteredges(): self.assertFalse(T.has_edge(edge)) def test_subgraph(self): T = self.G.subgraph(["A", "B", "C"]) self.assertEqual(T.v(), 3) self.assertEqual(T.e(), 3) for edge in T.iteredges(): self.assertTrue(self.G.has_edge(edge)) def test_degree(self): self.assertEqual(self.G.degree("A"), 2) self.assertEqual(self.G.degree("B"), 3) self.assertEqual(self.G.degree("C"), 3) self.assertEqual(self.G.degree("D"), 2) def test_add_graph_undirected(self): T = Graph(self.N) for node in self.nodes: T.add_node(node) T.add_edge(Edge("A", "D", 9)) self.assertEqual(T.v(), self.N) self.assertEqual(T.e(), 1) self.G.add_graph(T) self.assertEqual(self.G.v(), self.N) self.assertEqual(self.G.e(), 6) def test_load_save(self): name1 = "undirected_graph.txt" name2 = "undirected_graph.lgl" name3 = "undirected_graph.ncol" self.G.save(name1) self.G.save_lgl(name2) self.G.save_ncol(name3) T = Graph.load(name1) self.assertEqual(self.G, T) def tearDown(self): pass
class TestIndependentSet(unittest.TestCase): def setUp(self): self.N = 6 self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [ Edge(0, 1), Edge(0, 3), Edge(1, 3), Edge(1, 4), Edge(1, 2), Edge(2, 5), Edge(3, 4), Edge(4, 5) ] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_ll_independent_set1(self): algorithm = LargestLastIndependentSet1(self.G) #algorithm.run() # przypadkiem znajduje najlepsze rozwiazanie algorithm.run(3) # znajduje set([2, 3]) for edge in self.G.iteredges(): self.assertFalse(edge.source in algorithm.independent_set and edge.target in algorithm.independent_set) self.assertEqual(algorithm.cardinality, len(algorithm.independent_set)) #print algorithm.independent_set def test_ll_independent_set2(self): algorithm = LargestLastIndependentSet2(self.G) #algorithm.run() # przypadkiem znajduje najlepsze rozwiazanie algorithm.run(3) # znajduje set([2, 3]) for edge in self.G.iteredges(): self.assertFalse(algorithm.independent_set[edge.source] and algorithm.independent_set[edge.target]) cardinality = sum(1 for node in self.G if algorithm.independent_set[node]) self.assertEqual(algorithm.cardinality, cardinality) #print algorithm.independent_set def test_ll_independent_set3(self): algorithm = LargestLastIndependentSet3(self.G) #algorithm.run() # przypadkiem znajduje najlepsze rozwiazanie algorithm.run(3) # znajduje set([2, 3]) for edge in self.G.iteredges(): self.assertFalse(edge.source in algorithm.independent_set and edge.target in algorithm.independent_set) self.assertEqual(algorithm.cardinality, len(algorithm.independent_set)) #print algorithm.independent_set def test_ll_independent_set4(self): algorithm = LargestLastIndependentSet4(self.G) #algorithm.run() # przypadkiem znajduje najlepsze rozwiazanie algorithm.run(3) # znajduje set([2, 3]) for edge in self.G.iteredges(): self.assertFalse(algorithm.independent_set[edge.source] and algorithm.independent_set[edge.target]) cardinality = sum(1 for node in self.G if algorithm.independent_set[node]) self.assertEqual(algorithm.cardinality, cardinality) #print algorithm.independent_set def test_ll_independent_set5(self): algorithm = LargestLastIndependentSet5(self.G) #algorithm.run() # przypadkiem znajduje najlepsze rozwiazanie algorithm.run(3) # znajduje set([2, 3]) for edge in self.G.iteredges(): self.assertFalse(edge.source in algorithm.independent_set and edge.target in algorithm.independent_set) self.assertEqual(algorithm.cardinality, len(algorithm.independent_set)) #print algorithm.independent_set def test_ll_independent_set6(self): algorithm = LargestLastIndependentSet6(self.G) #algorithm.run() # przypadkiem znajduje najlepsze rozwiazanie algorithm.run(3) # znajduje set([2, 3]) for edge in self.G.iteredges(): self.assertFalse(edge.source in algorithm.independent_set and edge.target in algorithm.independent_set) self.assertEqual(algorithm.cardinality, len(algorithm.independent_set)) #print algorithm.independent_set def test_ll_independent_set7(self): algorithm = LargestLastIndependentSet7(self.G) #algorithm.run() # przypadkiem znajduje najlepsze rozwiazanie algorithm.run(3) # znajduje set([2, 3]) for edge in self.G.iteredges(): self.assertFalse(edge.source in algorithm.independent_set and edge.target in algorithm.independent_set) self.assertEqual(algorithm.cardinality, len(algorithm.independent_set)) #print algorithm.independent_set def test_exceptions(self): self.assertRaises(ValueError, LargestLastIndependentSet1, Graph(5, directed=True)) self.assertRaises(ValueError, LargestLastIndependentSet2, Graph(5, directed=True)) self.assertRaises(ValueError, LargestLastIndependentSet3, Graph(5, directed=True)) self.assertRaises(ValueError, LargestLastIndependentSet4, Graph(5, directed=True)) self.assertRaises(ValueError, LargestLastIndependentSet5, Graph(5, directed=True)) self.assertRaises(ValueError, LargestLastIndependentSet6, Graph(5, directed=True)) self.assertRaises(ValueError, LargestLastIndependentSet7, Graph(5, directed=True)) def tearDown(self): pass
class TestDijkstra2(unittest.TestCase): def setUp(self): self.N = 9 # number of nodes self.G = Graph(self.N, directed=True) self.nodes = range(self.N) self.edges = [ Edge(0, 1, 65), Edge(1, 8, 41), Edge(1, 2, 35), Edge(2, 3, 56), Edge(3, 4, 4), Edge(3, 6, 20), Edge(5, 2, 30), Edge(6, 5, 18), Edge(6, 7, 15), Edge(8, 3, 28) ] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_shortest_path(self): source = 0 target = 7 algorithm = Dijkstra(self.G) algorithm.run(source) distance_expected = { 0: 0, 1: 65, 2: 100, 3: 134, 4: 138, 5: 172, 6: 154, 7: 169, 8: 106 } self.assertEqual(algorithm.distance, distance_expected) parent_expected = { 0: None, 1: 0, 2: 1, 3: 8, 4: 3, 5: 6, 6: 3, 7: 6, 8: 1 } self.assertEqual(algorithm.parent, parent_expected) path_expected = [0, 1, 8, 3, 6, 7] self.assertEqual(algorithm.path(target), path_expected) def test_no_path(self): source = 2 target = 8 algorithm = Dijkstra(self.G) algorithm.run(source) distance_expected = { 0: float("inf"), 1: float("inf"), 2: 0, 3: 56, 4: 60, 5: 94, 6: 76, 7: 91, 8: float("inf") } self.assertEqual(algorithm.distance, distance_expected) parent_expected = { 0: None, 1: None, 2: None, 3: 2, 4: 3, 5: 6, 6: 3, 7: 6, 8: None } self.assertEqual(algorithm.parent, parent_expected) #path_expected = [] #self.assertEqual(algorithm.path(target), path_expected) self.assertRaises(ValueError, algorithm.path, target) def test_no_path_matrix(self): source = 2 target = 8 algorithm = DijkstraMatrix(self.G) algorithm.run(source) distance_expected = { 0: float("inf"), 1: float("inf"), 2: 0, 3: 56, 4: 60, 5: 94, 6: 76, 7: 91, 8: float("inf") } self.assertEqual(algorithm.distance, distance_expected) parent_expected = { 0: None, 1: None, 2: None, 3: 2, 4: 3, 5: 6, 6: 3, 7: 6, 8: None } self.assertEqual(algorithm.parent, parent_expected) #path_expected = [] #self.assertEqual(algorithm.path(target), path_expected) self.assertRaises(ValueError, algorithm.path, target) def test_dijkstra_matrix(self): source = 0 target = 7 algorithm = DijkstraMatrix(self.G) algorithm.run(source) distance_expected = { 0: 0, 1: 65, 2: 100, 3: 134, 4: 138, 5: 172, 6: 154, 7: 169, 8: 106 } self.assertEqual(algorithm.distance, distance_expected) parent_expected = { 0: None, 1: 0, 2: 1, 3: 8, 4: 3, 5: 6, 6: 3, 7: 6, 8: 1 } self.assertEqual(algorithm.parent, parent_expected) path_expected = [0, 1, 8, 3, 6, 7] self.assertEqual(algorithm.path(target), path_expected) def tearDown(self): pass
class TestEdmondsKarpWiki(unittest.TestCase): def setUp(self): self.N = 7 # number of nodes self.G = Graph(self.N, directed=True) self.nodes = range(self.N) self.edges = [ Edge(0, 1, 3), Edge(0, 3, 3), Edge(1, 2, 4), Edge(2, 0, 3), Edge(2, 3, 1), Edge(2, 4, 2), Edge(3, 4, 2), Edge(3, 5, 6), Edge(4, 1, 1), Edge(4, 6, 1), Edge(5, 6, 9) ] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_edmondskarp(self): algorithm = EdmondsKarp(self.G) algorithm.run(0, 6) expected_max_flow = 5 expected_flow = { 0: { 0: 0, 1: 2, 2: 0, 3: 3, 4: 0, 5: 0, 6: 0 }, 1: { 0: -2, 1: 0, 2: 2, 3: 0, 4: 0, 5: 0, 6: 0 }, 2: { 0: 0, 1: -2, 2: 0, 3: 1, 4: 1, 5: 0, 6: 0 }, 3: { 0: -3, 1: 0, 2: -1, 3: 0, 4: 0, 5: 4, 6: 0 }, 4: { 0: 0, 1: 0, 2: -1, 3: 0, 4: 0, 5: 0, 6: 1 }, 5: { 0: 0, 1: 0, 2: 0, 3: -4, 4: 0, 5: 0, 6: 4 }, 6: { 0: 0, 1: 0, 2: 0, 3: 0, 4: -1, 5: -4, 6: 0 } } self.assertEqual(algorithm.max_flow, expected_max_flow) self.assertEqual(algorithm.flow, expected_flow) def test_edmondskarp_sparse(self): algorithm = EdmondsKarpSparse(self.G) algorithm.run(0, 6) expected_max_flow = 5 expected_flow = { 0: { 1: 2, 2: 0, 3: 3 }, 1: { 0: -2, 2: 2, 4: 0 }, 2: { 0: 0, 1: -2, 3: 1, 4: 1 }, 3: { 0: -3, 2: -1, 4: 0, 5: 4 }, 4: { 1: 0, 2: -1, 3: 0, 6: 1 }, 5: { 3: -4, 6: 4 }, 6: { 4: -1, 5: -4 } } self.assertEqual(algorithm.max_flow, expected_max_flow) self.assertEqual(algorithm.flow, expected_flow) def tearDown(self): pass
def test_halin16(self): N = 16 G = Graph(N, False) edges = [ Edge(0, 1), Edge(0, 2), Edge(0, 15), Edge(1, 2), Edge(1, 6), Edge(2, 3), Edge(3, 4), Edge(3, 5), Edge(4, 5), Edge(4, 10), Edge(5, 6), Edge(6, 7), Edge(7, 8), Edge(7, 15), Edge(8, 9), Edge(8, 13), Edge(9, 10), Edge(9, 11), Edge(10, 11), Edge(11, 12), Edge(12, 13), Edge(12, 14), Edge(13, 14), Edge(14, 15) ] for node in range(N): G.add_node(node) for edge in edges: G.add_edge(edge) #print "halin16" algorithm = HalinNodeColoring(G, outer=set( [0, 2, 3, 4, 10, 11, 12, 14, 15])) algorithm.run() #print "halin16 outer", algorithm.outer parent = { 0: 1, 1: None, 2: 1, 3: 5, 4: 5, 5: 6, 6: 1, 7: 6, 8: 7, 9: 8, 10: 9, 11: 9, 12: 13, 13: 8, 14: 13, 15: 7 } self.assertEqual(algorithm.parent, parent) for node in G.iternodes(): self.assertNotEqual(algorithm.color[node], None) for edge in G.iteredges(): self.assertNotEqual(algorithm.color[edge.source], algorithm.color[edge.target]) all_colors = set(algorithm.color[node] for node in G.iternodes()) self.assertEqual(len(all_colors), 3)
# Euclidean TSP. # Nodes are points in a unit square. # Weights are distances. V = 8 # number of nodes E = V * (V - 1) // 2 # number of edges G = Graph(n=V, directed=False) for i in range(V): G.add_node((random.random(), random.random())) for source in G.iternodes(): for target in G.iternodes(): if source < target: x0, y0 = source x1, y1 = target weight = math.hypot(x1 - x0, y1 - y0) G.add_edge(Edge(source, target, weight)) #G.show() print("Calculate parameters ...") print("Nodes: {} {}".format(G.v(), V)) print("Edges: {} {}".format(G.e(), E)) print("Directed: {}".format(G.is_directed())) print("Delta: {}".format(max(G.degree(node) for node in G.iternodes()))) print("Testing BruteForceTSPWithGraph ...") t1 = timeit.Timer(lambda: BruteForceTSPWithGraph(G).run()) print("{} {} {}".format(V, E, t1.timeit(1))) # single run print("Testing NearestNeighborTSPWithGraph ...") t1 = timeit.Timer(lambda: NearestNeighborTSPWithGraph(G).run()) print("{} {} {}".format(V, E, t1.timeit(1))) # single run
class TestAllPairsShortestPaths(unittest.TestCase): def setUp(self): self.N = 5 # number of nodes self.G = Graph(self.N, directed=True) self.nodes = range(self.N) self.edges = [ Edge(0, 2, 6), Edge(0, 3, 3), Edge(1, 0, 3), Edge(2, 3, 2), Edge(3, 1, 1), Edge(3, 2, 1), Edge(4, 1, 4), Edge(4, 3, 2) ] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_slow(self): algorithm = SlowAllPairs(self.G) algorithm.run() expected_distance = { 0: { 0: 0, 1: 4, 2: 4, 3: 3, 4: float("inf") }, 1: { 0: 3, 1: 0, 2: 7, 3: 6, 4: float("inf") }, 2: { 0: 6, 1: 3, 2: 0, 3: 2, 4: float("inf") }, 3: { 0: 4, 1: 1, 2: 1, 3: 0, 4: float("inf") }, 4: { 0: 6, 1: 3, 2: 3, 3: 2, 4: 0 } } self.assertEqual(algorithm.distance, expected_distance) def test_slow_edges(self): algorithm = SlowAllPairsEdges(self.G) algorithm.run() expected_distance = { 0: { 0: 0, 1: 4, 2: 4, 3: 3, 4: float("inf") }, 1: { 0: 3, 1: 0, 2: 7, 3: 6, 4: float("inf") }, 2: { 0: 6, 1: 3, 2: 0, 3: 2, 4: float("inf") }, 3: { 0: 4, 1: 1, 2: 1, 3: 0, 4: float("inf") }, 4: { 0: 6, 1: 3, 2: 3, 3: 2, 4: 0 } } self.assertEqual(algorithm.distance, expected_distance) def test_faster(self): algorithm = FasterAllPairs(self.G) algorithm.run() expected_distance = { 0: { 0: 0, 1: 4, 2: 4, 3: 3, 4: float("inf") }, 1: { 0: 3, 1: 0, 2: 7, 3: 6, 4: float("inf") }, 2: { 0: 6, 1: 3, 2: 0, 3: 2, 4: float("inf") }, 3: { 0: 4, 1: 1, 2: 1, 3: 0, 4: float("inf") }, 4: { 0: 6, 1: 3, 2: 3, 3: 2, 4: 0 } } self.assertEqual(algorithm.distance, expected_distance) def test_slow_with_paths(self): algorithm = SlowAllPairsWithPaths(self.G) algorithm.run() expected_distance = { 0: { 0: 0, 1: 4, 2: 4, 3: 3, 4: float("inf") }, 1: { 0: 3, 1: 0, 2: 7, 3: 6, 4: float("inf") }, 2: { 0: 6, 1: 3, 2: 0, 3: 2, 4: float("inf") }, 3: { 0: 4, 1: 1, 2: 1, 3: 0, 4: float("inf") }, 4: { 0: 6, 1: 3, 2: 3, 3: 2, 4: 0 } } expected_parent = { 0: { 0: None, 2: 3, 1: 3, 4: None, 3: 0 }, 1: { 0: 1, 2: 3, 1: None, 4: None, 3: 0 }, 2: { 0: 1, 2: None, 1: 3, 4: None, 3: 2 }, 3: { 0: 1, 2: 3, 1: 3, 4: None, 3: None }, 4: { 0: 1, 2: 3, 1: 3, 4: None, 3: 4 } } self.assertEqual(algorithm.distance, expected_distance) self.assertEqual(algorithm.parent, expected_parent) self.assertEqual(algorithm.path(0, 1), [0, 3, 1]) def test_negative_cycle(self): self.G.add_edge(Edge(1, 3, -2)) algorithm = FasterAllPairs(self.G) self.assertRaises(ValueError, algorithm.run) algorithm = SlowAllPairs(self.G) self.assertRaises(ValueError, algorithm.run) algorithm = SlowAllPairsEdges(self.G) self.assertRaises(ValueError, algorithm.run) algorithm = SlowAllPairsWithPaths(self.G) self.assertRaises(ValueError, algorithm.run)
class TestMatching(unittest.TestCase): def setUp(self): # Wilson, ex. 25.1, bipartite graph # 0 : 4 5 6 # 1 : 3 5 # 2 : 3 4 # ... self.N = 7 self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [ Edge(0, 4), Edge(0, 5), Edge(0, 6), Edge(1, 3), Edge(1, 5), Edge(2, 3), Edge(2, 4) ] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_matching_fordfulkerson_set(self): algorithm = MatchingFordFulkersonSet(self.G) algorithm.run() # 5 solutions expected_cardinality = 3 expected_mate1 = {0: 5, 5: 0, 1: 3, 3: 1, 2: 4, 4: 2, 6: None} expected_mate2 = {0: 4, 4: 0, 1: 5, 5: 1, 2: 3, 3: 2, 6: None} expected_mate3 = {0: 6, 6: 0, 1: 3, 3: 1, 2: 4, 4: 2, 5: None} expected_mate4 = {0: 6, 6: 0, 1: 5, 5: 1, 2: 3, 3: 2, 4: None} expected_mate5 = {0: 6, 6: 0, 1: 5, 5: 1, 2: 4, 4: 2, 3: None} self.assertEqual(algorithm.cardinality, expected_cardinality) self.assertEqual(algorithm.mate, expected_mate5) def test_matching_fordfulkerson_list(self): algorithm = MatchingFordFulkersonList(self.G) algorithm.run() # 5 solutions expected_cardinality = 3 expected_mate1 = {0: 5, 5: 0, 1: 3, 3: 1, 2: 4, 4: 2, 6: None} expected_mate2 = {0: 4, 4: 0, 1: 5, 5: 1, 2: 3, 3: 2, 6: None} expected_mate3 = {0: 6, 6: 0, 1: 3, 3: 1, 2: 4, 4: 2, 5: None} expected_mate4 = {0: 6, 6: 0, 1: 5, 5: 1, 2: 3, 3: 2, 4: None} expected_mate5 = {0: 6, 6: 0, 1: 5, 5: 1, 2: 4, 4: 2, 3: None} self.assertEqual(algorithm.cardinality, expected_cardinality) self.assertEqual(algorithm.mate, expected_mate5) def test_matching_fordfulkerson_color(self): algorithm = MatchingFordFulkersonColor(self.G) algorithm.run() # 5 solutions expected_cardinality = 3 expected_mate1 = {0: 5, 5: 0, 1: 3, 3: 1, 2: 4, 4: 2, 6: None} expected_mate2 = {0: 4, 4: 0, 1: 5, 5: 1, 2: 3, 3: 2, 6: None} expected_mate3 = {0: 6, 6: 0, 1: 3, 3: 1, 2: 4, 4: 2, 5: None} expected_mate4 = {0: 6, 6: 0, 1: 5, 5: 1, 2: 3, 3: 2, 4: None} expected_mate5 = {0: 6, 6: 0, 1: 5, 5: 1, 2: 4, 4: 2, 3: None} self.assertEqual(algorithm.cardinality, expected_cardinality) self.assertEqual(algorithm.mate, expected_mate5) def test_exceptions(self): self.assertRaises(ValueError, MatchingFordFulkersonSet, Graph(2, directed=True)) self.assertRaises(ValueError, MatchingFordFulkersonList, Graph(2, directed=True)) self.assertRaises(ValueError, MatchingFordFulkersonColor, Graph(2, directed=True)) def tearDown(self): pass
class TestMatching(unittest.TestCase): def setUp(self): # Wilson, ex. 25.1, bipartite graph # 0 : 4 5 6 # 1 : 3 5 # 2 : 3 4 # ... self.N = 7 self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [ Edge(0, 4), Edge(0, 5), Edge(0, 6), Edge(1, 3), Edge(1, 5), Edge(2, 3), Edge(2, 4) ] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_maximal_matching(self): algorithm = MaximalMatching(self.G) algorithm.run() # 5 solutions expected_cardinality = 2 # max 3 expected_mate = {0: 4, 4: 0, 1: 3, 3: 1, 2: None, 5: None, 6: None} self.assertEqual(algorithm.cardinality, expected_cardinality) self.assertEqual(algorithm.mate, expected_mate) # Is it matching? for source in algorithm.mate: if algorithm.mate[source] is not None: target = algorithm.mate[source] self.assertEqual(algorithm.mate[target], source) def test_maximal_matching_with_edges(self): algorithm = MaximalMatchingWithEdges(self.G) algorithm.run() # 5 solutions expected_cardinality = 2 # max 3 expected_mate = { 0: Edge(0, 4), 1: Edge(1, 3), 2: None, 3: Edge(3, 1), 4: Edge(4, 0), 5: None, 6: None } self.assertEqual(algorithm.cardinality, expected_cardinality) self.assertEqual(algorithm.mate, expected_mate) # Is it matching? for source in algorithm.mate: if algorithm.mate[source] is not None: edge = algorithm.mate[source] self.assertEqual(algorithm.mate[edge.target], ~edge) def tearDown(self): pass
class TestMaximumFlow3(unittest.TestCase): def setUp(self): self.N = 6 # number of nodes self.G = Graph(self.N, directed=True) self.nodes = range(self.N) self.edges = [ Edge(0, 1, 10), Edge(0, 2, 10), Edge(1, 2, 2), Edge(1, 3, 4), Edge(1, 4, 8), Edge(2, 4, 9), Edge(4, 3, 6), Edge(4, 5, 10), Edge(3, 5, 10) ] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_ford_fulkerson(self): algorithm = FordFulkerson(self.G) algorithm.run(0, 5) expected_max_flow = 19 expected_flow = { 0: { 0: 0, 1: 10, 2: 9, 3: 0, 4: 0, 5: 0 }, 1: { 0: -10, 1: 0, 2: 0, 3: 4, 4: 6, 5: 0 }, 2: { 0: -9, 1: 0, 2: 0, 3: 0, 4: 9, 5: 0 }, 3: { 0: 0, 1: -4, 2: 0, 3: 0, 4: -5, 5: 9 }, 4: { 0: 0, 1: -6, 2: -9, 3: 5, 4: 0, 5: 10 }, 5: { 0: 0, 1: 0, 2: 0, 3: -9, 4: -10, 5: 0 } } self.assertEqual(algorithm.max_flow, expected_max_flow) self.assertEqual(algorithm.flow, expected_flow) def test_ford_fulkerson_sparse(self): algorithm = FordFulkersonSparse(self.G) algorithm.run(0, 5) expected_max_flow = 19 expected_flow = { 0: { 1: 10, 2: 9 }, 1: { 0: -10, 2: 0, 3: 4, 4: 6 }, 2: { 0: -9, 1: 0, 4: 9 }, 3: { 1: -4, 4: -5, 5: 9 }, 4: { 1: -6, 2: -9, 3: 5, 5: 10 }, 5: { 3: -9, 4: -10 } } self.assertEqual(algorithm.max_flow, expected_max_flow) self.assertEqual(algorithm.flow, expected_flow) def test_ford_fulkerson_with_edges(self): algorithm = FordFulkersonWithEdges(self.G) algorithm.run(0, 5) expected_max_flow = 19 expected_flow = { Edge(0, 1, 10): 10, Edge(0, 2, 10): 9, Edge(1, 0, 0): -10, Edge(1, 2, 2): 0, Edge(1, 3, 4): 4, Edge(1, 4, 8): 6, Edge(2, 0, 0): -9, Edge(2, 1, 0): 0, Edge(2, 4, 9): 9, Edge(3, 1, 0): -4, Edge(3, 4, 0): -5, Edge(3, 5, 10): 9, Edge(4, 1, 0): -6, Edge(4, 2, 0): -9, Edge(4, 3, 6): 5, Edge(4, 5, 10): 10, Edge(5, 3, 0): -9, Edge(5, 4, 0): -10 } self.assertEqual(algorithm.max_flow, expected_max_flow) self.assertEqual(algorithm.flow, expected_flow) def test_ford_fulkerson_recursive(self): algorithm = FordFulkersonRecursive(self.G) algorithm.run(0, 5) expected_max_flow = 19 expected_flow = { 0: { 0: 0, 1: 10, 2: 9, 3: 0, 4: 0, 5: 0 }, 1: { 0: -10, 1: 0, 2: 0, 3: 4, 4: 6, 5: 0 }, 2: { 0: -9, 1: 0, 2: 0, 3: 0, 4: 9, 5: 0 }, 3: { 0: 0, 1: -4, 2: 0, 3: 0, 4: -6, 5: 10 }, 4: { 0: 0, 1: -6, 2: -9, 3: 6, 4: 0, 5: 9 }, 5: { 0: 0, 1: 0, 2: 0, 3: -10, 4: -9, 5: 0 } } self.assertEqual(algorithm.max_flow, expected_max_flow) self.assertEqual(algorithm.flow, expected_flow) def test_ford_fulkerson_recursive_with_edges(self): algorithm = FordFulkersonRecursiveWithEdges(self.G) algorithm.run(0, 5) expected_max_flow = 19 expected_flow = { Edge(0, 1, 10): 10, Edge(0, 2, 10): 9, Edge(1, 0, 0): -10, Edge(1, 2, 2): 0, Edge(1, 3, 4): 4, Edge(1, 4, 8): 6, Edge(2, 0, 0): -9, Edge(2, 1, 0): 0, Edge(2, 4, 9): 9, Edge(3, 1, 0): -4, Edge(3, 4, 0): -6, Edge(3, 5, 10): 10, Edge(4, 1, 0): -6, Edge(4, 2, 0): -9, Edge(4, 3, 6): 6, Edge(4, 5, 10): 9, Edge(5, 3, 0): -10, Edge(5, 4, 0): -9 } self.assertEqual(algorithm.max_flow, expected_max_flow) self.assertEqual(algorithm.flow, expected_flow) def test_exceptions(self): self.assertRaises(ValueError, FordFulkerson, Graph()) self.assertRaises(ValueError, FordFulkersonSparse, Graph()) self.assertRaises(ValueError, FordFulkersonWithEdges, Graph()) self.assertRaises(ValueError, FordFulkersonRecursive, Graph()) self.assertRaises(ValueError, lambda: FordFulkerson(self.G).run(0, 0)) self.assertRaises(ValueError, lambda: FordFulkersonSparse(self.G).run(0, 0)) self.assertRaises(ValueError, lambda: FordFulkersonWithEdges(self.G).run(0, 0)) self.assertRaises(ValueError, lambda: FordFulkersonRecursive(self.G).run(0, 0)) self.assertRaises( ValueError, lambda: FordFulkersonRecursiveWithEdges(self.G).run(0, 0))
class TestEdmondsKarp(unittest.TestCase): def setUp(self): self.N = 4 # number of nodes self.G = Graph(self.N, directed=True) self.nodes = range(self.N) self.edges = [ Edge(0, 1, 10), Edge(0, 2, 10), Edge(1, 2, 1), Edge(1, 3, 10), Edge(2, 3, 10) ] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_edmondskarp(self): algorithm = EdmondsKarp(self.G) algorithm.run(0, 3) expected_max_flow = 20 expected_flow = { 0: { 0: 0, 2: 10, 1: 10, 3: 0 }, 1: { 0: -10, 2: 0, 1: 0, 3: 10 }, 2: { 0: -10, 2: 0, 1: 0, 3: 10 }, 3: { 0: 0, 2: -10, 1: -10, 3: 0 } } self.assertEqual(algorithm.max_flow, expected_max_flow) self.assertEqual(algorithm.flow, expected_flow) def test_edmondskarp_sparse(self): algorithm = EdmondsKarpSparse(self.G) algorithm.run(0, 3) expected_max_flow = 20 expected_flow = { 0: { 1: 10, 2: 10 }, 1: { 0: -10, 2: 0, 3: 10 }, 2: { 0: -10, 1: 0, 3: 10 }, 3: { 1: -10, 2: -10 } } self.assertEqual(algorithm.max_flow, expected_max_flow) self.assertEqual(algorithm.flow, expected_flow)
class TestGraphDirected(unittest.TestCase): def setUp(self): self.N = 4 # number of nodes self.G = Graph(self.N, directed=True) self.nodes = ["A", "B", "C", "D"] self.edges = [ Edge("A", "B", 2), Edge("B", "C", 4), Edge("C", "A", 6), Edge("C", "D", 3), Edge("D", "B", 5) ] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_directed(self): self.assertTrue(self.G.is_directed()) self.assertEqual(self.G.v(), self.N) self.assertEqual(self.G.e(), 5) self.G.del_node("B") self.assertEqual(self.G.v(), 3) self.assertEqual(self.G.e(), 2) def test_cmp(self): T = Graph(self.N) self.assertFalse(T == self.G, "directed and undirected graphs") T = Graph(self.N, directed=True) for node in ["A", "B", "C", "X"]: T.add_node(node) self.assertFalse(T == self.G, "nodes are different") T.del_node("X") self.assertFalse(T == self.G, "numbers of nodes are different") T.add_node("D") T.add_edge(Edge("A", "B", 2)) T.add_edge(Edge("B", "C", 4)) T.add_edge(Edge("C", "A", 6)) T.add_edge(Edge("C", "D", 3)) self.assertFalse(T == self.G, "edge numbers are different") T.add_edge(Edge("D", "B", 7)) self.assertFalse(T == self.G, "edge weights are different") T.del_edge(Edge("D", "B", 7)) T.add_edge(Edge("B", "D", 5)) self.assertFalse(T == self.G, "edge directions are different") T.del_edge(Edge("B", "D", 5)) T.add_edge(Edge("D", "B", 5)) self.assertTrue(T == self.G, "graphs are the same") def test_iteredges(self): inedges_B = list(self.G.iterinedges("B")) outedges_B = list(self.G.iteroutedges("B")) #print inedges_B, outedges_B self.assertEqual(len(inedges_B), 2) self.assertEqual(len(outedges_B), 1) def test_copy(self): T = self.G.copy() self.assertEqual(T.v(), self.G.v()) self.assertEqual(T.e(), self.G.e()) for node in T.iternodes(): self.assertTrue(self.G.has_node(node)) for edge in T.iteredges(): self.assertTrue(self.G.has_edge(edge)) def test_transpose(self): T = self.G.transpose() self.assertEqual(T.v(), self.G.v()) self.assertEqual(T.e(), self.G.e()) for node in T.iternodes(): self.assertTrue(self.G.has_node(node)) for edge in T.iteredges(): self.assertTrue(self.G.has_edge(~edge)) def test_complement(self): T = self.G.complement() self.assertEqual(T.v(), self.G.v()) self.assertEqual(T.e(), self.N * (self.N - 1) - self.G.e()) for node in T.iternodes(): self.assertTrue(self.G.has_node(node)) for edge in T.iteredges(): self.assertFalse(self.G.has_edge(edge)) for edge in self.G.iteredges(): self.assertFalse(T.has_edge(edge)) def test_subgraph(self): T = self.G.subgraph(["A", "B", "C"]) self.assertEqual(T.v(), 3) self.assertEqual(T.e(), 3) for edge in T.iteredges(): self.assertTrue(self.G.has_edge(edge)) def test_add_graph_directed(self): T = Graph(self.N, directed=True) for node in self.nodes: T.add_node(node) T.add_edge(Edge("A", "D", 9)) self.assertEqual(T.v(), self.N) self.assertEqual(T.e(), 1) self.G.add_graph(T) self.assertEqual(self.G.v(), self.N) self.assertEqual(self.G.e(), 6) def test_degree(self): self.assertEqual(self.G.indegree("A"), 1) self.assertEqual(self.G.indegree("B"), 2) self.assertEqual(self.G.indegree("C"), 1) self.assertEqual(self.G.indegree("D"), 1) self.assertEqual(self.G.outdegree("A"), 1) self.assertEqual(self.G.outdegree("B"), 1) self.assertEqual(self.G.outdegree("C"), 2) self.assertEqual(self.G.outdegree("D"), 1) def test_exceptions(self): self.assertRaises(ValueError, self.G.add_edge, Edge("A", "A", 1)) self.assertRaises(ValueError, self.G.add_edge, Edge("A", "B", 2)) self.assertRaises(ValueError, self.G.degree, "A") def tearDown(self): pass
class TestTSP(unittest.TestCase): def setUp(self): self.N = 4 self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [ Edge(0, 1, 20), Edge(0, 3, 35), Edge(0, 2, 42), Edge(1, 2, 30), Edge(1, 3, 34), Edge(2, 3, 12) ] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) self.best_weight = 97 #self.G.show() def test_brute_force_with_edges(self): algorithm = BruteForceTSPWithEdges(self.G) algorithm.run(2) # Cycles for different starting nodes. expected_hamiltonian_cycle0 = [ Edge(0, 1, 20), Edge(1, 2, 30), Edge(2, 3, 12), Edge(3, 0, 35) ] expected_hamiltonian_cycle1 = [ Edge(1, 0, 20), Edge(0, 3, 35), Edge(3, 2, 12), Edge(2, 1, 30) ] expected_hamiltonian_cycle2 = [ Edge(2, 1, 30), Edge(1, 0, 20), Edge(0, 3, 35), Edge(3, 2, 12) ] expected_hamiltonian_cycle3 = [ Edge(3, 0, 35), Edge(0, 1, 20), Edge(1, 2, 30), Edge(2, 3, 12) ] expected_hamiltonian_cycle = expected_hamiltonian_cycle2 self.assertEqual(algorithm.hamiltonian_cycle, expected_hamiltonian_cycle) weight = sum(edge.weight for edge in algorithm.hamiltonian_cycle) self.assertEqual(weight, self.best_weight) def test_brute_force_with_cycle_graph(self): algorithm = BruteForceTSPWithGraph(self.G) algorithm.run(2) # Hamiltonian cycle as a graph. weight = sum(edge.weight for edge in algorithm.hamiltonian_cycle.iteredges()) self.assertEqual(weight, self.best_weight) #algorithm.hamiltonian_cycle.show() self.assertEqual(algorithm.hamiltonian_cycle.e(), algorithm.hamiltonian_cycle.v()) for node in algorithm.hamiltonian_cycle.iternodes(): self.assertEqual(algorithm.hamiltonian_cycle.degree(node), 2) def test_exceptions(self): self.assertRaises(ValueError, BruteForceTSPWithEdges, Graph(5, True)) self.assertRaises(ValueError, BruteForceTSPWithGraph, Graph(5, True)) def tearDown(self): pass
class TestSPMatching(unittest.TestCase): def setUp(self): self.N = 5 self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [ Edge(0, 1), Edge(0, 2), Edge(1, 2), Edge(1, 3), Edge(1, 4) ] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() node1 = Node(0, 1, "edge") node2 = Node(0, 2, "edge") node3 = Node(2, 1, "edge") node4 = Node(1, 3, "edge") node5 = Node(1, 4, "edge") node6 = Node(0, 1, "series", node2, node3) node7 = Node(0, 1, "parallel", node1, node6) node8 = Node(0, 1, "jackknife", node7, node4) node9 = Node(0, 1, "jackknife", node8, node5) self.root = node9 def test_spgraph_mate(self): algorithm = SPGraphMatching(self.G, self.root) algorithm.run() expected1 = set([Edge(0, 2), Edge(1, 3)]) expected2 = set([Edge(0, 2), Edge(1, 4)]) #print "mate_set", algorithm.mate_set #print "mate", algorithm.mate self.assertEqual(algorithm.cardinality, len(expected1)) self.assertEqual(algorithm.mate_set, expected1) #self.assertEqual(algorithm.mate_set, expected2) # Test poprawnosci skojarzenia na krawedziach. # Sprawdzam, czy konce sie nie powtarzaja. S = set() for edge in algorithm.mate_set: S.add(edge.source) S.add(edge.target) self.assertEqual(len(S), 2 * len(algorithm.mate_set)) def test_sptree_mate(self): algorithm = SPTreeMatching(self.root) algorithm.run() expected1 = set([Edge(0, 2), Edge(1, 3)]) expected2 = set([Edge(0, 2), Edge(1, 4)]) #print "mate_set", algorithm.mate_set #print "mate", algorithm.mate self.assertEqual(algorithm.cardinality, len(expected1)) self.assertEqual(algorithm.mate_set, expected1) #self.assertEqual(algorithm.mate_set, expected2) # Test poprawnosci skojarzenia na krawedziach. # Sprawdzam, czy konce sie nie powtarzaja. S = set() for edge in algorithm.mate_set: S.add(edge.source) S.add(edge.target) self.assertEqual(len(S), 2 * len(algorithm.mate_set)) def tearDown(self): pass
class TestIndependentSet(unittest.TestCase): def setUp(self): pass def test_spgraph_independent_set_small(self): self.prepareSmallGraph() algorithm = SPGraphIndependentSet(self.G, self.root) algorithm.run() expected1 = set([0, 3, 4]) expected2 = set([2, 3, 4]) self.assertEqual(algorithm.cardinality, len(expected1)) self.assertTrue(algorithm.independent_set == expected1 or algorithm.independent_set == expected2) def test_sptree_independent_set_small(self): self.prepareSmallGraph() algorithm = SPTreeIndependentSet(self.root) algorithm.run() expected1 = set([0, 3, 4]) expected2 = set([2, 3, 4]) self.assertEqual(algorithm.cardinality, len(expected1)) self.assertTrue(algorithm.independent_set == expected1 or algorithm.independent_set == expected2) def test_spgraph_independent_set_small2(self): self.prepareSmallGraph2() algorithm = SPGraphIndependentSet(self.G, self.root) algorithm.run() expected1 = set([0, 2, 3, 4]) self.assertEqual(algorithm.cardinality, len(expected1)) self.assertTrue(algorithm.independent_set == expected1) def test_sptree_independent_set_small2(self): self.prepareSmallGraph2() algorithm = SPTreeIndependentSet(self.root) algorithm.run() expected1 = set([0, 2, 3, 4]) self.assertEqual(algorithm.cardinality, len(expected1)) self.assertTrue(algorithm.independent_set == expected1) def test_spgraph_independent_set_medium(self): self.prepareMediumGraph() algorithm = SPGraphIndependentSet(self.G, self.root) algorithm.run() expected = set([1, 2, 3, 4, 7]) self.assertEqual(algorithm.cardinality, len(expected)) self.assertEqual(algorithm.independent_set, expected) def test_sptree_independent_set_medium(self): self.prepareMediumGraph() algorithm = SPTreeIndependentSet(self.root) algorithm.run() expected = set([1, 2, 3, 4, 7]) self.assertEqual(algorithm.cardinality, len(expected)) self.assertEqual(algorithm.independent_set, expected) def tearDown(self): pass def prepareSmallGraph(self): # 0 s=0, t=1 # | \ # 1---2 # | \ # 3 4 self.N = 5 self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [Edge(0, 1), Edge(0, 2), Edge(1, 2), Edge(1, 3), Edge(1, 4)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) # self.G.show() node1 = Node(0, 1, "edge") node2 = Node(0, 2, "edge") node3 = Node(2, 1, "edge") node4 = Node(1, 3, "edge") node5 = Node(1, 4, "edge") node6 = Node(0, 1, "series", node2, node3) node7 = Node(0, 1, "parallel", node1, node6) node8 = Node(0, 1, "jackknife", node7, node4) node9 = Node(0, 1, "jackknife", node8, node5) self.root = node9 def prepareSmallGraph2(self): # 0 s=0, t=1 # | # 3--1--2 # | # 4 self.N = 5 self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [Edge(0, 1), Edge(1, 2), Edge(1, 3), Edge(1, 4)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) # self.G.show() node1 = Node(0, 1, "edge") node2 = Node(1, 2, "edge") node3 = Node(1, 3, "edge") node4 = Node(1, 4, "edge") node5 = Node(0, 1, "jackknife", node1, node2) node6 = Node(0, 1, "jackknife", node5, node3) node7 = Node(0, 1, "jackknife", node6, node4) self.root = node7 def prepareMediumGraph(self): # 0_____ s=0, t=8 # | \ \ \ # 1 2 3 4 | # \ | |/ / # 5 6 / # \/ / # 7 / # | / # 8 self.N = 9 self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [Edge(0, 2), Edge(0, 3), Edge(0, 4), Edge(0, 8), Edge(1, 5), Edge(2, 5), Edge(3, 6), Edge(4, 6), Edge(5, 7), Edge(6, 7), Edge(7, 8)] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) # self.G.show() node1 = Node(0, 2, "edge") node2 = Node(0, 3, "edge") node3 = Node(0, 4, "edge") node4 = Node(0, 8, "edge") node5 = Node(5, 1, "edge") node6 = Node(2, 5, "edge") node7 = Node(3, 6, "edge") node8 = Node(4, 6, "edge") node9 = Node(5, 7, "edge") node10 = Node(6, 7, "edge") node11 = Node(7, 8, "edge") node12 = Node(0, 5, "series", node1, node6) node13 = Node(0, 6, "series", node2, node7) node14 = Node(0, 6, "series", node3, node8) node15 = Node(0, 6, "parallel", node13, node14) node16 = Node(0, 5, "jackknife", node12, node5) node17 = Node(0, 7, "series", node15, node10) node18 = Node(0, 7, "series", node16, node9) node19 = Node(0, 7, "parallel", node17, node18) node20 = Node(0, 8, "series", node19, node11) node21 = Node(0, 8, "parallel", node20, node4) self.root = node21
class TestDijkstra(unittest.TestCase): def setUp(self): self.N = 4 # number of nodes self.G = Graph(self.N, directed=True) self.nodes = range(self.N) self.edges = [ Edge(0, 1, 1), Edge(0, 2, 5), Edge(1, 2, 1), Edge(1, 3, 3), Edge(2, 3, 1) ] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #self.G.show() def test_shortest_path(self): print("Testing Dijkstra") source = 0 target = 3 algorithm = Dijkstra(self.G) algorithm.run(source) distance_expected = {0: 0, 1: 1, 2: 2, 3: 3} self.assertEqual(algorithm.distance, distance_expected) parent_expected = {0: None, 2: 1, 1: 0, 3: 2} self.assertEqual(algorithm.parent, parent_expected) path_expected = [0, 1, 2, 3] self.assertEqual(algorithm.path(target), path_expected) def test_dijkstra_matrix(self): print("Testing Dijkstra matrix") source = 0 target = 3 algorithm = DijkstraMatrix(self.G) algorithm.run(source) distance_expected = {0: 0, 1: 1, 2: 2, 3: 3} self.assertEqual(algorithm.distance, distance_expected) parent_expected = {0: None, 2: 1, 1: 0, 3: 2} self.assertEqual(algorithm.parent, parent_expected) path_expected = [0, 1, 2, 3] self.assertEqual(algorithm.path(target), path_expected) def test_dijkstra_for_path_not_found(self): print("Testing Matrix 2nd time") self.N = 8 # number of nodes self.G = Graph(self.N, directed=True) self.nodes = range(self.N) self.edges = [ Edge(0, 1, 65), Edge(1, 8, 41), Edge(1, 2, 35), Edge(2, 3, 56), Edge(3, 4, 4), Edge(3, 6, 20), Edge(5, 2, 30), Edge(6, 5, 18), Edge(6, 7, 15), Edge(8, 3, 28) ] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) # self.G.show() algorithm = Dijkstra(self.G) source = 0 algorithm.run(source) target = 7 path_expected = [0, 1, 8, 3, 6, 7] distance_expected = 169 self.assertEqual(path_expected, algorithm.path(target)) self.assertEqual(distance_expected, algorithm.distance[target]) algorithm2 = DijkstraMatrix(self.G) algorithm2.run(source) self.assertEqual(path_expected, algorithm.path(target)) self.assertEqual(distance_expected, algorithm.distance[target]) source = 2 target = 8 algorithm.run(source) try: algorithm.path(target) except: pass else: self.fail("Path exception was not raised!") algorithm2.run(source) try: algorithm2.path(target) except: pass else: self.fail("Path exception was not raised!") def tearDown(self): pass
class TestBFS(unittest.TestCase): def setUp(self): # The graph from Cormen p.607 self.N = 8 # number of nodes self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [ Edge(0, 4, 2), Edge(0, 1, 3), Edge(1, 5, 4), Edge(5, 2, 5), Edge(5, 6, 6), Edge(2, 6, 7), Edge(2, 3, 8), Edge(6, 3, 9), Edge(6, 7, 10), Edge(3, 7, 11) ] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #print self.G #self.G.show() def test_bfs(self): self.assertEqual(self.G.v(), self.N) pre_order = [] post_order = [] algorithm = BFSWithQueue(self.G) algorithm.run(1, pre_action=lambda node: pre_order.append(node), post_action=lambda node: post_order.append(node)) order_expected = [1, 0, 5, 4, 2, 6, 3, 7] self.assertEqual(pre_order, order_expected) self.assertEqual(post_order, order_expected) distance_expected = {0: 1, 1: 0, 2: 2, 3: 3, 4: 2, 5: 1, 6: 2, 7: 3} self.assertEqual(algorithm.distance, distance_expected) parent_expected = {0: 1, 1: None, 2: 5, 3: 2, 4: 0, 5: 1, 6: 5, 7: 6} self.assertEqual(algorithm.parent, parent_expected) self.assertEqual(algorithm.path(1, 7), [1, 5, 6, 7]) self.assertEqual(algorithm.path(1, 4), [1, 0, 4]) self.assertRaises(ValueError, algorithm.path, 4, 7) #algorithm.dag.show() self.assertEqual(algorithm.dag.v(), self.N) self.assertEqual(algorithm.dag.e(), self.N - 1) self.assertTrue(algorithm.dag.is_directed()) for edge in algorithm.dag.iteredges(): self.assertTrue(self.G.has_edge(edge)) self.assertEqual(edge.weight, self.G.weight(edge)) def test_simple_bfs(self): self.assertEqual(self.G.v(), self.N) pre_order = [] post_order = [] algorithm = SimpleBFS(self.G) algorithm.run(1, pre_action=lambda node: pre_order.append(node), post_action=lambda node: post_order.append(node)) order_expected = [1, 0, 5, 4, 2, 6, 3, 7] self.assertEqual(pre_order, order_expected) self.assertEqual(post_order, order_expected) parent_expected = {0: 1, 1: None, 2: 5, 3: 2, 4: 0, 5: 1, 6: 5, 7: 6} self.assertEqual(algorithm.parent, parent_expected) self.assertEqual(algorithm.path(1, 7), [1, 5, 6, 7]) self.assertEqual(algorithm.path(1, 4), [1, 0, 4]) self.assertRaises(ValueError, algorithm.path, 4, 7) #algorithm.dag.show() self.assertEqual(algorithm.dag.v(), self.N) self.assertEqual(algorithm.dag.e(), self.N - 1) self.assertTrue(algorithm.dag.is_directed()) for edge in algorithm.dag.iteredges(): self.assertTrue(self.G.has_edge(edge)) self.assertEqual(edge.weight, self.G.weight(edge)) def tearDown(self): pass
class TestTreePlot(unittest.TestCase): def setUp(self): self.N = 7 # number of nodes self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [ Edge(0, 1), Edge(1, 2), Edge(1, 4), Edge(3, 4), Edge(4, 5), Edge(5, 6) ] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) def test_tree_plot(self): self.assertEqual(self.G.e(), self.N - 1) algorithm = TreePlot(self.G) algorithm.run() self.assertEqual(len(algorithm.point_dict), self.N) #print algorithm.point_dict def test_tree_plot_radius_angle(self): self.assertEqual(self.G.e(), self.N - 1) algorithm = TreePlotRadiusAngle(self.G) algorithm.run() self.assertEqual(len(algorithm.point_dict), self.N) #print algorithm.point_dict self.assertEqual( algorithm.point_dict, { 0: (2, Fraction(1, 2)), 1: (1, Fraction(1, 1)), 2: (2, Fraction(3, 2)), 3: (1, Fraction(3, 1)), 4: (0, Fraction(3, 1)), 5: (1, Fraction(5, 1)), 6: (2, Fraction(5, 1)) }) def test_tree_three_nodes(self): T = Graph(3) for node in (0, 1, 2): T.add_node(node) for edge in (Edge(0, 1), Edge(1, 2)): T.add_edge(edge) algorithm = TreePlot(T) algorithm.run() self.assertEqual(len(algorithm.point_dict), 3) #print algorithm.point_dict def test_tree_three_nodes_radius_angle(self): T = Graph(3) for node in (0, 1, 2): T.add_node(node) for edge in (Edge(0, 1), Edge(1, 2)): T.add_edge(edge) algorithm = TreePlotRadiusAngle(T) algorithm.run() self.assertEqual(len(algorithm.point_dict), 3) #print algorithm.point_dict self.assertEqual(algorithm.point_dict, { 0: (1, Fraction(3, 2)), 1: (0, Fraction(3, 1)), 2: (1, Fraction(9, 2)) }) def tearDown(self): pass
class TestDFS(unittest.TestCase): def setUp(self): # The graph from Cormen p.607 self.N = 8 # number of nodes self.G = Graph(self.N) self.nodes = range(self.N) self.edges = [ Edge(0, 4, 2), Edge(0, 1, 3), Edge(1, 5, 4), Edge(5, 2, 5), Edge(5, 6, 6), Edge(2, 6, 7), Edge(2, 3, 8), Edge(6, 3, 9), Edge(6, 7, 10), Edge(3, 7, 11) ] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) #print self.G #self.G.show() def test_dfs_with_stack(self): self.assertEqual(self.G.v(), self.N) pre_order = [] post_order = [] algorithm = DFSWithStack(self.G) algorithm.run(1, pre_action=lambda node: pre_order.append(node), post_action=lambda node: post_order.append(node)) pre_order_expected = [1, 0, 5, 2, 6, 3, 7, 4] post_order_expected = [1, 5, 6, 7, 3, 2, 0, 4] self.assertEqual(pre_order, pre_order_expected) self.assertEqual(post_order, post_order_expected) dd_expected = {0: 2, 1: 1, 2: 5, 3: 8, 4: 14, 5: 3, 6: 6, 7: 9} ff_expected = {0: 15, 1: 4, 2: 13, 3: 12, 4: 16, 5: 7, 6: 10, 7: 11} self.assertEqual(algorithm.dd, dd_expected) self.assertEqual(algorithm.ff, ff_expected) parent_expected = {0: 1, 1: None, 2: 5, 3: 6, 4: 0, 5: 1, 6: 5, 7: 6} self.assertEqual(algorithm.parent, parent_expected) self.assertEqual(algorithm.path(1, 7), [1, 5, 6, 7]) self.assertEqual(algorithm.path(1, 4), [1, 0, 4]) #algorithm.dag.show() self.assertEqual(algorithm.dag.v(), self.N) self.assertEqual(algorithm.dag.e(), self.N - 1) self.assertTrue(algorithm.dag.is_directed()) for edge in algorithm.dag.iteredges(): self.assertTrue(self.G.has_edge(edge)) self.assertEqual(edge.weight, self.G.weight(edge)) def test_dfs_with_recursion(self): self.assertEqual(self.G.v(), self.N) pre_order = [] post_order = [] algorithm = DFSWithRecursion(self.G) algorithm.run(1, pre_action=lambda node: pre_order.append(node), post_action=lambda node: post_order.append(node)) pre_order_expected = [1, 0, 4, 5, 2, 3, 6, 7] post_order_expected = [4, 0, 7, 6, 3, 2, 5, 1] self.assertEqual(pre_order, pre_order_expected) self.assertEqual(post_order, post_order_expected) dd_expected = {0: 2, 1: 1, 2: 7, 3: 8, 4: 3, 5: 6, 6: 9, 7: 10} ff_expected = {0: 5, 1: 16, 2: 14, 3: 13, 4: 4, 5: 15, 6: 12, 7: 11} self.assertEqual(algorithm.dd, dd_expected) self.assertEqual(algorithm.ff, ff_expected) parent_expected = {0: 1, 1: None, 2: 5, 3: 2, 4: 0, 5: 1, 6: 3, 7: 6} self.assertEqual(algorithm.parent, parent_expected) self.assertEqual(algorithm.path(1, 7), [1, 5, 2, 3, 6, 7]) self.assertEqual(algorithm.path(1, 4), [1, 0, 4]) #algorithm.dag.show() self.assertEqual(algorithm.dag.v(), self.N) self.assertEqual(algorithm.dag.e(), self.N - 1) self.assertTrue(algorithm.dag.is_directed()) for edge in algorithm.dag.iteredges(): self.assertTrue(self.G.has_edge(edge)) self.assertEqual(edge.weight, self.G.weight(edge)) def test_simple_dfs_with_recursion(self): self.assertEqual(self.G.v(), self.N) pre_order = [] post_order = [] algorithm = SimpleDFS(self.G) algorithm.run(1, pre_action=lambda node: pre_order.append(node), post_action=lambda node: post_order.append(node)) pre_order_expected = [1, 0, 4, 5, 2, 3, 6, 7] post_order_expected = [4, 0, 7, 6, 3, 2, 5, 1] self.assertEqual(pre_order, pre_order_expected) self.assertEqual(post_order, post_order_expected) parent_expected = {0: 1, 1: None, 2: 5, 3: 2, 4: 0, 5: 1, 6: 3, 7: 6} self.assertEqual(algorithm.parent, parent_expected) self.assertEqual(algorithm.path(1, 7), [1, 5, 2, 3, 6, 7]) self.assertEqual(algorithm.path(1, 4), [1, 0, 4]) #algorithm.dag.show() self.assertEqual(algorithm.dag.v(), self.N) self.assertEqual(algorithm.dag.e(), self.N - 1) self.assertTrue(algorithm.dag.is_directed()) for edge in algorithm.dag.iteredges(): self.assertTrue(self.G.has_edge(edge)) self.assertEqual(edge.weight, self.G.weight(edge)) def tearDown(self): pass