Python networkx.NetworkXException() Examples

The following are 25 code examples of networkx.NetworkXException(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module networkx , or try the search function .
Example #1
Source File: branchings.py    From qgisSpaceSyntaxToolkit with GNU General Public License v3.0 7 votes vote down vote up
def maximum_spanning_arborescence(G, attr='weight', default=1):
    ed = Edmonds(G)
    B = ed.find_optimum(attr, default, kind='max', style='arborescence')
    if not is_arborescence(B):
        msg = 'No maximum spanning arborescence in G.'
        raise nx.exception.NetworkXException(msg)
    return B 
Example #2
Source File: test_planarity.py    From Carnets with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def check_embedding(G, embedding):
    """Raises an exception if the combinatorial embedding is not correct

    Parameters
    ----------
    G : NetworkX graph
    embedding : a dict mapping nodes to a list of edges
        This specifies the ordering of the outgoing edges from a node for
        a combinatorial embedding

    Notes
    -----
    Checks the following things:
        - The type of the embedding is correct
        - The nodes and edges match the original graph
        - Every half edge has its matching opposite half edge
        - No intersections of edges (checked by Euler's formula)
    """

    if not isinstance(embedding, nx.PlanarEmbedding):
        raise nx.NetworkXException(
            "Bad embedding. Not of type nx.PlanarEmbedding")

    # Check structure
    embedding.check_structure()

    # Check that graphs are equivalent

    assert_equals(set(G.nodes), set(embedding.nodes),
                  "Bad embedding. Nodes don't match the original graph.")

    # Check that the edges are equal
    g_edges = set()
    for edge in G.edges:
        if edge[0] != edge[1]:
            g_edges.add((edge[0], edge[1]))
            g_edges.add((edge[1], edge[0]))
    assert_equals(g_edges, set(embedding.edges),
                  "Bad embedding. Edges don't match the original graph.") 
Example #3
Source File: branchings.py    From aws-kube-codesuite with Apache License 2.0 5 votes vote down vote up
def minimum_spanning_arborescence(G, attr='weight', default=1):
    ed = Edmonds(G)
    B = ed.find_optimum(attr, default, kind='min', style='arborescence')
    if not is_arborescence(B):
        msg = 'No minimum spanning arborescence in G.'
        raise nx.exception.NetworkXException(msg)
    return B 
Example #4
Source File: branchings.py    From aws-kube-codesuite with Apache License 2.0 5 votes vote down vote up
def maximum_spanning_arborescence(G, attr='weight', default=1):
    ed = Edmonds(G)
    B = ed.find_optimum(attr, default, kind='max', style='arborescence')
    if not is_arborescence(B):
        msg = 'No maximum spanning arborescence in G.'
        raise nx.exception.NetworkXException(msg)
    return B 
Example #5
Source File: test_agraph.py    From aws-kube-codesuite with Apache License 2.0 5 votes vote down vote up
def test_view_pygraphviz(self):
        G = nx.Graph()  # "An empty graph cannot be drawn."
        assert_raises(nx.NetworkXException, nx.nx_agraph.view_pygraphviz, G)
        G = nx.barbell_graph(4, 6)
        nx.nx_agraph.view_pygraphviz(G) 
Example #6
Source File: planarity.py    From Carnets with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def add_half_edge_ccw(self, start_node, end_node, reference_neighbor):
        """Adds a half-edge from start_node to end_node.

        The half-edge is added counter clockwise next to the existing half-edge
        (start_node, reference_neighbor).

        Parameters
        ----------
        start_node : node
            Start node of inserted edge.
        end_node : node
            End node of inserted edge.
        reference_neighbor: node
            End node of reference edge.

        Raises
        ------
        nx.NetworkXException
            If the reference_neighbor does not exist.

        See Also
        --------
        add_half_edge_cw
        connect_components
        add_half_edge_first

        """
        if reference_neighbor is None:
            # The start node has no neighbors
            self.add_edge(start_node, end_node)  # Add edge to graph
            self[start_node][end_node]['cw'] = end_node
            self[start_node][end_node]['ccw'] = end_node
            self.nodes[start_node]['first_nbr'] = end_node
        else:
            ccw_reference = self[start_node][reference_neighbor]['ccw']
            self.add_half_edge_cw(start_node, end_node, ccw_reference)

            if reference_neighbor == self.nodes[start_node].get('first_nbr',
                                                                None):
                # Update first neighbor
                self.nodes[start_node]['first_nbr'] = end_node 
Example #7
Source File: planarity.py    From Carnets with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def get_counterexample(G):
    """Obtains a Kuratowski subgraph.

    Raises nx.NetworkXException if G is planar.

    The function removes edges such that the graph is still not planar.
    At some point the removal of any edge would make the graph planar.
    This subgraph must be a Kuratowski subgraph.

    Parameters
    ----------
    G : NetworkX graph

    Returns
    -------
    subgraph : NetworkX graph
        A Kuratowski subgraph that proves that G is not planar.

    """
    # copy graph
    G = nx.Graph(G)

    if check_planarity(G)[0]:
        raise nx.NetworkXException("G is planar - no counter example.")

    # find Kuratowski subgraph
    subgraph = nx.Graph()
    for u in G:
        nbrs = list(G[u])
        for v in nbrs:
            G.remove_edge(u, v)
            if check_planarity(G)[0]:
                G.add_edge(u, v)
                subgraph.add_edge(u, v)

    return subgraph 
Example #8
Source File: branchings.py    From Carnets with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def maximum_spanning_arborescence(G, attr='weight', default=1,
                                  preserve_attrs=False):
    ed = Edmonds(G)
    B = ed.find_optimum(attr, default, kind='max', style='arborescence',
                        preserve_attrs=preserve_attrs)
    if not is_arborescence(B):
        msg = 'No maximum spanning arborescence in G.'
        raise nx.exception.NetworkXException(msg)
    return B 
Example #9
Source File: branchings.py    From qgisSpaceSyntaxToolkit with GNU General Public License v3.0 5 votes vote down vote up
def minimum_spanning_arborescence(G, attr='weight', default=1):
    ed = Edmonds(G)
    B = ed.find_optimum(attr, default, kind='min', style='arborescence')
    if not is_arborescence(B):
        msg = 'No maximum spanning arborescence in G.'
        raise nx.exception.NetworkXException(msg)
    return B 
Example #10
Source File: test_layout.py    From Carnets with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def test_planar_layout_non_planar_input(self):
        G = nx.complete_graph(9)
        assert_raises(nx.NetworkXException, nx.planar_layout, G) 
Example #11
Source File: test_agraph.py    From Carnets with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def test_view_pygraphviz(self):
        G = nx.Graph()  # "An empty graph cannot be drawn."
        assert_raises(nx.NetworkXException, nx.nx_agraph.view_pygraphviz, G)
        G = nx.barbell_graph(4, 6)
        nx.nx_agraph.view_pygraphviz(G) 
Example #12
Source File: graphical.py    From aws-kube-codesuite with Apache License 2.0 4 votes vote down vote up
def is_graphical(sequence, method='eg'):
    """Returns True if sequence is a valid degree sequence.

    A degree sequence is valid if some graph can realize it.

    Parameters
    ----------
    sequence : list or iterable container
        A sequence of integer node degrees

    method : "eg" | "hh"
        The method used to validate the degree sequence.
        "eg" corresponds to the Erdős-Gallai algorithm, and
        "hh" to the Havel-Hakimi algorithm.

    Returns
    -------
    valid : bool
        True if the sequence is a valid degree sequence and False if not.

    Examples
    --------
    >>> G = nx.path_graph(4)
    >>> sequence = (d for n, d in G.degree())
    >>> nx.is_graphical(sequence)
    True

    References
    ----------
    Erdős-Gallai
        [EG1960]_, [choudum1986]_

    Havel-Hakimi
        [havel1955]_, [hakimi1962]_, [CL1996]_
    """
    if method == 'eg':
        valid = is_valid_degree_sequence_erdos_gallai(list(sequence))
    elif method == 'hh':
        valid = is_valid_degree_sequence_havel_hakimi(list(sequence))
    else:
        msg = "`method` must be 'eg' or 'hh'"
        raise nx.NetworkXException(msg)
    return valid 
Example #13
Source File: planar_drawing.py    From Carnets with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
def make_bi_connected(embedding, starting_node, outgoing_node, edges_counted):
    """Triangulate a face and make it 2-connected

    This method also adds all edges on the face to `edges_counted`.

    Parameters
    ----------
    embedding: nx.PlanarEmbedding
        The embedding that defines the faces
    starting_node : node
        A node on the face
    outgoing_node : node
        A node such that the half edge (starting_node, outgoing_node) belongs
        to the face
    edges_counted: set
        Set of all half-edges that belong to a face that have been visited

    Returns
    -------
    face_nodes: list
        A list of all nodes at the border of this face
    """

    # Check if the face has already been calculated
    if (starting_node, outgoing_node) in edges_counted:
        # This face was already counted
        return []
    edges_counted.add((starting_node, outgoing_node))

    # Add all edges to edges_counted which have this face to their left
    v1 = starting_node
    v2 = outgoing_node
    face_list = [starting_node]  # List of nodes around the face
    face_set = set(face_list)  # Set for faster queries
    _, v3 = embedding.next_face_half_edge(v1, v2)

    # Move the nodes v1, v2, v3 around the face:
    while v2 != starting_node or v3 != outgoing_node:
        if v1 == v2:
            raise nx.NetworkXException("Invalid half-edge")
        # cycle is not completed yet
        if v2 in face_set:
            # v2 encountered twice: Add edge to ensure 2-connectedness
            embedding.add_half_edge_cw(v1, v3, v2)
            embedding.add_half_edge_ccw(v3, v1, v2)
            edges_counted.add((v2, v3))
            edges_counted.add((v3, v1))
            v2 = v1
        else:
            face_set.add(v2)
            face_list.append(v2)

        # set next edge
        v1 = v2
        v2, v3 = embedding.next_face_half_edge(v2, v3)

        # remember that this edge has been counted
        edges_counted.add((v1, v2))

    return face_list 
Example #14
Source File: graphical.py    From qgisSpaceSyntaxToolkit with GNU General Public License v3.0 4 votes vote down vote up
def is_graphical(sequence, method='eg'):
    """Returns True if sequence is a valid degree sequence.

    A degree sequence is valid if some graph can realize it.

    Parameters
    ----------
    sequence : list or iterable container
        A sequence of integer node degrees


    method : "eg" | "hh"
        The method used to validate the degree sequence.
        "eg" corresponds to the Erdős-Gallai algorithm, and
        "hh" to the Havel-Hakimi algorithm.

    Returns
    -------
    valid : bool
        True if the sequence is a valid degree sequence and False if not.

    Examples
    --------
    >>> G = nx.path_graph(4)
    >>> sequence = G.degree().values()
    >>> nx.is_valid_degree_sequence(sequence)
    True

    References
    ----------
    Erdős-Gallai
        [EG1960]_, [choudum1986]_

    Havel-Hakimi
        [havel1955]_, [hakimi1962]_, [CL1996]_
    """
    if method == 'eg':
        valid = is_valid_degree_sequence_erdos_gallai(list(sequence))
    elif method == 'hh':
        valid = is_valid_degree_sequence_havel_hakimi(list(sequence))
    else:
        msg = "`method` must be 'eg' or 'hh'"
        raise nx.NetworkXException(msg)
    return valid 
Example #15
Source File: branchings.py    From aws-kube-codesuite with Apache License 2.0 4 votes vote down vote up
def _init(self, attr, default, kind, style):
        if kind not in KINDS:
            raise nx.NetworkXException("Unknown value for `kind`.")

        # Store inputs.
        self.attr = attr
        self.default = default
        self.kind = kind
        self.style = style

        # Determine how we are going to transform the weights.
        if kind == 'min':
            self.trans = trans = _min_weight
        else:
            self.trans = trans = _max_weight

        if attr is None:
            # Generate a random attr the graph probably won't have.
            attr = random_string()

        # This is the actual attribute used by the algorithm.
        self._attr = attr

        # The object we manipulate at each step is a multidigraph.
        self.G = G = MultiDiGraph_EdgeKey()
        for key, (u, v, data) in enumerate(self.G_original.edges(data=True)):
            d = {attr: trans(data.get(attr, default))}
            G.add_edge(u, v, key, **d)

        self.level = 0

        # These are the "buckets" from the paper.
        #
        # As in the paper, G^i are modified versions of the original graph.
        # D^i and E^i are nodes and edges of the maximal edges that are
        # consistent with G^i. These are dashed edges in figures A-F of the
        # paper. In this implementation, we store D^i and E^i together as a
        # graph B^i. So we will have strictly more B^i than the paper does.
        self.B = MultiDiGraph_EdgeKey()
        self.B.edge_index = {}
        self.graphs = []        # G^i
        self.branchings = []    # B^i
        self.uf = nx.utils.UnionFind()

        # A list of lists of edge indexes. Each list is a circuit for graph G^i.
        # Note the edge list will not, in general, be a circuit in graph G^0.
        self.circuits = []
        # Stores the index of the minimum edge in the circuit found in G^i and B^i.
        # The ordering of the edges seems to preserve the weight ordering from G^0.
        # So even if the circuit does not form a circuit in G^0, it is still true
        # that the minimum edge of the circuit in G^i is still the minimum edge
        # in circuit G^0 (depsite their weights being different).
        self.minedge_circuit = [] 
Example #16
Source File: connectivity.py    From qgisSpaceSyntaxToolkit with GNU General Public License v3.0 4 votes vote down vote up
def _bidirectional_pred_succ(G, source, target, exclude):
    # does BFS from both source and target and meets in the middle
    # excludes nodes in the container "exclude" from the search
    if source is None or target is None:
        raise nx.NetworkXException(\
            "Bidirectional shortest path called without source or target")
    if target == source:
        return ({target:None},{source:None},source)

    # handle either directed or undirected
    if G.is_directed():
        Gpred = G.predecessors_iter
        Gsucc = G.successors_iter
    else:
        Gpred = G.neighbors_iter
        Gsucc = G.neighbors_iter

    # predecesssor and successors in search
    pred = {source: None}
    succ = {target: None}

    # initialize fringes, start with forward
    forward_fringe = [source]
    reverse_fringe = [target]

    level = 0
    
    while forward_fringe and reverse_fringe:
        # Make sure that we iterate one step forward and one step backwards
        # thus source and target will only tigger "found path" when they are
        # adjacent and then they can be safely included in the container 'exclude'
        level += 1
        if not level % 2 == 0:
            this_level = forward_fringe
            forward_fringe = []
            for v in this_level:
                for w in Gsucc(v):
                    if w in exclude:
                        continue
                    if w not in pred:
                        forward_fringe.append(w)
                        pred[w] = v
                    if w in succ:
                        return pred, succ, w # found path
        else:
            this_level = reverse_fringe
            reverse_fringe = []
            for v in this_level:
                for w in Gpred(v):
                    if w in exclude:
                        continue
                    if w not in succ:
                        succ[w] = v
                        reverse_fringe.append(w)
                    if w in pred: 
                        return pred, succ, w # found path

    raise nx.NetworkXNoPath("No path between %s and %s." % (source, target)) 
Example #17
Source File: connectivity.py    From Carnets with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
def _bidirectional_pred_succ(G, source, target, exclude):
    # does BFS from both source and target and meets in the middle
    # excludes nodes in the container "exclude" from the search
    if source is None or target is None:
        raise nx.NetworkXException(
            "Bidirectional shortest path called without source or target")
    if target == source:
        return ({target: None}, {source: None}, source)

    # handle either directed or undirected
    if G.is_directed():
        Gpred = G.predecessors
        Gsucc = G.successors
    else:
        Gpred = G.neighbors
        Gsucc = G.neighbors

    # predecesssor and successors in search
    pred = {source: None}
    succ = {target: None}

    # initialize fringes, start with forward
    forward_fringe = [source]
    reverse_fringe = [target]

    level = 0

    while forward_fringe and reverse_fringe:
        # Make sure that we iterate one step forward and one step backwards
        # thus source and target will only trigger "found path" when they are
        # adjacent and then they can be safely included in the container 'exclude'
        level += 1
        if not level % 2 == 0:
            this_level = forward_fringe
            forward_fringe = []
            for v in this_level:
                for w in Gsucc(v):
                    if w in exclude:
                        continue
                    if w not in pred:
                        forward_fringe.append(w)
                        pred[w] = v
                    if w in succ:
                        return pred, succ, w  # found path
        else:
            this_level = reverse_fringe
            reverse_fringe = []
            for v in this_level:
                for w in Gpred(v):
                    if w in exclude:
                        continue
                    if w not in succ:
                        succ[w] = v
                        reverse_fringe.append(w)
                    if w in pred:
                        return pred, succ, w  # found path

    raise nx.NetworkXNoPath("No path between %s and %s." % (source, target)) 
Example #18
Source File: planarity.py    From Carnets with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
def traverse_face(self, v, w, mark_half_edges=None):
        """Returns nodes on the face that belong to the half-edge (v, w).

        The face that is traversed lies to the right of the half-edge (in an
        orientation where v is below w).

        Optionally it is possible to pass a set to which all encountered half
        edges are added. Before calling this method, this set must not include
        any half-edges that belong to the face.

        Parameters
        ----------
        v : node
            Start node of half-edge.
        w : node
            End node of half-edge.
        mark_half_edges: set, optional
            Set to which all encountered half-edges are added.

        Returns
        -------
        face : list
            A list of nodes that lie on this face.
        """
        if mark_half_edges is None:
            mark_half_edges = set()

        face_nodes = [v]
        mark_half_edges.add((v, w))
        prev_node = v
        cur_node = w
        # Last half-edge is (incoming_node, v)
        incoming_node = self[v][w]['cw']

        while cur_node != v or prev_node != incoming_node:
            face_nodes.append(cur_node)
            prev_node, cur_node = self.next_face_half_edge(prev_node, cur_node)
            if (prev_node, cur_node) in mark_half_edges:
                raise nx.NetworkXException(
                    "Bad planar embedding. Impossible face.")
            mark_half_edges.add((prev_node, cur_node))

        return face_nodes 
Example #19
Source File: planarity.py    From Carnets with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
def add_half_edge_cw(self, start_node, end_node, reference_neighbor):
        """Adds a half-edge from start_node to end_node.

        The half-edge is added clockwise next to the existing half-edge
        (start_node, reference_neighbor).

        Parameters
        ----------
        start_node : node
            Start node of inserted edge.
        end_node : node
            End node of inserted edge.
        reference_neighbor: node
            End node of reference edge.

        Raises
        ------
        nx.NetworkXException
            If the reference_neighbor does not exist.

        See Also
        --------
        add_half_edge_ccw
        connect_components
        add_half_edge_first
        """
        self.add_edge(start_node, end_node)  # Add edge to graph

        if reference_neighbor is None:
            # The start node has no neighbors
            self[start_node][end_node]['cw'] = end_node
            self[start_node][end_node]['ccw'] = end_node
            self.nodes[start_node]['first_nbr'] = end_node
            return

        if reference_neighbor not in self[start_node]:
            raise nx.NetworkXException(
                "Cannot add edge. Reference neighbor does not exist")

        # Get half-edge at the other side
        cw_reference = self[start_node][reference_neighbor]['cw']
        # Alter half-edge data structures
        self[start_node][reference_neighbor]['cw'] = end_node
        self[start_node][end_node]['cw'] = cw_reference
        self[start_node][cw_reference]['ccw'] = end_node
        self[start_node][end_node]['ccw'] = reference_neighbor 
Example #20
Source File: planarity.py    From Carnets with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
def check_structure(self):
        """Runs without exceptions if this object is valid.

        Checks that the following properties are fulfilled:

        * Edges go in both directions (because the edge attributes differ).
        * Every edge has a 'cw' and 'ccw' attribute which corresponds to a
          correct planar embedding.
        * A node with a degree larger than 0 has a node attribute 'first_nbr'.

        Running this method verifies that the underlying Graph must be planar.

        Raises
        ------
        nx.NetworkXException
            This exception is raised with a short explanation if the
            PlanarEmbedding is invalid.
        """
        # Check fundamental structure
        for v in self:
            try:
                sorted_nbrs = set(self.neighbors_cw_order(v))
            except KeyError:
                msg = "Bad embedding. " \
                      "Missing orientation for a neighbor of {}".format(v)
                raise nx.NetworkXException(msg)

            unsorted_nbrs = set(self[v])
            if sorted_nbrs != unsorted_nbrs:
                msg = "Bad embedding. Edge orientations not set correctly."
                raise nx.NetworkXException(msg)
            for w in self[v]:
                # Check if opposite half-edge exists
                if not self.has_edge(w, v):
                    msg = "Bad embedding. Opposite half-edge is missing."
                    raise nx.NetworkXException(msg)

        # Check planarity
        counted_half_edges = set()
        for component in nx.connected_components(self):
            if len(component) == 1:
                # Don't need to check single node component
                continue
            num_nodes = len(component)
            num_half_edges = 0
            num_faces = 0
            for v in component:
                for w in self.neighbors_cw_order(v):
                    num_half_edges += 1
                    if (v, w) not in counted_half_edges:
                        # We encountered a new face
                        num_faces += 1
                        # Mark all half-edges belonging to this face
                        self.traverse_face(v, w, counted_half_edges)
            num_edges = num_half_edges // 2  # num_half_edges is even
            if num_nodes - num_edges + num_faces != 2:
                # The result does not match Euler's formula
                msg = "Bad embedding. The graph does not match Euler's formula"
                raise nx.NetworkXException(msg) 
Example #21
Source File: test_planarity.py    From Carnets with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
def check_counterexample(G, sub_graph):
    """Raises an exception if the counterexample is wrong.

    Parameters
    ----------
    G : NetworkX graph
    subdivision_nodes : set
        A set of nodes inducing a subgraph as a counterexample
    """
    # 1. Create the sub graph
    sub_graph = nx.Graph(sub_graph)

    # 2. Remove self loops
    for u in sub_graph:
        if sub_graph.has_edge(u, u):
            sub_graph.remove_edge(u, u)

    # keep track of nodes we might need to contract
    contract = list(sub_graph)

    # 3. Contract Edges
    while len(contract) > 0:
        contract_node = contract.pop()
        if contract_node not in sub_graph:
            # Node was already contracted
            continue
        degree = sub_graph.degree[contract_node]
        # Check if we can remove the node
        if degree == 2:
            # Get the two neighbors
            neighbors = iter(sub_graph[contract_node])
            u = next(neighbors)
            v = next(neighbors)
            # Save nodes for later
            contract.append(u)
            contract.append(v)
            # Contract edge
            sub_graph.remove_node(contract_node)
            sub_graph.add_edge(u, v)

    # 4. Check for isomorphism with K5 or K3_3 graphs
    if len(sub_graph) == 5:
        if not nx.is_isomorphic(nx.complete_graph(5), sub_graph):
            raise nx.NetworkXException("Bad counter example.")
    elif len(sub_graph) == 6:
        if not nx.is_isomorphic(nx.complete_bipartite_graph(3, 3), sub_graph):
            raise nx.NetworkXException("Bad counter example.")
    else:
        raise nx.NetworkXException("Bad counter example.") 
Example #22
Source File: branchings.py    From qgisSpaceSyntaxToolkit with GNU General Public License v3.0 4 votes vote down vote up
def _init(self, attr, default, kind, style):
        if kind not in KINDS:
            raise nx.NetworkXException("Unknown value for `kind`.")

        # Store inputs.
        self.attr = attr
        self.default = default
        self.kind = kind
        self.style = style

        # Determine how we are going to transform the weights.
        if kind == 'min':
            self.trans = trans = _min_weight
        else:
            self.trans = trans = _max_weight

        if attr is None:
            # Generate a random attr the graph probably won't have.
            attr = random_string()

        # This is the actual attribute used by the algorithm.
        self._attr = attr

        # The object we manipulate at each step is a multidigraph.
        self.G = G = MultiDiGraph_EdgeKey()
        for key, (u, v, data) in enumerate(self.G_original.edges(data=True)):
            d = {attr: trans(data.get(attr, default))}
            G.add_edge(u, v, key, **d)

        self.level = 0

        # These are the "buckets" from the paper.
        #
        # As in the paper, G^i are modified versions of the original graph.
        # D^i and E^i are nodes and edges of the maximal edges that are
        # consistent with G^i. These are dashed edges in figures A-F of the
        # paper. In this implementation, we store D^i and E^i together as a
        # graph B^i. So we will have strictly more B^i than the paper does.
        self.B = MultiDiGraph_EdgeKey()
        self.B.edge_index = {}
        self.graphs = []        # G^i
        self.branchings = []    # B^i
        self.uf = nx.utils.UnionFind()

        # A list of lists of edge indexes. Each list is a circuit for graph G^i.
        # Note the edge list will not, in general, be a circuit in graph G^0.
        self.circuits = []
        # Stores the index of the minimum edge in the circuit found in G^i and B^i.
        # The ordering of the edges seems to preserve the weight ordering from G^0.
        # So even if the circuit does not form a circuit in G^0, it is still true
        # that the minimum edge of the circuit in G^i is still the minimum edge
        # in circuit G^0 (depsite their weights being different).
        self.minedge_circuit = [] 
Example #23
Source File: test_planar_drawing.py    From Carnets with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
def check_edge_intersections(G, pos):
    """Check all edges in G for intersections.

    Raises an exception if an intersection is found.

    Parameters
    ----------
    G : NetworkX graph
    pos : dict
        Maps every node to a tuple (x, y) representing its position

    """
    for a, b in G.edges():
        for c, d in G.edges():
            # Check if end points are different
            if a != c and b != d and b != c and a != d:
                x1, y1 = pos[a]
                x2, y2 = pos[b]
                x3, y3 = pos[c]
                x4, y4 = pos[d]
                determinant = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4)
                if determinant != 0:  # the lines are not parallel
                    # calculate intersection point, see:
                    # https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection
                    px = ((x1 * y2 - y1 * x2) * (x3 - x4) -
                          (x1 - x2) * (x3 * y4 - y3 * x4) / float(determinant))
                    py = ((x1 * y2 - y1 * x2) * (y3 - y4) -
                          (y1 - y2) * (x3 * y4 - y3 * x4) / float(determinant))

                    # Check if intersection lies between the points
                    if (point_in_between(pos[a], pos[b], (px, py)) and
                            point_in_between(pos[c], pos[d], (px, py))):
                        msg = "There is an intersection at {},{}".format(px,
                                                                         py)
                        raise nx.NetworkXException(msg)

                #  Check overlap
                msg = "A node lies on a edge connecting two other nodes"
                if (point_in_between(pos[a], pos[b], pos[c]) or
                        point_in_between(pos[a], pos[b], pos[d]) or
                        point_in_between(pos[c], pos[d], pos[a]) or
                        point_in_between(pos[c], pos[d], pos[b])):
                    raise nx.NetworkXException(msg)
    # No edge intersection found 
Example #24
Source File: graphical.py    From Carnets with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
def is_graphical(sequence, method='eg'):
    """Returns True if sequence is a valid degree sequence.

    A degree sequence is valid if some graph can realize it.

    Parameters
    ----------
    sequence : list or iterable container
        A sequence of integer node degrees

    method : "eg" | "hh"  (default: 'eg')
        The method used to validate the degree sequence.
        "eg" corresponds to the Erdős-Gallai algorithm, and
        "hh" to the Havel-Hakimi algorithm.

    Returns
    -------
    valid : bool
        True if the sequence is a valid degree sequence and False if not.

    Examples
    --------
    >>> G = nx.path_graph(4)
    >>> sequence = (d for n, d in G.degree())
    >>> nx.is_graphical(sequence)
    True

    References
    ----------
    Erdős-Gallai
        [EG1960]_, [choudum1986]_

    Havel-Hakimi
        [havel1955]_, [hakimi1962]_, [CL1996]_
    """
    if method == 'eg':
        valid = is_valid_degree_sequence_erdos_gallai(list(sequence))
    elif method == 'hh':
        valid = is_valid_degree_sequence_havel_hakimi(list(sequence))
    else:
        msg = "`method` must be 'eg' or 'hh'"
        raise nx.NetworkXException(msg)
    return valid 
Example #25
Source File: layout.py    From Carnets with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
def planar_layout(G, scale=1, center=None, dim=2):
    """Position nodes without edge intersections.

    Parameters
    ----------
    G : NetworkX graph or list of nodes
        A position will be assigned to every node in G. If G is of type
        PlanarEmbedding, the positions are selected accordingly.

    Parameters
    ----------
    G : NetworkX graph or list of nodes
        A position will be assigned to every node in G. If G is of type
        nx.PlanarEmbedding, the positions are selected accordingly.

    scale : number (default: 1)
        Scale factor for positions.

    center : array-like or None
        Coordinate pair around which to center the layout.

    dim : int
        Dimension of layout.

    Returns
    -------
    pos : dict
        A dictionary of positions keyed by node

    Raises
    ------
    nx.NetworkXException
        If G is not planar

    Examples
    --------
    >>> G = nx.path_graph(4)
    >>> pos = nx.planar_layout(G)
    """
    import numpy as np

    if dim != 2:
        raise ValueError('can only handle 2 dimensions')

    G, center = _process_params(G, center, dim)

    if len(G) == 0:
        return {}

    if isinstance(G, nx.PlanarEmbedding):
        embedding = G
    else:
        is_planar, embedding = nx.check_planarity(G)
        if not is_planar:
            raise nx.NetworkXException("G is not planar.")
    pos = nx.combinatorial_embedding_to_pos(embedding)
    node_list = list(embedding)
    pos = np.row_stack((pos[x] for x in node_list))
    pos = pos.astype(np.float64)
    pos = rescale_layout(pos, scale=scale) + center
    return dict(zip(node_list, pos))