Beispiel #1
0
 def is_conditionaly_independent_of(self, n1: NumCatRVariable,
                                    n2: NumCatRVariable) -> bool:
     """!
     check if two nodes are conditionally independent
     from K. Murphy, 2012, p. 662
     """
     return BaseGraphAnalyzer.is_node_independent_of(self, n1, n2)
 def test_has_self_loop(self):
     """"""
     n1 = Node("n1", {})
     n2 = Node("n2", {})
     e1 = Edge("e1",
               start_node=n1,
               end_node=n2,
               edge_type=EdgeType.UNDIRECTED)
     e2 = Edge("e2",
               start_node=n1,
               end_node=n1,
               edge_type=EdgeType.UNDIRECTED)
     g1 = BaseGraph("graph", nodes=set([n1, n2]), edges=set([e1, e2]))
     g2 = BaseGraph("graph", nodes=set([n1, n2]), edges=set([e1]))
     self.assertTrue(BaseGraphAnalyzer.has_self_loop(g1))
     self.assertFalse(BaseGraphAnalyzer.has_self_loop(g2))
Beispiel #3
0
    def __init__(
        self,
        gid: str,
        nodes: Union[Set[AbstractNode], FrozenSet[AbstractNode]],
        edges: Union[Set[AbstractEdge], FrozenSet[AbstractEdge]],
        data={},
    ):
        super().__init__(oid=gid, odata=data)
        if not isinstance(nodes, (frozenset, set)):
            raise TypeError("Nodes must be a set or a frozenset")
        if not isinstance(edges, (frozenset, set)):
            raise TypeError("Edges must be a set or a frozenset")
        self._nodes: FrozenSet[AbstractNode] = BaseGraphOps.get_nodes(
            ns=nodes, es=edges
        )
        self._edges: FrozenSet[AbstractEdge] = frozenset(edges)
        #
        self.gdata: Dict[str, List[str]] = BaseGraphOps.to_edgelist(self)
        if self._nodes is not None:
            self.is_empty = len(self._nodes) == 0
        else:
            self.is_empty = True

        is_trivial = BaseGraphAnalyzer.is_trivial(self)
        if is_trivial:
            msg = "This library is not compatible with computations with trivial graph"
            msg += "\nNodes: "
            msg += str([n.id() for n in self.V])
            msg += "\nEdges: " + str([e.id() for e in self.E])
            raise ValueError(msg)
Beispiel #4
0
def min_unmarked_neighbours(g: Graph, nodes: Set[Node], marked: Dict[str,
                                                                     Node]):
    """!
    \brief find an unmarked node with minimum number of neighbours
    """
    ordered = [(n, BaseGraphAnalyzer.nb_neighbours_of(g, n)) for n in nodes]
    ordered.sort(key=lambda x: x[1])
    for X, nb in sorted(ordered, key=lambda x: x[1]):
        if marked[X.id()] is False:
            return X
    return None
Beispiel #5
0
    def transitive_closure_matrix(self) -> Dict[Tuple[str, str], bool]:
        """!
        \brief Obtain transitive closure matrix of a given graph

        Transitive closure is defined by Joyner, et. al. as:

        - Consider a digraph \f$G = (V, E)\f$ of order \f$n = |V |\f$. The
          transitive closure of G is defined as the digraph \f$G^{∗} = (V,
          E^{∗}) \f$ having the same vertex set as G. However, the edge set
          \f$E^{∗}\f$ of \f$G^{∗}\f$ consists of all edges uv such that there
          is a u-v path in G and \f$uv \not \in E\f$. The transitive closure
          \f$G^{*}\f$ answers an important question about G: If u and v are two
          distinct vertices of G, are they connected by a path with length ≥ 1?

        Variant of the Floyd-Roy-Warshall algorithm taken from Joyner,
        Phillips, Nguyen, Algorithmic Graph Theory, 2013, p.134

        \throws ValueError we raise a value error if the graph has a self loop.

        \code{.py}

        >>> a = Node("a", {})  # b
        >>> b = Node("b", {})  # c
        >>> f = Node("f", {})  # d
        >>> e = Node("e", {})  # e
        >>> ae = Edge(
        >>>    "ae", start_node=a, end_node=e, edge_type=EdgeType.UNDIRECTED
        >>> )

        >>> af = Edge(
        >>>     "af", start_node=a, end_node=f, edge_type=EdgeType.UNDIRECTED
        >>> )

        >>> ef = Edge(
        >>>     "ef", start_node=e, end_node=f, edge_type=EdgeType.UNDIRECTED
        >>> )

        >>> ugraph1 = Graph(
        >>>     "graph",
        >>>     data={"my": "graph", "data": "is", "very": "awesome"},
        >>>   nodes=set([a, b, e, f]),
        >>>   edges=set([ae, af, ef]),
        >>> )
        >>> mat == {
        >>>     ("a", "b"): True,
        >>>     ("a", "e"): True,
        >>>     ("a", "f"): True,
        >>>     ("b", "a"): False,
        >>>     ("b", "e"): False,
        >>>     ("b", "f"): False,
        >>>     ("e", "a"): True,
        >>>     ("e", "b"): True,
        >>>     ("e", "f"): True,
        >>>     ("f", "a"): True,
        >>>     ("f", "b"): True,
        >>>     ("f", "e"): True
        >>>   }
        >>> True

        \endcode
        """
        if BaseGraphAnalyzer.has_self_loop(self):
            raise ValueError("Graph has a self loop")
        #
        T = self.to_adjmat(vtype=bool)
        for k in self.V.copy():
            for i in self.V.copy():
                for j in self.V.copy():
                    t_ij = T[(i.id(), j.id())]
                    t_ik = T[(i.id(), k.id())]
                    t_ki = T[(i.id(), k.id())]
                    T[(i.id(), j.id())] = t_ij or (t_ik and t_ki)
        T = {(k, i): v for (k, i), v in T.items() if k != i}
        return T
 def test_is_trivial_1(self):
     """"""
     b = BaseGraphAnalyzer.is_trivial(self.graph)
     self.assertFalse(b)
 def test_order(self):
     """"""
     b = BaseGraphAnalyzer.order(self.graph)
     self.assertEqual(b, 4)
 def test_ev_ratio(self):
     deg = BaseGraphAnalyzer.ev_ratio(self.graph)
     self.assertEqual(0.5, deg)
Beispiel #9
0
 def test_visit_graph_dfs_cycles_true(self):
     "test visit graph dfs function"
     c3 = BaseGraphAnalyzer.has_cycles(self.ugraph2)
     self.assertTrue(c3)
 def test_average_degree(self):
     """"""
     adeg = BaseGraphAnalyzer.average_degree(self.graph)
     self.assertEqual(adeg, 1)
 def test_min_degree_vs(self):
     """"""
     mds = BaseGraphAnalyzer.min_degree_vs(self.graph)
     self.assertEqual(mds, set([self.n4]))
 def test_min_degree(self):
     """"""
     md = BaseGraphAnalyzer.min_degree(self.graph)
     self.assertEqual(md, 0)
 def test_nb_edges(self):
     """"""
     b = BaseGraphAnalyzer.nb_edges(self.graph)
     self.assertEqual(b, 2)
 def test_is_stable(self):
     """"""
     self.assertTrue(
         BaseGraphAnalyzer.is_stable(self.ugraph4,
                                     set([self.a, self.n3, self.n1])))
 def test_is_node_independant_of(self):
     self.assertTrue(
         BaseGraphAnalyzer.is_node_independent_of(self.graph_2, self.n1,
                                                  self.n3))
 def test_ev_ratio_from_average_degree(self):
     deg = BaseGraphAnalyzer.ev_ratio_from_average_degree(self.graph, 5)
     self.assertEqual(2.5, deg)
Beispiel #17
0
 def lower_bound_for_path_length(self) -> int:
     """!
     \brief also known as shortest possible path length
     see proof Diestel 2017, p. 8
     """
     return BaseGraphAnalyzer.min_degree(self)
Beispiel #18
0
 def test_nb_neighbours_of(self):
     ndes = BaseGraphAnalyzer.nb_neighbours_of(self.graph_2, self.n2)
     self.assertEqual(ndes, 2)