def test_johnson_4(self): graph = Graph() node_a = Node(graph) node_b = Node(graph) node_c = Node(graph) node_d = Node(graph) branch_ac = Branch(node_a, node_c, "ac") branch_ca = Branch(node_c, node_a, "ca") branch_ab = Branch(node_a, node_b, "ab") branch_ba = Branch(node_b, node_a, "ba") branch_bc = Branch(node_b, node_c, "bc") branch_cd = Branch(node_c, node_d, "cd") branch_db = Branch(node_d, node_b, "db") actual = strongly_connected_components(graph) expected = [[node_a, node_b, node_c, node_d]] self.assertTrue(self.__check_strongly_connected_components( expected, actual)) cycles = [[branch.id for branch in cycle] for cycle in simple_cycles(graph)] self.assertTrue( self.__check_loop_order([[branch_ac.id, branch_ca.id], [branch_ab.id, branch_ba.id], [branch_ab.id, branch_bc.id, branch_ca.id], [branch_ac.id, branch_cd.id, branch_db.id, branch_ba.id], [branch_bc.id, branch_cd.id, branch_db.id]], cycles))
def test_johnson_2(self): graph = Graph() node_1 = Node(graph) node_2 = Node(graph) node_3 = Node(graph) node_4 = Node(graph) branch_a = Branch(node_1, node_2, "a") branch_b = Branch(node_2, node_1, "b") branch_c = Branch(node_2, node_4, "c") branch_d = Branch(node_4, node_3, "d") branch_e = Branch(node_3, node_1, "e") branch_f = Branch(node_1, node_3, "f") components = strongly_connected_components(graph) self.assertEqual(1, len(components)) self.assertCountEqual([node_3, node_4, node_2, node_1], components[0]) cycles = [[branch.id for branch in cycle] for cycle in simple_cycles(graph)] self.assertTrue(self.__check_loop_order( [[branch_f.id, branch_e.id], [branch_a.id, branch_c.id, branch_d.id, branch_e.id], [branch_a.id, branch_b.id], ], cycles))
def test_self_loops_2(self): graph = Graph() node_1 = Node(graph) branch_a = Branch(node_1, node_1, "a") cycles = [[branch.id for branch in cycle] for cycle in simple_cycles(graph)] self.assertCountEqual([[branch_a.id]], cycles) graph = Graph() node_1 = Node(graph) node_2 = Node(graph) node_3 = Node(graph) node_4 = Node(graph) branch_a = Branch(node_1, node_2, "a") branch_b = Branch(node_2, node_3, "b") branch_c = Branch(node_3, node_1, "c") Branch(node_3, node_4, "d") branch_e = Branch(node_1, node_1, "e") branch_f = Branch(node_2, node_2, "f") branch_g = Branch(node_3, node_3, "g") branch_h = Branch(node_4, node_4, "h") cycles = [[branch.id for branch in cycle] for cycle in simple_cycles(graph)] self.assertTrue(self.__check_loop_order( [[branch_e.id], [branch_a.id, branch_b.id, branch_c.id], [branch_f.id], [branch_g.id], [branch_h.id]], cycles))
def test_not_touching_loops(self): graph = Graph() node_1 = Node(graph) node_2 = Node(graph) node_3 = Node(graph) branch_a = Branch(node_1, node_1, "a") branch_b = Branch(node_2, node_2, "b") branch_c = Branch(node_3, node_3, "c") res = find_loop_groups([ [branch_a], [branch_b], [branch_c] ]) loops = [(loopGroup.loops, loopGroup.loop_count) for loopGroup in res] expected = [ ([[branch_a]], 1), ([[branch_b]], 1), ([[branch_c]], 1), ([[branch_b], [branch_a]], 2), ([[branch_c], [branch_b]], 2), ([[branch_c], [branch_a]], 2), ([[branch_c], [branch_b], [branch_a]], 3), ] self.assertCountEqual(expected, loops)
def test_graph_copy(self): # Create graph graph = Graph() node_1 = Node(graph) node_2 = Node(graph) node_3 = Node(graph) node_4 = Node(graph) Branch(node_1, node_2) Branch(node_2, node_2) Branch(node_2, node_3) Branch(node_3, node_1) Branch(node_1, node_4) # Make copy graph_copy = graph.copy() # Assert nodes_original = list(graph.nodes) nodes_original.sort(key=lambda n: n.id) nodes_copy = list(graph_copy.nodes) nodes_copy.sort(key=lambda n: n.id) branches_original = list(graph.branches) branches_original.sort(key=lambda n: n.id) branches_copy = list(graph_copy.branches) branches_copy.sort(key=lambda n: n.id) for node_original, node_copy in zip(nodes_original, nodes_copy): self.assertTrue(self.__node_equals(node_original, node_copy)) for branch_original, branch_copy in zip(branches_original, branches_copy): self.assertTrue(self.__branch_equals(branch_original, branch_copy))
def test_find_paths_line(self): graph = Graph() node_1 = Node(graph) node_2 = Node(graph) node_3 = Node(graph) branch_a = Branch(node_1, node_2, "a") branch_b = Branch(node_2, node_3, "b") self.assertCountEqual([[branch_a, branch_b]], find_paths(node_1, node_3))
def test_johnson_1(self): graph = Graph() node_1 = Node(graph) node_2 = Node(graph) node_3 = Node(graph) branch_a = Branch(node_1, node_2, "a") branch_b = Branch(node_2, node_3, "b") branch_c = Branch(node_3, node_1, "c") cycles = [[branch.id for branch in cycle] for cycle in simple_cycles(graph)] self.assertTrue(self.__check_loop_order( [[branch_a.id, branch_b.id, branch_c.id]], cycles))
def test_find_paths_self_loop4(self): graph = Graph() node_1 = Node(graph) node_2 = Node(graph) node_3 = Node(graph) node_4 = Node(graph) branch_a = Branch(node_1, node_2, "a") Branch(node_1, node_3, "b") Branch(node_3, node_4, "c") Branch(node_4, node_1, "d") paths = find_paths(node_1, node_2) self.assertCountEqual([[branch_a]], paths)
def test_strongly_connected_components(self): graph = Graph() node_1 = Node(graph) node_2 = Node(graph) node_3 = Node(graph) Branch(node_1, node_2, "a") Branch(node_2, node_3, "b") Branch(node_2, node_3, "c") Branch(node_3, node_1, "d") components = strongly_connected_components(graph) self.assertEqual(1, len(components)) component = components[0] self.assertCountEqual([node_3, node_2, node_1], component)
def test_loop_to_expression_2(self): graph = Graph() node_1 = Node(graph) node_2 = Node(graph) branch_a = Branch(node_1, node_2, "a") branch_b = Branch(node_2, node_1, "b") branches = [branch_a, branch_b] expectedExpression = Mul(Symbol(branch_a.weight), Symbol(branch_b.weight)) expression = loop_to_expression(branches) self.assertEqual(srepr(expression), srepr(expectedExpression))
def test_johnson_3(self): graph = Graph() node_1 = Node(graph) node_2 = Node(graph) node_3 = Node(graph) node_4 = Node(graph) node_5 = Node(graph) node_6 = Node(graph) node_7 = Node(graph) Branch(node_1, node_2, "a") branch_b = Branch(node_2, node_3, "b") branch_c = Branch(node_3, node_4, "c") Branch(node_4, node_5, "d") branch_e = Branch(node_5, node_6, "e") Branch(node_6, node_7, "f") branch_g = Branch(node_6, node_5, "g") branch_h = Branch(node_4, node_3, "h") branch_i = Branch(node_4, node_2, "i") Branch(node_2, node_6, "j") cycles = cycles = [[branch.id for branch in cycle] for cycle in simple_cycles(graph)] self.assertTrue(self.__check_loop_order( [[branch_b.id, branch_c.id, branch_i.id], [branch_h.id, branch_c.id], [branch_e.id, branch_g.id]], cycles))
def test_find_paths_self_loop3(self): graph = Graph() node_1 = Node(graph) node_2 = Node(graph) node_3 = Node(graph) node_4 = Node(graph) node_5 = Node(graph) branch_a = Branch(node_1, node_2, "a") branch_b = Branch(node_2, node_3, "b") branch_c = Branch(node_3, node_4, "c") branch_d = Branch(node_4, node_5, "d") Branch(node_4, node_2, "e") paths = find_paths(node_1, node_5) self.assertCountEqual([[branch_a, branch_b, branch_c, branch_d]], paths)
def test_find_paths_self_loops(self): graph = Graph() node_1 = Node(graph) node_2 = Node(graph) node_3 = Node(graph) branch_a = Branch(node_1, node_2, "a") branch_b = Branch(node_2, node_3, "b") branch_c = Branch(node_2, node_3, "c") Branch(node_2, node_2, "d") branch_e = Branch(node_2, node_1, "e") branch_f = Branch(node_3, node_1, "f") self.assertCountEqual([[branch_a, branch_b], [branch_a, branch_c]], find_paths(node_1, node_3)) paths = find_paths(node_2, node_1) self.assertCountEqual( [[branch_c, branch_f], [branch_e], [branch_b, branch_f]], paths)
def test_loop_to_expression_1(self): graph = Graph() node_1 = Node(graph) branch_a = Branch(node_1, node_1, "a") branches = [branch_a] expectedExpression = Symbol(branch_a.weight) expression = loop_to_expression(branches) self.assertEqual(srepr(expression), srepr(expectedExpression))
def test_subgraph(self): graph = Graph() node = Node(graph) subgraph = graph.subgraph({node}) self.assertEqual(1, len(subgraph.nodes)) self.assertEqual(0, len(graph.nodes)) self.assertEqual(node, list(subgraph.nodes)[0]) self.assertEqual(node.graph, subgraph) graph = Graph() node_1 = Node(graph) node_2 = Node(graph) node_3 = Node(graph) branch_1 = Branch(node_1, node_2, "1") branch_2 = Branch(node_2, node_1, "2") Branch(node_2, node_3, "3") Branch(node_3, node_1, "4") branch_5 = Branch(node_3, node_3, "5") branch_6 = Branch(node_2, node_2, "6") subgraph = graph.subgraph([node_1, node_2]) self.assertCountEqual([node_1, node_2], subgraph.nodes) self.assertCountEqual([node_3], graph.nodes) self.assertCountEqual([branch_1, branch_2, branch_6], subgraph.branches) self.assertCountEqual([branch_5], graph.branches) self.assertEqual(node_1.graph, subgraph) self.assertEqual(node_2.graph, subgraph) self.assertEqual(node_3.graph, graph) self.assertEqual(branch_1.graph, subgraph) self.assertEqual(branch_2.graph, subgraph) self.assertEqual(branch_5.graph, graph) self.assertEqual(branch_6.graph, subgraph)
def test_add_invalid_branches(self): graph = MagicMock(Graph) graph2 = MagicMock(Graph) node = Node(graph) self.assertEqual(graph, node.graph) b1 = MagicMock(Branch) b1.graph = graph2 b1.end = node def add_ingoing(): node.add_ingoing_branch(b1) self.assertRaises(ValueError, add_ingoing) b2 = MagicMock(Branch) b2.graph = graph2 b2.start = node def add_outgoing(): node.add_outgoing_branch(b2) self.assertRaises(ValueError, add_outgoing) b1.graph = graph b1.start = MagicMock(Node) b1.end = MagicMock(Node) b2.graph = graph b2.start = MagicMock(Node) b2.end = MagicMock(Node) self.assertRaises(ValueError, add_ingoing) self.assertRaises(ValueError, add_outgoing) node.graph = None b1.start = node b1.end = node b2.start = node b2.end = node self.assertRaises(ValueError, add_ingoing) self.assertRaises(ValueError, add_outgoing) node.graph = graph add_ingoing() add_outgoing() self.assertRaises(ValueError, add_ingoing) self.assertRaises(ValueError, add_outgoing)
def test_set_graph(self): graph = MagicMock(Graph) node = Node(graph) self.assertEqual(graph, node.graph) graph2 = MagicMock(Graph) def set_graph(): node.graph = graph2 self.assertRaises(ValueError, set_graph) node.graph = None self.assertIsNone(node.graph) node.graph = graph2 self.assertEqual(graph2, node.graph)
def test_johson_multiple_scc(self): graph = Graph() node_1 = Node(graph) node_2 = Node(graph) node_3 = Node(graph) node_4 = Node(graph) node_5 = Node(graph) node_6 = Node(graph) node_7 = Node(graph) node_8 = Node(graph) node_9 = Node(graph) Branch(node_1, node_2, "a") branch_b = Branch(node_2, node_3, "b") branch_c = Branch(node_3, node_4, "c") branch_d = Branch(node_4, node_2, "d") branch_e = Branch(node_1, node_5, "e") branch_f = Branch(node_5, node_6, "f") branch_g = Branch(node_6, node_1, "g") branch_h = Branch(node_9, node_7, "h") branch_i = Branch(node_7, node_8, "i") branch_j = Branch(node_8, node_9, "j") Branch(node_6, node_9, "k") actual = strongly_connected_components(graph) expected = [[node_9, node_8, node_7], [node_3, node_2, node_4], [node_6, node_5, node_1]] self.assertTrue(self.__check_strongly_connected_components( expected, actual)) cycles = [[branch.id for branch in cycle] for cycle in simple_cycles(graph)] self.assertTrue( self.__check_loop_order([[branch_b.id, branch_c.id, branch_d.id], [branch_e.id, branch_f.id, branch_g.id], [branch_h.id, branch_i.id, branch_j.id]], cycles))
def test_mason_1(self): # Create graph graph = Graph() # Add nodes node_x = Node(graph) # input node node_1 = Node(graph) node_2 = Node(graph) node_3 = Node(graph) node_4 = Node(graph) node_5 = Node(graph) node_z = Node(graph) # output node # Add branches Branch(node_x, node_1, "a") Branch(node_1, node_2, "b") Branch(node_2, node_3, "c") Branch(node_3, node_4, "d") Branch(node_4, node_5, "e") Branch(node_5, node_z, "f") Branch(node_5, node_4, "g") Branch(node_3, node_2, "h") Branch(node_3, node_1, "j") Branch(node_1, node_5, "k") # Execute result = mason(graph, node_x, node_z) # Assert expected = [ "(a*b*c*d*e*f + a*f*k*(-c*h + 1))", "/(b*c*e*g*j - b*c*j + c*e*g*h - c*h - e*g + 1)" ] T = result.transfer_function[0][0] actual = T.subs(result.transfer_function) \ .subs(result.numerator) \ .subs(result.denominator) \ .subs(result.determinant) \ .subs(result.paths) \ .subs(result.loops) self.assertEqual(expected[0] + expected[1], str(actual))
def test_properties(self): graph = MagicMock(Graph) node = Node(graph) self.assertEqual(graph, node.graph) b1 = MagicMock(Branch) b1.graph = graph b1.end = node node.add_ingoing_branch(b1) self.assertIn(b1, node.ingoing) b2 = MagicMock(Branch) b2.graph = graph b2.start = node node.add_outgoing_branch(b2) self.assertIn(b2, node.outgoing) node.remove_ingoing_branch(b1) self.assertEqual(set(), node.ingoing) node.remove_outgoing_branch(b2) self.assertEqual(set(), node.outgoing)
def test_mason_3(self): # Create graph graph = Graph() # Add nodes node_x = Node(graph) # input node node_1 = Node(graph) node_2 = Node(graph) node_3 = Node(graph) node_4 = Node(graph) node_5 = Node(graph) node_z = Node(graph) # output node # Add branches Branch(node_x, node_z, "g7") Branch(node_z, node_x, "h7") Branch(node_z, node_1, "g8") Branch(node_1, node_2, "C") Branch(node_2, node_3, "g3") Branch(node_3, node_4, "g4") Branch(node_4, node_5, "g5") Branch(node_5, node_x, "g6") Branch(node_2, node_1, "h2") Branch(node_4, node_3, "N") # Execute result = mason(graph, node_x, node_z) # Assert expected_num = "g7*(C*N*g4*h2 - C*h2 - N*g4 + 1)" actual_num = result.numerator[0][1] \ .subs(result.numerator) \ .subs(result.denominator) \ .subs(result.determinant) \ .subs(result.paths) \ .subs(result.loops) self.assertEqual(expected_num, str(actual_num))
def test_find_paths_loop_over_loop(self): # <--j ------------| # | <--h----| <--g---- # | | | | | # X --a--> 1 --b--> 2 --c--> 3 --d--> 4 --e--> 5 --f--> Z # | | # -------------------------------k--> # Create graph graph = Graph() # Create nodes node_x = Node(graph) # input node node_1 = Node(graph) node_2 = Node(graph) node_3 = Node(graph) node_4 = Node(graph) node_5 = Node(graph) node_z = Node(graph) # output node # Create branches and connect nodes branch_a = Branch(node_x, node_1, "a") branch_b = Branch(node_1, node_2, "b") branch_c = Branch(node_2, node_3, "c") branch_d = Branch(node_3, node_4, "d") branch_e = Branch(node_4, node_5, "e") branch_f = Branch(node_5, node_z, "f") Branch(node_5, node_4, "g") Branch(node_3, node_2, "h") Branch(node_3, node_1, "j") branch_k = Branch(node_1, node_5, "k") # Assert paths = find_paths(node_x, node_z) self.assertCountEqual( [[branch_a, branch_b, branch_c, branch_d, branch_e, branch_f], [branch_a, branch_k, branch_f]], paths)
def test_touching_loops(self): graph = Graph() node_1 = Node(graph) node_2 = Node(graph) node_3 = Node(graph) node_4 = Node(graph) node_5 = Node(graph) node_6 = Node(graph) node_7 = Node(graph) Branch(node_1, node_2, "a") branch_b = Branch(node_2, node_3, "b") branch_c = Branch(node_3, node_4, "c") Branch(node_4, node_5, "d") branch_e = Branch(node_5, node_6, "e") Branch(node_6, node_7, "f") branch_g = Branch(node_6, node_5, "g") branch_h = Branch(node_4, node_3, "h") branch_i = Branch(node_4, node_2, "i") Branch(node_2, node_6, "j") res = find_loop_groups([[branch_h, branch_c], [branch_g, branch_e], [branch_i, branch_b, branch_c]]) loops = [(loopGroup.loops, loopGroup.loop_count) for loopGroup in res] expected = [ ([[branch_h, branch_c]], 1), ([[branch_g, branch_e]], 1), ([[branch_i, branch_b, branch_c]], 1), ([[branch_g, branch_e], [branch_h, branch_c]], 2), ([[branch_i, branch_b, branch_c], [branch_g, branch_e]], 2) ] self.assertCountEqual(expected, loops)
def test_to_dict(self): graph = MagicMock(Graph) node = Node(graph) dict = {'id': node.id.hex} self.assertEqual(dict, node.to_dict())
def test_loop_to_expression_3(self): graph = Graph() node_1 = Node(graph) node_2 = Node(graph) node_3 = Node(graph) node_4 = Node(graph) node_5 = Node(graph) node_6 = Node(graph) node_7 = Node(graph) node_8 = Node(graph) node_9 = Node(graph) node_10 = Node(graph) node_11 = Node(graph) branch_a = Branch(node_1, node_2, "a") branch_b = Branch(node_2, node_3, "b") branch_c = Branch(node_3, node_4, "c") branch_d = Branch(node_4, node_5, "d") branch_e = Branch(node_5, node_6, "e") branch_f = Branch(node_6, node_7, "f") branch_g = Branch(node_7, node_8, "g") branch_h = Branch(node_8, node_9, "h") branch_j = Branch(node_9, node_10, "j") branch_k = Branch(node_10, node_11, "k") branch_l = Branch(node_11, node_1, "l") branches = [branch_a, branch_b, branch_c, branch_d, branch_e, branch_f, branch_g, branch_h, branch_j, branch_k, branch_l] expectedExpression = Mul(Symbol(branch_a.weight), Symbol(branch_b.weight), Symbol(branch_c.weight), Symbol(branch_d.weight), Symbol(branch_e.weight), Symbol(branch_f.weight), Symbol(branch_g.weight), Symbol(branch_h.weight), Symbol(branch_j.weight), Symbol(branch_k.weight), Symbol(branch_l.weight)) expression = loop_to_expression(branches) self.assertEqual(srepr(expression), srepr(expectedExpression))