Ejemplo n.º 1
0
 def update(self, ebunch, attr_dict=None, **attr):
     # set up attribute dict
     if attr_dict is None:
         attr_dict = attr
     else:
         try:
             attr_dict.update(attr)
         except AttributeError:
             raise NetworkXError(
                 "The attr_dict argument must be a dictionary.")
     # process ebunch
     for e in ebunch:
         ne = len(e)
         if ne == 3:
             u, v, dd = e
         elif ne == 2:
             u, v = e
             try:
                 {v}  # is v hashable, i.e. a datadict?
             except TypeError:
                 dd = v
                 u, v = u
             else:
                 dd = {}  # doesnt need edge_attr_dict_factory
         else:
             msg = "Edge tuple %s must be a 2-tuple or 3-tuple." % (e, )
             raise NetworkXError(msg)
         datadict = attr_dict.copy()
         datadict.update(dd)
         self._add_edge(u, v, datadict)
Ejemplo n.º 2
0
def check_vrp(G: DiGraph = None):
    """Checks if graph is well defined."""

    # if G is not a DiGraph
    if not isinstance(G, DiGraph):
        raise TypeError(
            "Input graph must be of type networkx.classes.digraph.DiGraph.")
    for v in ["Source", "Sink"]:
        # If Source or Sink is missing
        if v not in G.nodes():
            raise KeyError("Input graph requires Source and Sink nodes.")
        # If Source has incoming edges
        if len(list(G.predecessors("Source"))) > 0:
            raise NetworkXError("Source must have no incoming edges.")
        # If Sink has outgoing edges
        if len(list(G.successors("Sink"))) > 0:
            raise NetworkXError("Sink must have no outgoing edges.")
    # Roundtrips should always be possible
    # Missing edges are added with a high cost
    for v in G.nodes():
        if v not in ["Source", "Sink"]:
            if v not in G.successors("Source"):
                logger.warning("Source not connected to %s" % v)
                G.add_edge("Source", v, cost=1e10)
            if v not in G.predecessors("Sink"):
                logger.warning("%s not connected to Sink" % v)
                G.add_edge(v, "Sink", cost=1e10)
    # If graph is disconnected
    if not has_path(G, "Source", "Sink"):
        raise NetworkXError("Source and Sink are not connected.")
    # If cost is missing
    for (i, j) in G.edges():
        if "cost" not in G.edges[i, j]:
            raise KeyError("Edge (%s,%s) requires cost attribute" % (i, j))
Ejemplo n.º 3
0
 def _check_vrp(self):
     """Checks if graph and vrp constraints are consistent."""
     # if G is not a DiGraph
     if not isinstance(self.G, DiGraph):
         raise TypeError(
             "Input graph must be of type networkx.classes.digraph.DiGraph."
         )
     for v in ["Source", "Sink"]:
         # If Source or Sink is missing
         if v not in self.G.nodes():
             raise KeyError("Input graph requires Source and Sink nodes.")
         # If Source has incoming edges
         if len(list(self.G.predecessors("Source"))) > 0:
             raise NetworkXError("Source must have no incoming edges.")
         # If Sink has outgoing edges
         if len(list(self.G.successors("Sink"))) > 0:
             raise NetworkXError("Sink must have no outgoing edges.")
     # If graph is disconnected
     if not has_path(self.G, "Source", "Sink"):
         raise NetworkXError("Source and Sink are not connected.")
     # If cost is missing
     for (i, j) in self.G.edges():
         if "cost" not in self.G.edges[i, j]:
             raise KeyError("Edge (%s,%s) requires cost attribute" % (i, j))
     # If num_stops/load_capacity/duration are not integers
     if self.num_stops is not None and (not isinstance(self.num_stops, int)
                                        or self.num_stops <= 0):
         raise TypeError(
             "Maximum number of stops must be positive integer.")
     if self.load_capacity is not None and (not isinstance(
             self.load_capacity, int) or self.load_capacity <= 0):
         raise TypeError("Load capacity must be positive integer.")
     if self.duration is not None and (not isinstance(self.duration, int)
                                       or self.duration <= 0):
         raise TypeError("Maximum duration must be positive integer.")
Ejemplo n.º 4
0
def page_rank(G,
              alpha=0.85,
              personalization=None,
              max_iter=100,
              tol=1.0e-6,
              nstart=None,
              weight='weight',
              dangling=None):
    if len(G) == 0:
        return {}
    if not G.is_directed():
        D = G.to_directed()
    else:
        D = G
    W = nx.stochastic_grap(D, weight=weight)
    N = W.number_of_nodes()
    if nstart is None:
        x = dict.fromkeys(W, 1.0 / N)
    else:
        s = float(sum(nstart.values()))
        x = dict((k, v / s) for k, v in nstart.items())
    if personalization is None:
        p = dict.fromkeys(W, 1.0 / N)
    else:
        missing = set(G) - set(personalization)
        if missing:
            raise NetworkXError(
                'Personalization dictionary must have a value for every node. Missing nodes %s'
                % missing)
        s = float(sum(personalization.values()))
        p = dict((k, v / s) for k, v in personalization.items())
    if dangling is None:
        dangling_weights = p
    else:
        missing = set(G) - set(dangling)
        if missing:
            raise NetworkXError(
                'Dangling node dictionary must have a value for every node. Missing nodes %s'
                % missing)
        s = float(sum(dangling.values()))
        dangling_weights = dict((k, v / s) for k, v in dangling.items())
        dangling_nodes = [
            n for n in W if W.out_degree(n, weight=weight) == 0.0
        ]
        for _ in range(max_iter):
            xlast = xx = dict.fromkeys(xlast.keys(), 0)
            danglesum = alpha * sum(xlast[n] for n in dangling_nodes)
            for n in x:
                for nbr in W[n]:
                    x[nbr] += alpha * xlast[n] * W[n][nbr][weight]
                x[n] += danglesum * dangling_weights[n] + (1.0 - alpha) * p[n]
        err = sum([abs(x[n] - xlast[n]) for n in x])
        if err < N * tol:
            return x
    raise NetworkXError(
        'Pagerank: power iteration failed to converge in %d iterations.' %
        max_iter)
Ejemplo n.º 5
0
def init(g):
    if isinstance(g, nx.MultiGraph):
        raise NetworkXError('freeman does not support multigraphs')
    for n, m in g.edges:
        if n == m:
            raise NetworkXError('freeman does not support self loops')
    for n in g.nodes:
        if 'pos' not in g.nodes[n]:
            x = random()
            y = random()
            g.nodes[n]['pos'] = (x, y)
    set_nodeframe(g)
    set_edgeframe(g)
Ejemplo n.º 6
0
def _triangles_and_degree_iter(G, nbunch=None):
    """ Return an iterator of (node, degree, triangles).  

    This double counts triangles so you may want to divide by 2.
    See degree() and triangles() for definitions and details.

    """
    if G.is_multigraph():
        raise NetworkXError("Not defined for multigraphs.")

    if nbunch is None:
        nodes_nbrs = G.adj.iteritems()
    else:
        nodes_nbrs = ((n, G[n]) for n in G.nbunch_iter(nbunch))

    for v, v_nbrs in nodes_nbrs:
        vs = set(v_nbrs)
        if v in vs:
            vs.remove(v)
        ntriangles = 0
        for w in vs:
            ws = set(G[w])
            if w in ws:
                ws.remove(w)
            ntriangles += len(vs.intersection(ws))
        yield (v, len(vs), ntriangles)
Ejemplo n.º 7
0
 def _add_edge(self, u, v, attr_dict):
     if not isinstance(attr_dict, Mapping):  # Mapping includes dict
         raise NetworkXError("The attr_dict argument must be a Mapping.")
     succ = self._mapping
     pred = self._graph._pred
     nodes = self._graph._nodes
     # add nodes
     u_new = u not in succ
     v_new = v not in succ
     if u_new:
         succ[u] = {}  # fixme factory
         pred[u] = {}  # fixme factory
         nodes[u] = {}
     if v_new:
         succ[v] = {}  # fixme factory
         pred[v] = {}  # fixme factory
         nodes[v] = {}
     # find the edge
     if not (u_new or v_new):
         if v in succ[u]:
             datadict = succ[u][v]
             datadict.update(attr_dict)
             return False  # not new edge
         # if not directed check other direction
         if (not self._graph._directed) and v in pred[u]:
             datadict = pred[u][v]
             datadict.update(attr_dict)
             return False  # not new edge
         # else new edge-- drop out of if
     # add new edge
     datadict = attr_dict
     succ[u][v] = datadict
     pred[v][u] = datadict
     return True  # new edge
Ejemplo n.º 8
0
def stochastic_graph(G,copy=True):
    """Return a right-stochastic representation of G.

    A right-stochastic graph is a weighted graph in which all of
    the node (out) neighbors edge weights sum to 1.
    
    Parameters
    -----------
    G : graph
      A networkx graph, must have valid edge weights

    copy : bool, optional
      If True make a copy of the graph, otherwise modify original graph

    """        
    if not G.weighted:
        raise NetworkXError("Input to stochastic_graph() must be a weighted graph.")

    if copy:
        if G.directed:
            W=networkx.DiGraph(G)
        else:
            W=networkx.Graph(G) 
    else:
        W=G # reference original graph, no copy

    for n in W:
        deg=float(sum(W[n].values()))
        for p in W[n]: 
            W[n][p]/=deg
            # also adjust pred entry for consistency 
            # though it is not used in pagerank algorithm
            if G.directed:
                W.pred[p][n]/=deg
    return W
Ejemplo n.º 9
0
    def get_edge_label(self, u, v):
        """
        Returns the edge label of (u,v).

        INPUT:
            u,v: vertex labels
        
        OUTPUT:
            label of (u,v)
        
        DOCTEST:
            sage: G = sage.graphs.base.graph_backends.NetworkXGraphBackend()
            sage: G.get_edge_label(1,2)
            Traceback (most recent call last):
            ...
            NetworkXError: Edge (1,2) requested via get_edge_label does not exist.
        """
        try:
            assert(not isinstance(self._nxg, (NetworkXGraphDeprecated, NetworkXDiGraphDeprecated)))
        except AssertionError:
            self._nxg = self._nxg.mutate()

        try:
            E = self._nxg.edge[u][v]
        except KeyError:
            from networkx import NetworkXError
            raise NetworkXError("Edge (%s,%s) requested via get_edge_label does not exist."%(u,v))

        if self._nxg.is_multigraph():
            return [ e.get('weight',None) for e in E.itervalues() ]
        else:
            return E.get('weight',None)
Ejemplo n.º 10
0
def _weighted_triangles_and_degree_iter(G, nodes=None, weight='weight'):
    """ Return an iterator of (node, degree, weighted_triangles).  
    
    Used for weighted clustering.

    """
    if G.is_multigraph():
        raise NetworkXError("Not defined for multigraphs.")

    if weight is None or G.edges()==[]:
        max_weight=1.0
    else:
        max_weight=float(max(d.get(weight,1.0) 
                             for u,v,d in G.edges(data=True)))
    if nodes is None:
        nodes_nbrs = G.adj.items()
    else:
        nodes_nbrs= ( (n,G[n]) for n in G.nbunch_iter(nodes) )

    for i,nbrs in nodes_nbrs:
        inbrs=set(nbrs)-set([i])
        weighted_triangles=0.0
        seen=set()
        for j in inbrs:
            wij=G[i][j].get(weight,1.0)/max_weight
            seen.add(j)
            jnbrs=set(G[j])-seen # this keeps from double counting
            for k in inbrs&jnbrs:
                wjk=G[j][k].get(weight,1.0)/max_weight
                wki=G[i][k].get(weight,1.0)/max_weight
                weighted_triangles+=(wij*wjk*wki)**(1.0/3.0)
        yield (i,len(inbrs),weighted_triangles*2)
Ejemplo n.º 11
0
def barabasi_albert_graph(n, m, **kwargs):
    """
    Generate a random graph using the Barabasi-Albert preferential attachment model.
    
    **Args**:
    
        * ``n`` (int): the number of nodes to add to the graph
        * ``m`` (int): the number of edges a new node will add to the graph
    
    **KwArgs**:
        * ``directed [=False]`` (boolean): whether to build the graph directed.  If ``True``, then the ``m`` edges created
          by a node upon its creation are instantiated as out-edges.  All others are in-edges to that node.
        * ``seed [=-1]`` (int): a seed for the random number generator
        * ``graph [=None]`` (:py:class:`networkx.Graph` or :py:class:`networkx.DiGraph`): this is the actual graph instance to populate. It must be
          empty and its directionality must agree with the value of ``directed``.
    
    **Returns**:
        :py:class:`networkx.Graph` or :py:class:`networkx.DiGraph`. The graph generated.  If ``directed = True``, then a :py:class:`networkx.DiGraph` will be returned.
    
    .. note::
        Source: A. L. Barabasi and R. Albert "Emergence of scaling in random networks", Science 286, pp 509-512, 1999.
    """
    seed = kwargs.pop('seed', None)
    directed = kwargs.pop('directed', False)
    graph = kwargs.pop('graph', None)

    if graph is not None:
        if len(graph) > 0:
            raise NetworkXError('the graph must be empty, if provided')
        if type(graph) == DiGraph != directed:
            raise NetworkXError('graph and directed arguments must agree')
    else:
        if directed:
            graph = DiGraph()
        else:
            graph = Graph()

    if len(kwargs) > 0:
        raise NetworkXError('Unknown arguments: %s' % ', '.join(kwargs.keys()))

    if seed is None:
        seed = -1

    if not directed:
        return __inner_barabasi_albert_udir(n, m, seed, graph)
    else:
        return __inner_barabasi_albert_dir(n, m, seed, graph)
Ejemplo n.º 12
0
 def _add_edge(self, u, v, k, attr_dict):
     if not isinstance(attr_dict, Mapping):  # Mapping includes dict
         raise NetworkXError( "The attr_dict argument must be a Mapping.")
     succ = self._mapping
     pred = self._graph._pred
     nodes = self._graph._nodes
     # add nodes
     u_new = u not in succ
     v_new = v not in succ
     if u_new:
         succ[u] = {}  # fixme factory
         pred[u] = {}  # fixme factory
         nodes[u] = {}
     if v_new:
         succ[v] = {}  # fixme factory
         pred[v] = {}  # fixme factory
         nodes[v] = {}
     # find the edge
     if not (u_new or v_new):
         new_succ = new_pred = False
         if v in succ[u]:
             skeydict = succ[u][v]
             if k in skeydict:
                 datadict = skeydict[k]
                 datadict.update(attr_dict)
                 return False  # not new edge
             # add edge to keydict
             if k is None:
                 k = len(skeydict)
                 while k in skeydict:
                     k += 1
             datadict = attr_dict
             skeydict[k] = datadict
             return True  # New edge
         # if not directed check other direction
         if (not self._graph._directed) and v in pred[u]:
             pkeydict = pred[u][v]
             if k in pkeydict:
                 datadict = pkeydict[k]
                 datadict.update(attr_dict)
                 return False  # not new edge
             # add edge to keydict
             if k is None:
                 k = len(pkeydict)
                 while k in pkeydict:
                     k += 1
             datadict = attr_dict
             pkeydict[k] = datadict
             return True  # New edge
         # else new edge-- drop out of if
     # add new edge
     k = 0 if k is None else k
     datadict = attr_dict
     keydict = {k: datadict}  # fixme factory
     succ[u][v] = keydict
     pred[v][u] = keydict
     return True # new edge
Ejemplo n.º 13
0
def read_mtx(path: str, node_type=str, edge_key_type=int) -> Union[Graph, DiGraph]:
    reader = MatrixMarketReader(
        node_type=node_type,
        edge_key_type=edge_key_type
    )
    glist: List[Union[Graph, DiGraph]] = [reader(path=path)]
    if len(glist) == 0:
        raise NetworkXError('file not successfully read as mtx')
    return glist[0]
Ejemplo n.º 14
0
def erdos_renyi_graph(n, p, **kwargs):
    """
    Generate an Erdos-Renyi graph.
    
    **Args**:
         * ``num_nodes`` (int): the number of nodes to populate the graph with.
         * ``p`` (0 <= float <= 1): the probability p given to each edge's existence.
    
    **KwArgs**:
        * ``directed [=False]`` (boolean): indicates whether the network generated is directed.
        * ``self_loops [=False]`` (boolean): indicates whether self-loops are permitted in the generated graph.
        * ``seed [=-1]`` (int): the seed provided to the random generator used to drive the graph construction.
        * ``graph [=None]`` (:py:class:`zen.Graph` or :py:class:`zen.DiGraph`): this is the actual graph instance to populate. It must be
          empty and its directionality must agree with the value of ``directed``.
    """
    directed = kwargs.pop('directed', False)
    self_loops = kwargs.pop('self_loops', False)
    seed = kwargs.pop('seed', None)
    graph = kwargs.pop('graph', None)

    if graph is not None:
        if len(graph) > 0:
            raise NetworkXError('the graph must be empty, if provided')
        if isinstance(graph, DiGraph) != directed:
            raise NetworkXError('graph and directed arguments must agree')
    else:
        if directed:
            graph = DiGraph()
        else:
            graph = Graph()
    if p > 1 or p < 0:
        msg = f"NetworkXError p={p} is not in [0,1]."
        raise NetworkXError(msg)

    if len(kwargs) > 0:
        raise NetworkXError('Unknown arguments: %s' % ', '.join(kwargs.keys()))

    if seed is None:
        seed = -1

    if directed:
        return __erdos_renyi_directed(n, p, self_loops, seed, graph)
    else:
        return __erdos_renyi_undirected(n, p, self_loops, seed, graph)
Ejemplo n.º 15
0
 def add(self, u, v, attr_dict=None, **attr):
     if attr_dict is None:
         attr_dict = attr
     else:
         try:
             attr_dict.update(attr)
         except AttributeError:
             raise NetworkXError(
                 "The attr_dict argument must be a dictionary.")
     return self._add_edge(u, v, attr_dict)
Ejemplo n.º 16
0
 def discard(self, ekeys):
     try:
         u, v = ekeys
     except TypeError:
         raise NetworkXError('bad edge key: use edge key = (u,v)')
     try:
         del self._graph._succ[u][v]
         del self._graph._pred[v][u]
         return True
     except KeyError:
         return False
Ejemplo n.º 17
0
 def __getitem__(self, ekeys):
     try:
         u, v = ekeys
     except TypeError:
         raise NetworkXError('bad edge key: use edge key = (u,v)')
     try:
         return self._mapping[u][v]
     except KeyError:
         if self._graph._directed:
             raise
         return self._graph._pred[u][v]
Ejemplo n.º 18
0
def small_world_graph(n, q, p, graph=None):
    '''
    q must be even
    '''
    if graph is not None and not isinstance(graph, Graph):
        raise NetworkXError('The graph provided must be undirected')
    if graph is not None and len(graph) > 0:
        raise NetworkXError('the graph must be empty, if provided')

    if type(q) != int:
        raise NetworkXError('q must be an integer')
    if q % 2 != 0:
        raise NetworkXError('q must be even')
    if p > 1 or p < 0:
        msg = f"NetworkXError p={p} is not in [0,1]."
        raise NetworkXError(msg)

    G = graph
    if G is None:
        G = Graph()

    for i in range(n):
        G.add_node(i)

    # add the regular edges
    for u in range(n):
        for v in range(u + 1, int(u + 1 + q / 2)):
            v = v % n
            G.add_edge(u, v)

    # add the random edges
    for u in range(n):
        for v in range(u + 1, n):
            if not G.has_edge(u, v):
                if random.random() <= p:
                    G.add_edge(u, v)
    return G
Ejemplo n.º 19
0
 def __init__(self, data=None, **attr):
     self._nodes = nd = {}  # fixme factory
     self._mapping = nd
     self._succ = succ = {}  # fixme factory
     self._pred = pred = {}  # fixme factory
     self._directed = attr.pop("directed", False)
     self._multigraph = attr.pop("multigraph", False)
     if self._multigraph:
         myEdges = MultiEdges
         myAdjacency = MultiAdjacency
         myAtlasUnion = MultiAtlasUnion
     else:
         myEdges = Edges
         myAdjacency = Adjacency
         myAtlasUnion = AtlasUnion
     # Interface
     self.n = Nodes(self)
     self.e = myEdges(self)
     self.a = myAdjacency(myAtlasUnion(self._succ, self._pred))
     if self._directed:
         self.su = myAdjacency(self._succ)
         self.pr = myAdjacency(self._pred)
     else:
         self.su = self.a
         self.pr = self.a
     # graph data attributes
     self.data = attr
     # Handle input
     if data is None:
         return
     if hasattr(data, "_nodes"):
         # new datadicts but with same info (containers in datadicts same)
         self.data.update(data.data)
         for n in data.n:
             self.n.update(data.n.items())
         self.e.update(data.e.items())
     elif len(data) == 2:
         try:
             V,E = data
             self.n.update(V)
             self.e.update(E)
         except:  # something else
             d=self.data.copy()
             convert.to_networkx_graph(data, create_using=self)
             self.data.update(d)
     else:
         msg = ("Graph argument must be a graph "
                "or (V, E)-tuple of nodes and edges.")
         raise NetworkXError(msg)
Ejemplo n.º 20
0
 def _check_vrp(self):
     """Checks if graph is well defined."""
     # if G is not a DiGraph
     if not isinstance(self.G, DiGraph):
         raise TypeError(
             "Input graph must be of type networkx.classes.digraph.DiGraph."
         )
     for v in ["Source", "Sink"]:
         # If Source or Sink is missing
         if v not in self.G.nodes():
             raise KeyError("Input graph requires Source and Sink nodes.")
         # If Source has incoming edges
         if len(list(self.G.predecessors("Source"))) > 0:
             raise NetworkXError("Source must have no incoming edges.")
         # If Sink has outgoing edges
         if len(list(self.G.successors("Sink"))) > 0:
             raise NetworkXError("Sink must have no outgoing edges.")
     # If graph is disconnected
     if not has_path(self.G, "Source", "Sink"):
         raise NetworkXError("Source and Sink are not connected.")
     # If cost is missing
     for (i, j) in self.G.edges():
         if "cost" not in self.G.edges[i, j]:
             raise KeyError("Edge (%s,%s) requires cost attribute" % (i, j))
Ejemplo n.º 21
0
def reciprocity(G, nodes=None):
    """Compute the reciprocity in a directed graph.

    The reciprocity of a directed graph is defined as the ratio
    of the number of edges pointing in both directions to the total
    number of edges in the graph.
    Formally, :math:`r = |{(u,v) \in G|(v,u) \in G}| / |{(u,v) \in G}|`.

    The reciprocity of a single node u is defined similarly,
    it is the ratio of the number of edges in both directions to
    the total number of edges attached to node u.

    Parameters
    ----------
    G : graph
       A networkx directed graph
    nodes : container of nodes, optional (default=None,
            in such case return the reciprocity of the whole graph.)
       Compute reciprocity for nodes in this container.

    Returns
    -------
    out : dictionary
       Reciprocity keyed by node label.

    Notes
    -----
    The reciprocity is not defined for isolated nodes.
    In such cases this function will return None.
    
    """
    # If `nodes` is not specified, calculate the reciprocity of the graph.
    if nodes is None:
        return overall_reciprocity(G)

    # If `nodes` represents a single node in the graph, return only its
    # reciprocity.
    if nodes in G:
        reciprocity = next(_reciprocity_iter(G,nodes))[1]
        if reciprocity is None:
            raise NetworkXError('Not defined for isolated nodes.')
        else:
            return reciprocity

    # Otherwise, `nodes` represents an iterable of nodes, so return a
    # dictionary mapping node to its reciprocity.
    return dict(_reciprocity_iter(G,nodes))
Ejemplo n.º 22
0
def triangles(G, nbunch=None, with_labels=False):
    """Compute the number of triangles.

    Finds the number of triangles that include a node as one of the vertices.

    Parameters
    ----------
    G : graph
       A networkx graph
    nbunch : container of nodes, optional
       Compute triangles for nodes in nbunch. The default is all nodes in G.
    with_labels: bool, optional
        If True return a dictionary keyed by node label.

    Returns
    -------
    out : list or dictionary
       Number of trianges
    
    Examples
    --------
    >>> G=nx.complete_graph(5)
    >>> print nx.triangles(G,0)
    6
    >>> print nx.triangles(G,with_labels=True)
    {0: 6, 1: 6, 2: 6, 3: 6, 4: 6}
    >>> print nx.triangles(G,(0,1))
    [6, 6]

    Notes
    -----
    When computing triangles for the entire graph 
    each triangle is counted three times, once at each node.

    Self loops are ignored.

    """
    if G.is_directed():
        raise NetworkXError("triangles() is not defined for directed graphs.")
    if with_labels:
        return dict(
            (v, t / 2) for v, d, t in _triangles_and_degree_iter(G, nbunch))
    elif nbunch in G:
        return _triangles_and_degree_iter(
            G, nbunch).next()[2] / 2  # return single value
    return [t / 2 for n, d, t in _triangles_and_degree_iter(G, nbunch)]
Ejemplo n.º 23
0
 def add(self, n, attr_dict=None, **attr):
     if attr_dict is None:
         attr_dict = attr
     else:
         try:
             attr_dict.update(attr)
         except AttributeError:
             msg = "The attr_dict argument must be a dictionary."
             raise NetworkXError(msg)
     nodes = self._mapping
     if n not in nodes:
         self._graph._succ[n] = {}  # FIXME factory
         self._graph._pred[n] = {}  # FIXME factory
         nodes[n] = attr_dict
         return True  # new node
     # update attr even if node already exists
     nodes[n].update(attr_dict)
     return False  # not new node
Ejemplo n.º 24
0
def overall_reciprocity(G):
    """Compute the reciprocity for the whole graph.

    See the doc of reciprocity for the definition.

    Parameters
    ----------
    G : graph
       A networkx graph

    """
    n_all_edge = G.number_of_edges()
    n_overlap_edge = (n_all_edge - G.to_undirected().number_of_edges()) * 2

    if n_all_edge == 0:
        raise NetworkXError("Not defined for empty graphs")

    return float(n_overlap_edge) / float(n_all_edge)
Ejemplo n.º 25
0
    def remove_edge(self, u, v, key=None):
        """Remove the edge between u and v.

        Parameters
        ----------
        u,v: nodes 
            Remove edge or edges between nodes u and v.
        key : hashable identifier, optional (default= None)
            Used to distinguish multiedges between a pair of nodes.  
            If None, remove all edges between u and v.

        Raises
        ------
        NetworkXError
            If there is not an edge between u and v.

        See Also
        --------
        remove_edges_from : remove a collection of edges

        Examples
        --------
        >>> G = nx.MultiGraph()   # or MultiDiGraph, etc
        >>> G.add_path([0,1,2,3])
        >>> G.remove_edge(0,1)
        >>> e = (1,2)
        >>> G.remove_edge(*e) # unpacks e from an edge tuple
        >>> G.remove_edge(2,3,key=0) # identify an individual edge with key
        """
        if key is None: 
            super(MultiGraph, self).remove_edge(u,v)
        else:
            try:
                d=self.adj[u][v]
                # remove the edge with specified data
                del d[key]
                if len(d)==0: 
                    # remove the key entries if last edge
                    del self.adj[u][v]
                    if u!=v:  # check for selfloop 
                        del self.adj[v][u]
            except (KeyError,ValueError): 
                raise NetworkXError(
                    "The edge %s-%s with key %s not in the graph."%(u,v,key))
Ejemplo n.º 26
0
def triangles(G, nodes=None):
    """Compute the number of triangles.

    Finds the number of triangles that include a node as one vertex.

    Parameters
    ----------
    G : graph
       A networkx graph
    nodes : container of nodes, optional (default= all nodes in G)
       Compute triangles for nodes in this container. 

    Returns
    -------
    out : dictionary
       Number of triangles keyed by node label.
    
    Examples
    --------
    >>> G=nx.complete_graph(5)
    >>> print(nx.triangles(G,0))
    6
    >>> print(nx.triangles(G))
    {0: 6, 1: 6, 2: 6, 3: 6, 4: 6}
    >>> print(list(nx.triangles(G,(0,1)).values()))
    [6, 6]

    Notes
    -----
    When computing triangles for the entire graph each triangle is counted 
    three times, once at each node.  Self loops are ignored.

    """
    if G.is_directed():
        raise NetworkXError("triangles() is not defined for directed graphs.")
    if nodes in G:
        # return single value
        return next(_triangles_and_degree_iter(G, nodes))[2] // 2
    return dict(
        (v, t // 2) for v, d, t in _triangles_and_degree_iter(G, nodes))
Ejemplo n.º 27
0
    def add_edges_from(self, ebunch_to_add, **attr):
        """Add all the edges in ebunch_to_add.

        Parameters
        ----------
        ebunch_to_add : container of edges
            Each edge given in the container will be added to the
            interval graph. The edges must be given as as 4-tuples (u, v, being, end).
            Both begin and end must be orderable and the same type across all edges.
        attr : keyword arguments, optional
            Edge data (or labels or objects) can be assigned using
            keyword arguments.

        See Also
        --------
        add_edge : add a single edge

        Notes
        -----
        Adding the same edge (with the same interval) twice has no effect
        but any edge data will be updated when each duplicate edge is added.

        Examples
        --------
        >>> G = dnx.IntervalDiGraph()
        >>> G.add_edges_from([(1, 2, 3, 10), (2, 4, 1, 11)]) # using a list of edge tuples

        Associate data to edges

        >>> G.add_edges_from([(1, 2, 3, 10), (2, 4, 1, 11)], weight=3)
        >>> G.add_edges_from([(3, 4, 2, 19), (1, 4, 1, 3)], label='WN2898')
        """

        for e in ebunch_to_add:
            if len(e) != 4:
                raise NetworkXError(
                    "Edge tuple {0} must be a 4-tuple.".format(e))

            self.add_edge(e[0], e[1], e[2], e[3], **attr)
Ejemplo n.º 28
0
 def discard(self, ekeys):
     try:
         u,v,k = ekeys
     except (TypeError, ValueError):
         try:
             u,v = ekeys
         except (TypeError, ValueError):
             raise NetworkXError('bad edge key: %s' % (ekeys,))
         if u in self._graph._succ and v in self._graph._succ[u]:
             keydict = self._graph._succ[u][v]
             keydict.popitem()
             if len(keydict) == 0:
                 del self._graph._succ[u][v]
                 del self._graph._pred[v][u]
             return True
         elif self._graph._directed is False\
                 and v in self._graph._pred\
                 and u in self._graph._pred[v]:
             keydict = self._graph._pred[u][v]
             keydict.popitem()
             if len(keydict) == 0:
                 del self._graph._pred[u][v]
                 del self._graph._succ[v][u]
             return True
         return False  # Didn't remove edge
     try:
         del self._graph._succ[u][v]
         del self._graph._pred[v][u]
         return True
     except KeyError:
         if self._graph._directed is True:
             return False
         try:
             del self._graph._pred[u][v]
             del self._graph._succ[v][u]
             return True
         except KeyError:
             return False
Ejemplo n.º 29
0
 def __getitem__(self, ekeys):
     try:
         u,v,k = ekeys
     except (TypeError, ValueError):
         try:
             u,v = ekeys
             k = None
         except (TypeError, ValueError):
             raise NetworkXError('bad edge key: %s' % (ekeys,))
     if k is None:
         try:
             keydict = self._mapping[u][v]
         except KeyError:
             if self._graph._directed:
                 raise
             keydict = self._graph._pred[u][v]
         k = next(iter(keydict))
         return keydict[k]
     try:
         return self._mapping[u][v][k]
     except KeyError:
         if self._graph._directed:
             raise
         return self._graph._pred[u][v][k]
Ejemplo n.º 30
0
    def remove_edge(self, u, v, key=None):
        """Remove an edge between u and v.

        Parameters
        ----------
        u, v : nodes
            Remove an edge between nodes u and v.
        key : hashable identifier, optional (default=None)
            Used to distinguish multiple edges between a pair of nodes.
            If None remove a single (arbitrary) edge between u and v.

        Raises
        ------
        NetworkXError
            If there is not an edge between u and v, or
            if there is no edge with the specified key.

        See Also
        --------
        remove_edges_from : remove a collection of edges

        Examples
        --------
        >>> G = nx.MultiGraph()
        >>> nx.add_path(G, [0, 1, 2, 3])
        >>> G.remove_edge(0,1)
        >>> e = (1,2)
        >>> G.remove_edge(*e) # unpacks e from an edge tuple

        For multiple edges

        >>> G = nx.MultiGraph()   # or MultiDiGraph, etc
        >>> G.add_edges_from([(1,2),(1,2),(1,2)])
        >>> G.remove_edge(1,2) # remove a single (arbitrary) edge

        For edges with keys

        >>> G = nx.MultiGraph()   # or MultiDiGraph, etc
        >>> G.add_edge(1,2,key='first')
        >>> G.add_edge(1,2,key='second')
        >>> G.remove_edge(1,2,key='second')

        """
        try:
            d = self.adj[u][v]
        except (KeyError):
            raise NetworkXError("The edge %s-%s is not in the graph." % (u, v))
        # remove the edge with specified data
        if key is None:
            d.popitem()
        else:
            try:
                del d[key]
            except (KeyError):
                raise NetworkXError(
                    "The edge %s-%s with key %s is not in the graph." %
                    (u, v, key))
        if len(d) == 0:
            # remove the key entries if last edge
            del self.adj[u][v]
            if u != v:  # check for selfloop
                del self.adj[v][u]