Exemple #1
0
def has_singleton(A) -> bool:
    assert A is not None
    if is_multiobjects(A):
        return any(has_singleton(adj) for adj in A)
    out_deg = A.sum(1).A1
    in_deg = A.sum(0).A1
    return np.any(np.logical_and(in_deg == 0, out_deg == 0))
Exemple #2
0
def is_connected(A) -> bool:
    """Returns True if the graph is connected, False otherwise.
    For directed graph, it test the weak connectivity.

    A directed graph is weakly connected if and only if the graph
    is connected when the direction of the edge between nodes is ignored.

    Note that if a graph is strongly connected (i.e. the graph is connected
    even when we account for directionality), it is by definition weakly
    connected as well.

    Example
    -------
    >>> G = np.array([[0,1,1], [0,0,0], [0,0,0]])
    >>> G
    array([[0, 1, 1],
       [0, 0, 0],
       [0, 0, 0]])
    >>> G = sp.csr_matrix(G)
    >>> gf.is_connected(G)
    True
    """
    assert A is not None
    if is_multiobjects(A):
        return all(is_connected(adj) for adj in A)
    return sp.csgraph.connected_components(A,
                                           directed=is_directed(A),
                                           return_labels=False,
                                           connection='weak') == 1
Exemple #3
0
def is_eulerian(A):
    """Returns True if and only if `A` is Eulerian.

    A graph is *Eulerian* if it has an Eulerian circuit. An *Eulerian
    circuit* is a closed walk that includes each edge of a graph exactly
    once.

    Parameters
    ----------
    A : Scipy sparse matrix
       A graph, either directed or undirected.

    Examples
    --------
    >>> gf.is_eulerian(nx.to_scipy_sparse_matrix(nx.DiGraph({0: [3], 1: [2], 2: [3], 3: [0, 1]})))
    True
    >>> gf.is_eulerian(nx.to_scipy_sparse_matrix(nx.complete_graph(5)))
    True
    >>> gf.is_eulerian(nx.to_scipy_sparse_matrix(nx.petersen_graph()))
    False


    Notes
    -----
    If the graph is not connected (or not strongly connected, for
    directed graphs), this function returns False.

    See Also
    --------
    networkx.is_eulerian
    """
    assert A is not None
    if is_multiobjects(A):
        return all(is_eulerian(adj) for adj in A)

    if not is_connected(A):
        return False

    deg = degree(A)
    if isinstance(deg, tuple):
        # Directed graph
        # Every node must have equal in degree and out degree and the
        # graph must be strongly connected
        ind, outd = deg
        return np.all(ind == outd)
    # An undirected Eulerian graph has no vertices of odd degree and
    # must be connected.
    return np.all(deg % 2 == 0)
Exemple #4
0
def is_strong_connected(A) -> bool:
    """Test directed graph for strong connectivity.

    A directed graph is strongly connected if and only if every vertex in
    the graph is reachable from every other vertex.

    Example
    -------
    >>> G = np.array([[0,1,1], [0,0,0], [0,0,0]])
    >>> G
    array([[0, 1, 1],
       [0, 0, 0],
       [0, 0, 0]])
    >>> G = sp.csr_matrix(G)
    >>> gf.is_strong_connected(G)
    False
    """
    assert A is not None
    if is_multiobjects(A):
        return all(is_strong_connected(adj) for adj in A)
    return sp.csgraph.connected_components(A, directed=is_directed(A), return_labels=False, connection='strong') == 1
Exemple #5
0
def is_weighted(A) -> bool:
    assert A is not None
    if is_multiobjects(A):
        return any(is_weighted(adj) for adj in A)
    return np.any(A.data != 1)
Exemple #6
0
def is_symmetric(A) -> bool:
    assert A is not None
    if is_multiobjects(A):
        return all(is_symmetric(adj) for adj in A)
    return np.abs(A - A.T).sum() == 0
Exemple #7
0
def is_binary(A) -> bool:
    assert A is not None
    if is_multiobjects(A):
        return all(is_binary(adj) for adj in A)
    return np.all(np.unique(A) == (0, 1))
Exemple #8
0
def has_selfloops(A) -> bool:
    assert A is not None
    if is_multiobjects(A):
        return any(has_selfloops(adj) for adj in A)
    return not np.allclose(A.diagonal(), 0)
Exemple #9
0
def is_directed(A) -> bool:
    assert A is not None
    if is_multiobjects(A):
        return any(is_directed(adj) for adj in A)
    return (A != A.T).sum() != 0