Пример #1
0
    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)
Пример #2
0
    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))
Пример #3
0
    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))
Пример #4
0
    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))
Пример #5
0
    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))
Пример #6
0
    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))
Пример #7
0
    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)
Пример #8
0
    def test_add_remove(self):
        node1 = MagicMock(Node)
        node2 = MagicMock(Node)
        graph = MagicMock(Graph)
        node1.graph = graph
        node2.graph = graph
        branch = Branch(node1, node2, "1234")
        graph.add_branch.assert_called_once_with(branch)
        node1.add_outgoing_branch.assert_called_once_with(branch)
        node2.add_ingoing_branch.assert_called_once_with(branch)
        self.assertEqual(graph, branch.graph)

        branch.remove()
        self.assertIsNone(branch.graph)
        node1.remove_outgoing_branch.assert_called_once_with(branch)
        node2.remove_ingoing_branch.assert_called_once_with(branch)
Пример #9
0
    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)
Пример #10
0
    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))
Пример #11
0
    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))
Пример #12
0
    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)
Пример #13
0
    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))
Пример #14
0
    def test_to_dict(self):
        node1 = MagicMock(Node)
        node2 = MagicMock(Node)
        graph = MagicMock(Graph)
        node1.graph = graph
        node2.graph = graph
        hex1 = MagicMock()
        hex1.hex = '1234'
        node1.id = hex1
        hex2 = MagicMock()
        hex2.hex = '5678'
        node2.id = hex2
        branch = Branch(node1, node2, "1234")

        dict = {
            'id': branch.id.hex,
            'weight': '1234',
            'start': '1234',
            'end': '5678',
        }
        self.assertEqual(dict, branch.to_dict())
Пример #15
0
    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))
Пример #16
0
    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))
Пример #17
0
    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)
Пример #18
0
    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))
Пример #19
0
    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)
Пример #20
0
    def test_properties(self):
        node1 = MagicMock(Node)
        node2 = MagicMock(Node)
        graph = MagicMock(Graph)
        node1.graph = graph
        node2.graph = graph
        branch = Branch(node1, node2, "1234")
        self.assertEqual(node1, branch.start)
        self.assertEqual(node2, branch.end)
        self.assertEqual("1234", branch.weight)
        self.assertEqual(graph, branch.graph)

        branch.weight = "1111"
        self.assertEqual("1111", branch.weight)

        def set_graph(graph: Graph):
            branch.graph = graph

        graph2 = MagicMock(Graph)
        self.assertRaises(ValueError, set_graph, graph2)
        branch.graph = None
        self.assertEqual(None, branch.graph)
        branch.graph = graph2
        self.assertEqual(graph2, branch.graph)
Пример #21
0
    def test_connect(self):
        node1 = MagicMock(Node)
        node2 = MagicMock(Node)
        graph = MagicMock(Graph)
        node1.graph = graph
        node2.graph = graph
        branch = Branch(node1, node2, "1234")
        branch.remove()

        node3 = MagicMock(Node)
        node4 = MagicMock(Node)
        node3.graph = graph
        node4.graph = graph

        branch.reconnect(node3, node4)
        self.assertEqual(graph, branch.graph)
        node3.add_outgoing_branch.assert_called_once_with(branch)
        node4.add_ingoing_branch.assert_called_once_with(branch)
Пример #22
0
    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)
Пример #23
0
    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)
Пример #24
0
    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))
Пример #25
0
 def create_branch():
     Branch(node1, node2, "1234")
Пример #26
0
    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))