PK _Gídz! z! # networkx-networkx-1.10/gallery.html
Release: | 1.10 |
---|---|
Date: | October 31, 2015 |
Tutorial [PDF]
Reference [PDF]
Tutorial+Reference [HTML zip]
NetworkX is a Python language software package for the creation, manipulation, and study of the structure, dynamics, and function of complex networks.
With NetworkX you can load and store networks in standard and nonstandard data formats, generate many types of random and classic networks, analyze network structure, build network models, design new network algorithms, draw networks, and much more.
The potential audience for NetworkX includes mathematicians, physicists, biologists, computer scientists, and social scientists. Good reviews of the state-of-the-art in the science of complex networks are presented in Albert and Barabási [BA02], Newman [Newman03], and Dorogovtsev and Mendes [DM03]. See also the classic texts [Bollobas01], [Diestel97] and [West01] for graph theoretic results and terminology. For basic graph algorithms, we recommend the texts of Sedgewick, e.g. [Sedgewick01] and [Sedgewick02] and the survey of Brandes and Erlebach [BE05].
NetworkX is intended to provide
Python is a powerful programming language that allows simple and flexible representations of networks, and clear and concise expressions of network algorithms (and other algorithms too). Python has a vibrant and growing ecosystem of packages that NetworkX uses to provide more features such as numerical linear algebra and drawing. In addition Python is also an excellent “glue” language for putting together pieces of software from other languages which allows reuse of legacy code and engineering of high-performance algorithms [Langtangen04].
Equally important, Python is free, well-supported, and a joy to use.
In order to make the most out of NetworkX you will want to know how to write basic programs in Python. Among the many guides to Python, we recommend the documentation at http://www.python.org and the text by Alex Martelli [Martelli03].
NetworkX is free software; you can redistribute it and/or modify it under the terms of the BSD License. We welcome contributions from the community. Information on NetworkX development is found at the NetworkX Developer Zone at Github https://github.com/networkx/networkx
NetworkX was born in May 2002. The original version was designed and written by Aric Hagberg, Dan Schult, and Pieter Swart in 2002 and 2003. The first public release was in April 2005.
Many people have contributed to the success of NetworkX. Some of the contributors are listed in the credits.
- A Brief Tour
- Installing
- Reference
Examples
Source and binary releases: http://cheeseshop.python.org/pypi/networkx/
Github (latest development): https://github.com/networkx/networkx/
Before installing NetworkX, you need to have setuptools installed.
Get NetworkX from the Python Package Index at http://pypi.python.org/pypi/networkx
or install it with
pip install networkx
and an attempt will be made to find and install an appropriate version that matches your operating system and Python version.
You can install the development version (at github.com) with
pip install git://github.com/networkx/networkx.git#egg=networkx
More download file options are at http://networkx.github.io/download.html.
You can install from source by downloading a source archive file (tar.gz or zip) or by checking out the source files from the Mercurial source code repository.
NetworkX is a pure Python package; you don’t need a compiler to build or install it.
- Download the source (tar.gz or zip file) from https://pypi.python.org/pypi/networkx/ or get the latest development version from https://github.com/networkx/networkx/
- Unpack and change directory to the source directory (it should have the files README.txt and setup.py).
- Run
python setup.py install
to build and install- (Optional) Run
nosetests
to execute the tests if you have nose installed.
Clone the networkx repostitory
git clone https://github.com/networkx/networkx.git
(see https://github.com/networkx/networkx/ for other options)
- Change directory to
networkx
- Run
python setup.py install
to build and install- (Optional) Run
nosetests
to execute the tests if you have nose installed.
If you don’t have permission to install software on your
system, you can install into another directory using
the --user
, --prefix
, or --home
flags to setup.py.
For example
python setup.py install --prefix=/home/username/python
or
python setup.py install --home=~
or
python setup.py install --user
If you didn’t install in the standard Python site-packages directory you will need to set your PYTHONPATH variable to the alternate location. See http://docs.python.org/2/install/index.html#search-path for further details.
To use NetworkX you need Python 2.7, 3.2 or later.
The easiest way to get Python and most optional packages is to install the Enthought Python distribution “Canopy”.
There are several other distributions that contain the key packages you need for scientific computing. See http://scipy.org/install.html for a list.
The following are optional packages that NetworkX can use to provide additional functions.
Provides matrix representation of graphs and is used in some graph algorithms for high-performance matrix computations.
- Download: http://scipy.org/Download
Provides sparse matrix representation of graphs and many numerical scientific tools.
- Download: http://scipy.org/Download
In conjunction with either
provides graph drawing and graph layout algorithms.
- Download: http://graphviz.org/
These are extra packages you may consider using with NetworkX
- IPython, interactive Python shell, http://ipython.scipy.org/
Start here to begin working with NetworkX.
Create an empty graph with no nodes and no edges.
>>> import networkx as nx
>>> G=nx.Graph()
By definition, a Graph
is a collection of nodes (vertices)
along with identified pairs of nodes (called edges, links, etc).
In NetworkX, nodes can be any hashable object e.g. a text string, an
image, an XML object, another Graph, a customized node object, etc.
(Note: Python’s None object should not be used as a node as it
determines whether optional function arguments have been assigned
in many functions.)
The graph G can be grown in several ways. NetworkX includes many graph generator functions and facilities to read and write graphs in many formats. To get started though we’ll look at simple manipulations. You can add one node at a time,
>>> G.add_node(1)
add a list of nodes,
>>> G.add_nodes_from([2,3])
or add any nbunch of nodes. An nbunch is any iterable container of nodes that is not itself a node in the graph. (e.g. a list, set, graph, file, etc..)
>>> H=nx.path_graph(10)
>>> G.add_nodes_from(H)
Note that G now contains the nodes of H as nodes of G. In contrast, you could use the graph H as a node in G.
>>> G.add_node(H)
The graph G now contains H as a node. This flexibility is very powerful as it allows graphs of graphs, graphs of files, graphs of functions and much more. It is worth thinking about how to structure your application so that the nodes are useful entities. Of course you can always use a unique identifier in G and have a separate dictionary keyed by identifier to the node information if you prefer. (Note: You should not change the node object if the hash depends on its contents.)
G can also be grown by adding one edge at a time,
>>> G.add_edge(1,2)
>>> e=(2,3)
>>> G.add_edge(*e) # unpack edge tuple*
by adding a list of edges,
>>> G.add_edges_from([(1,2),(1,3)])
or by adding any ebunch of edges. An ebunch is any iterable container of edge-tuples. An edge-tuple can be a 2-tuple of nodes or a 3-tuple with 2 nodes followed by an edge attribute dictionary, e.g. (2,3,{‘weight’:3.1415}). Edge attributes are discussed further below
>>> G.add_edges_from(H.edges())
One can demolish the graph in a similar fashion; using
Graph.remove_node()
,
Graph.remove_nodes_from()
,
Graph.remove_edge()
and
Graph.remove_edges_from()
, e.g.
>>> G.remove_node(H)
There are no complaints when adding existing nodes or edges. For example, after removing all nodes and edges,
>>> G.clear()
we add new nodes/edges and NetworkX quietly ignores any that are already present.
>>> G.add_edges_from([(1,2),(1,3)])
>>> G.add_node(1)
>>> G.add_edge(1,2)
>>> G.add_node("spam") # adds node "spam"
>>> G.add_nodes_from("spam") # adds 4 nodes: 's', 'p', 'a', 'm'
At this stage the graph G consists of 8 nodes and 2 edges, as can be seen by:
>>> G.number_of_nodes()
8
>>> G.number_of_edges()
2
We can examine them with
>>> G.nodes()
['a', 1, 2, 3, 'spam', 'm', 'p', 's']
>>> G.edges()
[(1, 2), (1, 3)]
>>> G.neighbors(1)
[2, 3]
Removing nodes or edges has similar syntax to adding:
>>> G.remove_nodes_from("spam")
>>> G.nodes()
[1, 2, 3, 'spam']
>>> G.remove_edge(1,3)
When creating a graph structure by instantiating one of the graph classes you can specify data in several formats.
>>> H=nx.DiGraph(G) # create a DiGraph using the connections from G
>>> H.edges()
[(1, 2), (2, 1)]
>>> edgelist=[(0,1),(1,2),(2,3)]
>>> H=nx.Graph(edgelist)
You might notice that nodes and edges are not specified as NetworkX objects. This leaves you free to use meaningful items as nodes and edges. The most common choices are numbers or strings, but a node can be any hashable object (except None), and an edge can be associated with any object x using G.add_edge(n1,n2,object=x).
As an example, n1 and n2 could be protein objects from the RCSB Protein Data Bank, and x could refer to an XML record of publications detailing experimental observations of their interaction.
We have found this power quite useful, but its abuse
can lead to unexpected surprises unless one is familiar with Python.
If in doubt, consider using convert_node_labels_to_integers()
to obtain
a more traditional graph with integer labels.
In addition to the methods
Graph.nodes()
,
Graph.edges()
, and
Graph.neighbors()
,
iterator versions (e.g. Graph.edges_iter()
) can save you from
creating large lists when you are just going to iterate
through them anyway.
Fast direct access to the graph data structure is also possible using subscript notation.
Warning
Do not change the returned dict–it is part of the graph data structure and direct manipulation may leave the graph in an inconsistent state.
>>> G[1] # Warning: do not change the resulting dict
{2: {}}
>>> G[1][2]
{}
You can safely set the attributes of an edge using subscript notation if the edge already exists.
>>> G.add_edge(1,3)
>>> G[1][3]['color']='blue'
Fast examination of all edges is achieved using adjacency iterators. Note that for undirected graphs this actually looks at each edge twice.
>>> FG=nx.Graph()
>>> FG.add_weighted_edges_from([(1,2,0.125),(1,3,0.75),(2,4,1.2),(3,4,0.375)])
>>> for n,nbrs in FG.adjacency_iter():
... for nbr,eattr in nbrs.items():
... data=eattr['weight']
... if data<0.5: print('(%d, %d, %.3f)' % (n,nbr,data))
(1, 2, 0.125)
(2, 1, 0.125)
(3, 4, 0.375)
(4, 3, 0.375)
Convenient access to all edges is achieved with the edges method.
>>> for (u,v,d) in FG.edges(data='weight'):
... if d<0.5: print('(%d, %d, %.3f)'%(n,nbr,d))
(1, 2, 0.125)
(3, 4, 0.375)
Attributes such as weights, labels, colors, or whatever Python object you like, can be attached to graphs, nodes, or edges.
Each graph, node, and edge can hold key/value attribute pairs in an associated attribute dictionary (the keys must be hashable). By default these are empty, but attributes can be added or changed using add_edge, add_node or direct manipulation of the attribute dictionaries named G.graph, G.node and G.edge for a graph G.
Assign graph attributes when creating a new graph
>>> G = nx.Graph(day="Friday")
>>> G.graph
{'day': 'Friday'}
Or you can modify attributes later
>>> G.graph['day']='Monday'
>>> G.graph
{'day': 'Monday'}
Add node attributes using add_node(), add_nodes_from() or G.node
>>> G.add_node(1, time='5pm')
>>> G.add_nodes_from([3], time='2pm')
>>> G.node[1]
{'time': '5pm'}
>>> G.node[1]['room'] = 714
>>> G.nodes(data=True)
[(1, {'room': 714, 'time': '5pm'}), (3, {'time': '2pm'})]
Note that adding a node to G.node does not add it to the graph, use G.add_node() to add new nodes.
Add edge attributes using add_edge(), add_edges_from(), subscript notation, or G.edge.
>>> G.add_edge(1, 2, weight=4.7 )
>>> G.add_edges_from([(3,4),(4,5)], color='red')
>>> G.add_edges_from([(1,2,{'color':'blue'}), (2,3,{'weight':8})])
>>> G[1][2]['weight'] = 4.7
>>> G.edge[1][2]['weight'] = 4
The special attribute ‘weight’ should be numeric and holds values used by algorithms requiring weighted edges.
The DiGraph
class provides additional methods specific to directed
edges, e.g.
DiGraph.out_edges()
,
DiGraph.in_degree()
,
DiGraph.predecessors()
,
DiGraph.successors()
etc.
To allow algorithms to work with both classes easily, the directed
versions of neighbors() and degree() are equivalent to successors()
and the sum of in_degree() and out_degree() respectively even though
that may feel inconsistent at times.
>>> DG=nx.DiGraph()
>>> DG.add_weighted_edges_from([(1,2,0.5), (3,1,0.75)])
>>> DG.out_degree(1,weight='weight')
0.5
>>> DG.degree(1,weight='weight')
1.25
>>> DG.successors(1)
[2]
>>> DG.neighbors(1)
[2]
Some algorithms work only for directed graphs and others are not well
defined for directed graphs. Indeed the tendency to lump directed
and undirected graphs together is dangerous. If you want to treat
a directed graph as undirected for some measurement you should probably
convert it using Graph.to_undirected()
or with
>>> H = nx.Graph(G) # convert G to undirected graph
NetworkX provides classes for graphs which allow multiple edges
between any pair of nodes. The MultiGraph
and
MultiDiGraph
classes allow you to add the same edge twice, possibly with different
edge data. This can be powerful for some applications, but many
algorithms are not well defined on such graphs. Shortest path is one
example. Where results are well defined,
e.g. MultiGraph.degree()
we provide the function. Otherwise you
should convert to a standard graph in a way that makes the measurement
well defined.
>>> MG=nx.MultiGraph()
>>> MG.add_weighted_edges_from([(1,2,.5), (1,2,.75), (2,3,.5)])
>>> MG.degree(weight='weight')
{1: 1.25, 2: 1.75, 3: 0.5}
>>> GG=nx.Graph()
>>> for n,nbrs in MG.adjacency_iter():
... for nbr,edict in nbrs.items():
... minvalue=min([d['weight'] for d in edict.values()])
... GG.add_edge(n,nbr, weight = minvalue)
...
>>> nx.shortest_path(GG,1,3)
[1, 2, 3]
In addition to constructing graphs node-by-node or edge-by-edge, they can also be generated by
Applying classic graph operations, such as:
subgraph(G, nbunch) - induce subgraph of G on nodes in nbunch
union(G1,G2) - graph union
disjoint_union(G1,G2) - graph union assuming all nodes are different
cartesian_product(G1,G2) - return Cartesian product graph
compose(G1,G2) - combine graphs identifying nodes common to both
complement(G) - graph complement
create_empty_copy(G) - return an empty copy of the same graph class
convert_to_undirected(G) - return an undirected representation of G
convert_to_directed(G) - return a directed representation of G
Using a call to one of the classic small graphs, e.g.
>>> petersen=nx.petersen_graph()
>>> tutte=nx.tutte_graph()
>>> maze=nx.sedgewick_maze_graph()
>>> tet=nx.tetrahedral_graph()
>>> K_5=nx.complete_graph(5)
>>> K_3_5=nx.complete_bipartite_graph(3,5)
>>> barbell=nx.barbell_graph(10,10)
>>> lollipop=nx.lollipop_graph(10,20)
>>> er=nx.erdos_renyi_graph(100,0.15)
>>> ws=nx.watts_strogatz_graph(30,3,0.1)
>>> ba=nx.barabasi_albert_graph(100,5)
>>> red=nx.random_lobster(100,0.9,0.9)
>>> nx.write_gml(red,"path.to.file")
>>> mygraph=nx.read_gml("path.to.file")
Details on graph formats: Reading and writing graphs
Details on graph generator functions: Graph generators
The structure of G can be analyzed using various graph-theoretic functions such as:
>>> G=nx.Graph()
>>> G.add_edges_from([(1,2),(1,3)])
>>> G.add_node("spam") # adds node "spam"
>>> nx.connected_components(G)
[[1, 2, 3], ['spam']]
>>> sorted(nx.degree(G).values())
[0, 1, 1, 2]
>>> nx.clustering(G)
{1: 0.0, 2: 0.0, 3: 0.0, 'spam': 0.0}
Functions that return node properties return dictionaries keyed by node label.
>>> nx.degree(G)
{1: 2, 2: 1, 3: 1, 'spam': 0}
For values of specific nodes, you can provide a single node or an nbunch of nodes as argument. If a single node is specified, then a single value is returned. If an nbunch is specified, then the function will return a dictionary.
>>> nx.degree(G,1)
2
>>> G.degree(1)
2
>>> G.degree([1,2])
{1: 2, 2: 1}
>>> sorted(G.degree([1,2]).values())
[1, 2]
>>> sorted(G.degree().values())
[0, 1, 1, 2]
Details on graph algorithms supported: Algorithms
NetworkX is not primarily a graph drawing package but basic drawing with Matplotlib as well as an interface to use the open source Graphviz software package are included. These are part of the networkx.drawing package and will be imported if possible. See Drawing for details.
Note that the drawing package in NetworkX is not yet compatible with Python versions 3.0 and above.
First import Matplotlib’s plot interface (pylab works too)
>>> import matplotlib.pyplot as plt
You may find it useful to interactively test code using “ipython -pylab”, which combines the power of ipython and matplotlib and provides a convenient interactive mode.
To test if the import of networkx.drawing was successful draw G using one of
>>> nx.draw(G)
>>> nx.draw_random(G)
>>> nx.draw_circular(G)
>>> nx.draw_spectral(G)
when drawing to an interactive display. Note that you may need to issue a Matplotlib
>>> plt.show()
command if you are not using matplotlib in interactive mode: (See Matplotlib FAQ )
To save drawings to a file, use, for example
>>> nx.draw(G)
>>> plt.savefig("path.png")
writes to the file “path.png” in the local directory. If Graphviz and PyGraphviz, or pydot, are available on your system, you can also use
>>> nx.draw_graphviz(G)
>>> nx.write_dot(G,'file.dot')
Details on drawing graphs: Drawing
What Next
Now that you have an idea of what the NetworkX package provides, you should investigate the parts of the package most useful for you.
Reference Section provides details on NetworkX.
/examples/index
provides some example programs written using NetworkX.
Release: 1.10 Date: October 31, 2015
NetworkX provides data structures for graphs (or networks) along with graph algorithms, generators, and drawing tools.
The structure of NetworkX can be seen by the organization of its source code. The package provides classes for graph objects, generators to create standard graphs, IO routines for reading in existing datasets, algorithms to analyse the resulting networks and some basic drawing tools.
Most of the NetworkX API is provided by functions which take a graph object as an argument. Methods of the graph object are limited to basic manipulation and reporting. This provides modularity of code and documentation. It also makes it easier for newcomers to learn about the package in stages. The source code for each module is meant to be easy to read and reading this Python code is actually a good way to learn more about network algorithms, but we have put a lot of effort into making the documentation sufficient and friendly. If you have suggestions or questions please contact us by joining the NetworkX Google group.
Classes are named using CamelCase (capital letters at the start of each word). functions, methods and variable names are lower_case_underscore (lowercase with an underscore representing a space between words).
After starting Python, import the networkx module with (the recommended way)
>>> import networkx as nx
To save repetition, in the documentation we assume that NetworkX has been imported this way.
If importing networkx fails, it means that Python cannot find the installed module. Check your installation and your PYTHONPATH.
The following basic graph types are provided as Python classes:
Graph
DiGraph
MultiGraph
MultiDiGraph
Empty graph-like objects are created with
>>> G=nx.Graph()
>>> G=nx.DiGraph()
>>> G=nx.MultiGraph()
>>> G=nx.MultiDiGraph()
All graph classes allow any hashable object as a node. Hashable objects include strings, tuples, integers, and more. Arbitrary edge attributes such as weights and labels can be associated with an edge.
The graph internal data structures are based on an adjacency list representation and implemented using Python dictionary datastructures. The graph adjaceny structure is implemented as a Python dictionary of dictionaries; the outer dictionary is keyed by nodes to values that are themselves dictionaries keyed by neighboring node to the edge attributes associated with that edge. This “dict-of-dicts” structure allows fast addition, deletion, and lookup of nodes and neighbors in large graphs. The underlying datastructure is accessed directly by methods (the programming interface “API”) in the class definitions. All functions, on the other hand, manipulate graph-like objects solely via those API methods and not by acting directly on the datastructure. This design allows for possible replacement of the ‘dicts-of-dicts’-based datastructure with an alternative datastructure that implements the same methods.
The first choice to be made when using NetworkX is what type of graph object to use. A graph (network) is a collection of nodes together with a collection of edges that are pairs of nodes. Attributes are often associated with nodes and/or edges. NetworkX graph objects come in different flavors depending on two main properties of the network:
- Directed: Are the edges directed? Does the order of the edge pairs (u,v) matter? A directed graph is specified by the “Di” prefix in the class name, e.g. DiGraph(). We make this distinction because many classical graph properties are defined differently for directed graphs.
- Multi-edges: Are multiple edges allowed between each pair of nodes? As you might imagine, multiple edges requires a different data structure, though tricky users could design edge data objects to support this functionality. We provide a standard data structure and interface for this type of graph using the prefix “Multi”, e.g. MultiGraph().
The basic graph classes are named: Graph, DiGraph, MultiGraph, and MultiDiGraph
The next choice you have to make when specifying a graph is what kinds of nodes and edges to use.
If the topology of the network is all you care about then using integers or strings as the nodes makes sense and you need not worry about edge data. If you have a data structure already in place to describe nodes you can simply use that structure as your nodes provided it is hashable. If it is not hashable you can use a unique identifier to represent the node and assign the data as a node attribute.
Edges often have data associated with them. Arbitrary data can associated with edges as an edge attribute. If the data is numeric and the intent is to represent a weighted graph then use the ‘weight’ keyword for the attribute. Some of the graph algorithms, such as Dijkstra’s shortest path algorithm, use this attribute name to get the weight for each edge.
Other attributes can be assigned to an edge by using keyword/value pairs when adding edges. You can use any keyword except ‘weight’ to name your attribute and can then easily query the edge data by that attribute keyword.
Once you’ve decided how to encode the nodes and edges, and whether you have an undirected/directed graph with or without multiedges you are ready to build your network.
NetworkX graph objects can be created in one of three ways:
Explicit addition and removal of nodes/edges is the easiest to describe. Each graph object supplies methods to manipulate the graph. For example,
>>> import networkx as nx
>>> G=nx.Graph()
>>> G.add_edge(1,2) # default edge data=1
>>> G.add_edge(2,3,weight=0.9) # specify edge data
Edge attributes can be anything:
>>> import math
>>> G.add_edge('y','x',function=math.cos)
>>> G.add_node(math.cos) # any hashable can be a node
You can add many edges at one time:
>>> elist=[('a','b',5.0),('b','c',3.0),('a','c',1.0),('c','d',7.3)]
>>> G.add_weighted_edges_from(elist)
See the Tutorial for more examples.
Some basic graph operations such as union and intersection are described in the Operators module documentation.
Graph generators such as binomial_graph and powerlaw_graph are provided in the Graph generators subpackage.
For importing network data from formats such as GML, GraphML, edge list text files see the Reading and writing graphs subpackage.
Class methods are used for the basic reporting functions neighbors, edges and degree. Reporting of lists is often needed only to iterate through that list so we supply iterator versions of many property reporting methods. For example edges() and nodes() have corresponding methods edges_iter() and nodes_iter(). Using these methods when you can will save memory and often time as well.
The basic graph relationship of an edge can be obtained in two basic ways. One can look for neighbors of a node or one can look for edges incident to a node. We jokingly refer to people who focus on nodes/neighbors as node-centric and people who focus on edges as edge-centric. The designers of NetworkX tend to be node-centric and view edges as a relationship between nodes. You can see this by our avoidance of notation like G[u,v] in favor of G[u][v]. Most data structures for sparse graphs are essentially adjacency lists and so fit this perspective. In the end, of course, it doesn’t really matter which way you examine the graph. G.edges() removes duplicate representations of each edge while G.neighbors(n) or G[n] is slightly faster but doesn’t remove duplicates.
Any properties that are more complicated than edges, neighbors and degree are provided by functions. For example nx.triangles(G,n) gives the number of triangles which include node n as a vertex. These functions are grouped in the code and documentation under the term algorithms.
A number of graph algorithms are provided with NetworkX. These include shortest path, and breadth first search (see traversal), clustering and isomorphism algorithms and others. There are many that we have not developed yet too. If you implement a graph algorithm that might be useful for others please let us know through the NetworkX Google group or the Github Developer Zone.
As an example here is code to use Dijkstra’s algorithm to find the shortest weighted path:
>>> G=nx.Graph()
>>> e=[('a','b',0.3),('b','c',0.9),('a','c',0.5),('c','d',1.2)]
>>> G.add_weighted_edges_from(e)
>>> print(nx.dijkstra_path(G,'a','d'))
['a', 'c', 'd']
While NetworkX is not designed as a network layout tool, we provide a simple interface to drawing packages and some simple layout algorithms. We interface to the excellent Graphviz layout tools like dot and neato with the (suggested) pygraphviz package or the pydot interface. Drawing can be done using external programs or the Matplotlib Python package. Interactive GUI interfaces are possible though not provided. The drawing tools are provided in the module drawing.
The basic drawing functions essentially place the nodes on a scatterplot using the positions in a dictionary or computed with a layout function. The edges are then lines between those dots.
>>> G=nx.cubical_graph()
>>> nx.draw(G) # default spring_layout
>>> nx.draw(G,pos=nx.spectral_layout(G), nodecolor='r',edge_color='b')
See the
examples
for more ideas.
NetworkX uses a “dictionary of dictionaries of dictionaries” as the basic network data structure. This allows fast lookup with reasonable storage for large sparse networks. The keys are nodes so G[u] returns an adjacency dictionary keyed by neighbor to the edge attribute dictionary. The expression G[u][v] returns the edge attribute dictionary itself. A dictionary of lists would have also been possible, but not allowed fast edge detection nor convenient storage of edge data.
Advantages of dict-of-dicts-of-dicts data structure:
- Find edges and remove edges with two dictionary look-ups.
- Prefer to “lists” because of fast lookup with sparse storage.
- Prefer to “sets” since data can be attached to edge.
- G[u][v] returns the edge attribute dictionary.
n in G
tests if noden
is in graph G.for n in G:
iterates through the graph.for nbr in G[n]:
iterates through neighbors.
As an example, here is a representation of an undirected graph with the edges (‘A’,’B’), (‘B’,’C’)
>>> G=nx.Graph()
>>> G.add_edge('A','B')
>>> G.add_edge('B','C')
>>> print(G.adj)
{'A': {'B': {}}, 'C': {'B': {}}, 'B': {'A': {}, 'C': {}}}
The data structure gets morphed slightly for each base graph class. For DiGraph two dict-of-dicts-of-dicts structures are provided, one for successors and one for predecessors. For MultiGraph/MultiDiGraph we use a dict-of-dicts-of-dicts-of-dicts [1] where the third dictionary is keyed by an edge key identifier to the fourth dictionary which contains the edge attributes for that edge between the two nodes.
Graphs use a dictionary of attributes for each edge. We use a dict-of-dicts-of-dicts data structure with the inner dictionary storing “name-value” relationships for that edge.
>>> G=nx.Graph()
>>> G.add_edge(1,2,color='red',weight=0.84,size=300)
>>> print(G[1][2]['size'])
300
Footnotes
[1] | “It’s dictionaries all the way down.” |
NetworkX provides data structures and methods for storing graphs.
All NetworkX graph classes allow (hashable) Python objects as nodes. and any Python object can be assigned as an edge attribute.
The choice of graph class depends on the structure of the graph you want to represent.
Graph Type | NetworkX Class |
---|---|
Undirected Simple | Graph |
Directed Simple | DiGraph |
With Self-loops | Graph, DiGraph |
With Parallel edges | MultiGraph, MultiDiGraph |
Graph
(data=None, **attr)[source]¶Base class for undirected graphs.
A Graph stores nodes and edges with optional data, or attributes.
Graphs hold undirected edges. Self loops are allowed but multiple (parallel) edges are not.
Nodes can be arbitrary (hashable) Python objects with optional key/value attributes.
Edges are represented as links between nodes with optional key/value attributes.
Parameters: |
|
---|
See also
Examples
Create an empty graph structure (a “null graph”) with no nodes and no edges.
>>> G = nx.Graph()
G can be grown in several ways.
Nodes:
Add one node at a time:
>>> G.add_node(1)
Add the nodes from any container (a list, dict, set or even the lines from a file or the nodes from another graph).
>>> G.add_nodes_from([2,3])
>>> G.add_nodes_from(range(100,110))
>>> H=nx.Graph()
>>> H.add_path([0,1,2,3,4,5,6,7,8,9])
>>> G.add_nodes_from(H)
In addition to strings and integers any hashable Python object (except None) can represent a node, e.g. a customized node object, or even another Graph.
>>> G.add_node(H)
Edges:
G can also be grown by adding edges.
Add one edge,
>>> G.add_edge(1, 2)
a list of edges,
>>> G.add_edges_from([(1,2),(1,3)])
or a collection of edges,
>>> G.add_edges_from(H.edges())
If some edges connect nodes not yet in the graph, the nodes are added automatically. There are no errors when adding nodes or edges that already exist.
Attributes:
Each graph, node, and edge can hold key/value attribute pairs in an associated attribute dictionary (the keys must be hashable). By default these are empty, but can be added or changed using add_edge, add_node or direct manipulation of the attribute dictionaries named graph, node and edge respectively.
>>> G = nx.Graph(day="Friday")
>>> G.graph
{'day': 'Friday'}
Add node attributes using add_node(), add_nodes_from() or G.node
>>> G.add_node(1, time='5pm')
>>> G.add_nodes_from([3], time='2pm')
>>> G.node[1]
{'time': '5pm'}
>>> G.node[1]['room'] = 714
>>> del G.node[1]['room'] # remove attribute
>>> G.nodes(data=True)
[(1, {'time': '5pm'}), (3, {'time': '2pm'})]
Warning: adding a node to G.node does not add it to the graph.
Add edge attributes using add_edge(), add_edges_from(), subscript notation, or G.edge.
>>> G.add_edge(1, 2, weight=4.7 )
>>> G.add_edges_from([(3,4),(4,5)], color='red')
>>> G.add_edges_from([(1,2,{'color':'blue'}), (2,3,{'weight':8})])
>>> G[1][2]['weight'] = 4.7
>>> G.edge[1][2]['weight'] = 4
Shortcuts:
Many common graph features allow python syntax to speed reporting.
>>> 1 in G # check if node in graph
True
>>> [n for n in G if n<3] # iterate through nodes
[1, 2]
>>> len(G) # number of nodes in graph
5
The fastest way to traverse all edges of a graph is via adjacency_iter(), but the edges() method is often more convenient.
>>> for n,nbrsdict in G.adjacency_iter():
... for nbr,eattr in nbrsdict.items():
... if 'weight' in eattr:
... (n,nbr,eattr['weight'])
(1, 2, 4)
(2, 1, 4)
(2, 3, 8)
(3, 2, 8)
>>> G.edges(data='weight')
[(1, 2, 4), (2, 3, 8), (3, 4, None), (4, 5, None)]
Reporting:
Simple graph information is obtained using methods. Iterator versions of many reporting methods exist for efficiency. Methods exist for reporting nodes(), edges(), neighbors() and degree() as well as the number of nodes and edges.
For details on these and other miscellaneous methods, see below.
Subclasses (Advanced):
The Graph class uses a dict-of-dict-of-dict data structure. The outer dict (node_dict) holds adjacency lists keyed by node. The next dict (adjlist) represents the adjacency list and holds edge data keyed by neighbor. The inner dict (edge_attr) represents the edge data and holds edge attribute values keyed by attribute names.
Each of these three dicts can be replaced by a user defined dict-like object. In general, the dict-like features should be maintained but extra features can be added. To replace one of the dicts create a new graph class by changing the class(!) variable holding the factory for that dict-like structure. The variable names are node_dict_factory, adjlist_dict_factory and edge_attr_dict_factory.
Examples
Create a graph object that tracks the order nodes are added.
>>> from collections import OrderedDict
>>> class OrderedNodeGraph(nx.Graph):
... node_dict_factory=OrderedDict
>>> G=OrderedNodeGraph()
>>> G.add_nodes_from( (2,1) )
>>> G.nodes()
[2, 1]
>>> G.add_edges_from( ((2,2), (2,1), (1,1)) )
>>> G.edges()
[(2, 1), (2, 2), (1, 1)]
Create a graph object that tracks the order nodes are added and for each node track the order that neighbors are added.
>>> class OrderedGraph(nx.Graph):
... node_dict_factory = OrderedDict
... adjlist_dict_factory = OrderedDict
>>> G = OrderedGraph()
>>> G.add_nodes_from( (2,1) )
>>> G.nodes()
[2, 1]
>>> G.add_edges_from( ((2,2), (2,1), (1,1)) )
>>> G.edges()
[(2, 2), (2, 1), (1, 1)]
Create a low memory graph class that effectively disallows edge attributes by using a single attribute dict for all edges. This reduces the memory used, but you lose edge attributes.
>>> class ThinGraph(nx.Graph):
... all_edge_dict = {'weight': 1}
... def single_edge_dict(self):
... return self.all_edge_dict
... edge_attr_dict_factory = single_edge_dict
>>> G = ThinGraph()
>>> G.add_edge(2,1)
>>> G.edges(data= True)
[(1, 2, {'weight': 1})]
>>> G.add_edge(2,2)
>>> G[2][1] is G[2][2]
True
Graph.__init__ ([data]) |
Initialize a graph with edges, name, graph attributes. |
Graph.add_node (n[, attr_dict]) |
Add a single node n and update node attributes. |
Graph.add_nodes_from (nodes, **attr) |
Add multiple nodes. |
Graph.remove_node (n) |
Remove node n. |
Graph.remove_nodes_from (nodes) |
Remove multiple nodes. |
Graph.add_edge (u, v[, attr_dict]) |
Add an edge between u and v. |
Graph.add_edges_from (ebunch[, attr_dict]) |
Add all the edges in ebunch. |
Graph.add_weighted_edges_from (ebunch[, weight]) |
Add all the edges in ebunch as weighted edges with specified weights. |
Graph.remove_edge (u, v) |
Remove the edge between u and v. |
Graph.remove_edges_from (ebunch) |
Remove all edges specified in ebunch. |
Graph.add_star (nodes, **attr) |
Add a star. |
Graph.add_path (nodes, **attr) |
Add a path. |
Graph.add_cycle (nodes, **attr) |
Add a cycle. |
Graph.clear () |
Remove all nodes and edges from the graph. |
Graph.nodes ([data]) |
Return a list of the nodes in the graph. |
Graph.nodes_iter ([data]) |
Return an iterator over the nodes. |
Graph.__iter__ () |
Iterate over the nodes. |
Graph.edges ([nbunch, data, default]) |
Return a list of edges. |
Graph.edges_iter ([nbunch, data, default]) |
Return an iterator over the edges. |
Graph.get_edge_data (u, v[, default]) |
Return the attribute dictionary associated with edge (u,v). |
Graph.neighbors (n) |
Return a list of the nodes connected to the node n. |
Graph.neighbors_iter (n) |
Return an iterator over all neighbors of node n. |
Graph.__getitem__ (n) |
Return a dict of neighbors of node n. |
Graph.adjacency_list () |
Return an adjacency list representation of the graph. |
Graph.adjacency_iter () |
Return an iterator of (node, adjacency dict) tuples for all nodes. |
Graph.nbunch_iter ([nbunch]) |
Return an iterator of nodes contained in nbunch that are also in the graph. |
Graph.has_node (n) |
Return True if the graph contains the node n. |
Graph.__contains__ (n) |
Return True if n is a node, False otherwise. |
Graph.has_edge (u, v) |
Return True if the edge (u,v) is in the graph. |
Graph.order () |
Return the number of nodes in the graph. |
Graph.number_of_nodes () |
Return the number of nodes in the graph. |
Graph.__len__ () |
Return the number of nodes. |
Graph.degree ([nbunch, weight]) |
Return the degree of a node or nodes. |
Graph.degree_iter ([nbunch, weight]) |
Return an iterator for (node, degree). |
Graph.size ([weight]) |
Return the number of edges. |
Graph.number_of_edges ([u, v]) |
Return the number of edges between two nodes. |
Graph.nodes_with_selfloops () |
Return a list of nodes with self loops. |
Graph.selfloop_edges ([data, default]) |
Return a list of selfloop edges. |
Graph.number_of_selfloops () |
Return the number of selfloop edges. |
Graph.copy () |
Return a copy of the graph. |
Graph.to_undirected () |
Return an undirected copy of the graph. |
Graph.to_directed () |
Return a directed representation of the graph. |
Graph.subgraph (nbunch) |
Return the subgraph induced on nodes in nbunch. |
DiGraph
(data=None, **attr)[source]¶Base class for directed graphs.
A DiGraph stores nodes and edges with optional data, or attributes.
DiGraphs hold directed edges. Self loops are allowed but multiple (parallel) edges are not.
Nodes can be arbitrary (hashable) Python objects with optional key/value attributes.
Edges are represented as links between nodes with optional key/value attributes.
Parameters: |
|
---|
See also
Examples
Create an empty graph structure (a “null graph”) with no nodes and no edges.
>>> G = nx.DiGraph()
G can be grown in several ways.
Nodes:
Add one node at a time:
>>> G.add_node(1)
Add the nodes from any container (a list, dict, set or even the lines from a file or the nodes from another graph).
>>> G.add_nodes_from([2,3])
>>> G.add_nodes_from(range(100,110))
>>> H=nx.Graph()
>>> H.add_path([0,1,2,3,4,5,6,7,8,9])
>>> G.add_nodes_from(H)
In addition to strings and integers any hashable Python object (except None) can represent a node, e.g. a customized node object, or even another Graph.
>>> G.add_node(H)
Edges:
G can also be grown by adding edges.
Add one edge,
>>> G.add_edge(1, 2)
a list of edges,
>>> G.add_edges_from([(1,2),(1,3)])
or a collection of edges,
>>> G.add_edges_from(H.edges())
If some edges connect nodes not yet in the graph, the nodes are added automatically. There are no errors when adding nodes or edges that already exist.
Attributes:
Each graph, node, and edge can hold key/value attribute pairs in an associated attribute dictionary (the keys must be hashable). By default these are empty, but can be added or changed using add_edge, add_node or direct manipulation of the attribute dictionaries named graph, node and edge respectively.
>>> G = nx.DiGraph(day="Friday")
>>> G.graph
{'day': 'Friday'}
Add node attributes using add_node(), add_nodes_from() or G.node
>>> G.add_node(1, time='5pm')
>>> G.add_nodes_from([3], time='2pm')
>>> G.node[1]
{'time': '5pm'}
>>> G.node[1]['room'] = 714
>>> del G.node[1]['room'] # remove attribute
>>> G.nodes(data=True)
[(1, {'time': '5pm'}), (3, {'time': '2pm'})]
Warning: adding a node to G.node does not add it to the graph.
Add edge attributes using add_edge(), add_edges_from(), subscript notation, or G.edge.
>>> G.add_edge(1, 2, weight=4.7 )
>>> G.add_edges_from([(3,4),(4,5)], color='red')
>>> G.add_edges_from([(1,2,{'color':'blue'}), (2,3,{'weight':8})])
>>> G[1][2]['weight'] = 4.7
>>> G.edge[1][2]['weight'] = 4
Shortcuts:
Many common graph features allow python syntax to speed reporting.
>>> 1 in G # check if node in graph
True
>>> [n for n in G if n<3] # iterate through nodes
[1, 2]
>>> len(G) # number of nodes in graph
5
The fastest way to traverse all edges of a graph is via adjacency_iter(), but the edges() method is often more convenient.
>>> for n,nbrsdict in G.adjacency_iter():
... for nbr,eattr in nbrsdict.items():
... if 'weight' in eattr:
... (n,nbr,eattr['weight'])
(1, 2, 4)
(2, 3, 8)
>>> G.edges(data='weight')
[(1, 2, 4), (2, 3, 8), (3, 4, None), (4, 5, None)]
Reporting:
Simple graph information is obtained using methods. Iterator versions of many reporting methods exist for efficiency. Methods exist for reporting nodes(), edges(), neighbors() and degree() as well as the number of nodes and edges.
For details on these and other miscellaneous methods, see below.
Subclasses (Advanced):
The Graph class uses a dict-of-dict-of-dict data structure. The outer dict (node_dict) holds adjacency lists keyed by node. The next dict (adjlist) represents the adjacency list and holds edge data keyed by neighbor. The inner dict (edge_attr) represents the edge data and holds edge attribute values keyed by attribute names.
Each of these three dicts can be replaced by a user defined dict-like object. In general, the dict-like features should be maintained but extra features can be added. To replace one of the dicts create a new graph class by changing the class(!) variable holding the factory for that dict-like structure. The variable names are node_dict_factory, adjlist_dict_factory and edge_attr_dict_factory.
Examples
Create a graph object that tracks the order nodes are added.
>>> from collections import OrderedDict
>>> class OrderedNodeGraph(nx.Graph):
... node_dict_factory=OrderedDict
>>> G=OrderedNodeGraph()
>>> G.add_nodes_from( (2,1) )
>>> G.nodes()
[2, 1]
>>> G.add_edges_from( ((2,2), (2,1), (1,1)) )
>>> G.edges()
[(2, 1), (2, 2), (1, 1)]
Create a graph object that tracks the order nodes are added and for each node track the order that neighbors are added.
>>> class OrderedGraph(nx.Graph):
... node_dict_factory = OrderedDict
... adjlist_dict_factory = OrderedDict
>>> G = OrderedGraph()
>>> G.add_nodes_from( (2,1) )
>>> G.nodes()
[2, 1]
>>> G.add_edges_from( ((2,2), (2,1), (1,1)) )
>>> G.edges()
[(2, 2), (2, 1), (1, 1)]
Create a low memory graph class that effectively disallows edge attributes by using a single attribute dict for all edges. This reduces the memory used, but you lose edge attributes.
>>> class ThinGraph(nx.Graph):
... all_edge_dict = {'weight': 1}
... def single_edge_dict(self):
... return self.all_edge_dict
... edge_attr_dict_factory = single_edge_dict
>>> G = ThinGraph()
>>> G.add_edge(2,1)
>>> G.edges(data= True)
[(1, 2, {'weight': 1})]
>>> G.add_edge(2,2)
>>> G[2][1] is G[2][2]
True
DiGraph.__init__ ([data]) |
Initialize a graph with edges, name, graph attributes. |
DiGraph.add_node (n[, attr_dict]) |
Add a single node n and update node attributes. |
DiGraph.add_nodes_from (nodes, **attr) |
Add multiple nodes. |
DiGraph.remove_node (n) |
Remove node n. |
DiGraph.remove_nodes_from (nbunch) |
Remove multiple nodes. |
DiGraph.add_edge (u, v[, attr_dict]) |
Add an edge between u and v. |
DiGraph.add_edges_from (ebunch[, attr_dict]) |
Add all the edges in ebunch. |
DiGraph.add_weighted_edges_from (ebunch[, weight]) |
Add all the edges in ebunch as weighted edges with specified weights. |
DiGraph.remove_edge (u, v) |
Remove the edge between u and v. |
DiGraph.remove_edges_from (ebunch) |
Remove all edges specified in ebunch. |
DiGraph.add_star (nodes, **attr) |
Add a star. |
DiGraph.add_path (nodes, **attr) |
Add a path. |
DiGraph.add_cycle (nodes, **attr) |
Add a cycle. |
DiGraph.clear () |
Remove all nodes and edges from the graph. |
DiGraph.nodes ([data]) |
Return a list of the nodes in the graph. |
DiGraph.nodes_iter ([data]) |
Return an iterator over the nodes. |
DiGraph.__iter__ () |
Iterate over the nodes. |
DiGraph.edges ([nbunch, data, default]) |
Return a list of edges. |
DiGraph.edges_iter ([nbunch, data, default]) |
Return an iterator over the edges. |
DiGraph.out_edges ([nbunch, data, default]) |
Return a list of edges. |
DiGraph.out_edges_iter ([nbunch, data, default]) |
Return an iterator over the edges. |
DiGraph.in_edges ([nbunch, data]) |
Return a list of the incoming edges. |
DiGraph.in_edges_iter ([nbunch, data]) |
Return an iterator over the incoming edges. |
DiGraph.get_edge_data (u, v[, default]) |
Return the attribute dictionary associated with edge (u,v). |
DiGraph.neighbors (n) |
Return a list of successor nodes of n. |
DiGraph.neighbors_iter (n) |
Return an iterator over successor nodes of n. |
DiGraph.__getitem__ (n) |
Return a dict of neighbors of node n. |
DiGraph.successors (n) |
Return a list of successor nodes of n. |
DiGraph.successors_iter (n) |
Return an iterator over successor nodes of n. |
DiGraph.predecessors (n) |
Return a list of predecessor nodes of n. |
DiGraph.predecessors_iter (n) |
Return an iterator over predecessor nodes of n. |
DiGraph.adjacency_list () |
Return an adjacency list representation of the graph. |
DiGraph.adjacency_iter () |
Return an iterator of (node, adjacency dict) tuples for all nodes. |
DiGraph.nbunch_iter ([nbunch]) |
Return an iterator of nodes contained in nbunch that are also in the graph. |
DiGraph.has_node (n) |
Return True if the graph contains the node n. |
DiGraph.__contains__ (n) |
Return True if n is a node, False otherwise. |
DiGraph.has_edge (u, v) |
Return True if the edge (u,v) is in the graph. |
DiGraph.order () |
Return the number of nodes in the graph. |
DiGraph.number_of_nodes () |
Return the number of nodes in the graph. |
DiGraph.__len__ () |
Return the number of nodes. |
DiGraph.degree ([nbunch, weight]) |
Return the degree of a node or nodes. |
DiGraph.degree_iter ([nbunch, weight]) |
Return an iterator for (node, degree). |
DiGraph.in_degree ([nbunch, weight]) |
Return the in-degree of a node or nodes. |
DiGraph.in_degree_iter ([nbunch, weight]) |
Return an iterator for (node, in-degree). |
DiGraph.out_degree ([nbunch, weight]) |
Return the out-degree of a node or nodes. |
DiGraph.out_degree_iter ([nbunch, weight]) |
Return an iterator for (node, out-degree). |
DiGraph.size ([weight]) |
Return the number of edges. |
DiGraph.number_of_edges ([u, v]) |
Return the number of edges between two nodes. |
DiGraph.nodes_with_selfloops () |
Return a list of nodes with self loops. |
DiGraph.selfloop_edges ([data, default]) |
Return a list of selfloop edges. |
DiGraph.number_of_selfloops () |
Return the number of selfloop edges. |
DiGraph.copy () |
Return a copy of the graph. |
DiGraph.to_undirected ([reciprocal]) |
Return an undirected representation of the digraph. |
DiGraph.to_directed () |
Return a directed copy of the graph. |
DiGraph.subgraph (nbunch) |
Return the subgraph induced on nodes in nbunch. |
DiGraph.reverse ([copy]) |
Return the reverse of the graph. |
MultiGraph
(data=None, **attr)[source]¶An undirected graph class that can store multiedges.
Multiedges are multiple edges between two nodes. Each edge can hold optional data or attributes.
A MultiGraph holds undirected edges. Self loops are allowed.
Nodes can be arbitrary (hashable) Python objects with optional key/value attributes.
Edges are represented as links between nodes with optional key/value attributes.
Parameters: |
|
---|
See also
Examples
Create an empty graph structure (a “null graph”) with no nodes and no edges.
>>> G = nx.MultiGraph()
G can be grown in several ways.
Nodes:
Add one node at a time:
>>> G.add_node(1)
Add the nodes from any container (a list, dict, set or even the lines from a file or the nodes from another graph).
>>> G.add_nodes_from([2,3])
>>> G.add_nodes_from(range(100,110))
>>> H=nx.Graph()
>>> H.add_path([0,1,2,3,4,5,6,7,8,9])
>>> G.add_nodes_from(H)
In addition to strings and integers any hashable Python object (except None) can represent a node, e.g. a customized node object, or even another Graph.
>>> G.add_node(H)
Edges:
G can also be grown by adding edges.
Add one edge,
>>> G.add_edge(1, 2)
a list of edges,
>>> G.add_edges_from([(1,2),(1,3)])
or a collection of edges,
>>> G.add_edges_from(H.edges())
If some edges connect nodes not yet in the graph, the nodes are added automatically. If an edge already exists, an additional edge is created and stored using a key to identify the edge. By default the key is the lowest unused integer.
>>> G.add_edges_from([(4,5,dict(route=282)), (4,5,dict(route=37))])
>>> G[4]
{3: {0: {}}, 5: {0: {}, 1: {'route': 282}, 2: {'route': 37}}}
Attributes:
Each graph, node, and edge can hold key/value attribute pairs in an associated attribute dictionary (the keys must be hashable). By default these are empty, but can be added or changed using add_edge, add_node or direct manipulation of the attribute dictionaries named graph, node and edge respectively.
>>> G = nx.MultiGraph(day="Friday")
>>> G.graph
{'day': 'Friday'}
Add node attributes using add_node(), add_nodes_from() or G.node
>>> G.add_node(1, time='5pm')
>>> G.add_nodes_from([3], time='2pm')
>>> G.node[1]
{'time': '5pm'}
>>> G.node[1]['room'] = 714
>>> del G.node[1]['room'] # remove attribute
>>> G.nodes(data=True)
[(1, {'time': '5pm'}), (3, {'time': '2pm'})]
Warning: adding a node to G.node does not add it to the graph.
Add edge attributes using add_edge(), add_edges_from(), subscript notation, or G.edge.
>>> G.add_edge(1, 2, weight=4.7 )
>>> G.add_edges_from([(3,4),(4,5)], color='red')
>>> G.add_edges_from([(1,2,{'color':'blue'}), (2,3,{'weight':8})])
>>> G[1][2][0]['weight'] = 4.7
>>> G.edge[1][2][0]['weight'] = 4
Shortcuts:
Many common graph features allow python syntax to speed reporting.
>>> 1 in G # check if node in graph
True
>>> [n for n in G if n<3] # iterate through nodes
[1, 2]
>>> len(G) # number of nodes in graph
5
>>> G[1] # adjacency dict keyed by neighbor to edge attributes
... # Note: you should not change this dict manually!
{2: {0: {'weight': 4}, 1: {'color': 'blue'}}}
The fastest way to traverse all edges of a graph is via adjacency_iter(), but the edges() method is often more convenient.
>>> for n,nbrsdict in G.adjacency_iter():
... for nbr,keydict in nbrsdict.items():
... for key,eattr in keydict.items():
... if 'weight' in eattr:
... (n,nbr,key,eattr['weight'])
(1, 2, 0, 4)
(2, 1, 0, 4)
(2, 3, 0, 8)
(3, 2, 0, 8)
>>> G.edges(data='weight', keys=True)
[(1, 2, 0, 4), (1, 2, 1, None), (2, 3, 0, 8), (3, 4, 0, None), (4, 5, 0, None)]
Reporting:
Simple graph information is obtained using methods. Iterator versions of many reporting methods exist for efficiency. Methods exist for reporting nodes(), edges(), neighbors() and degree() as well as the number of nodes and edges.
For details on these and other miscellaneous methods, see below.
Subclasses (Advanced):
The MultiGraph class uses a dict-of-dict-of-dict-of-dict data structure. The outer dict (node_dict) holds adjacency lists keyed by node. The next dict (adjlist) represents the adjacency list and holds edge_key dicts keyed by neighbor. The edge_key dict holds each edge_attr dict keyed by edge key. The inner dict (edge_attr) represents the edge data and holds edge attribute values keyed by attribute names.
Each of these four dicts in the dict-of-dict-of-dict-of-dict structure can be replaced by a user defined dict-like object. In general, the dict-like features should be maintained but extra features can be added. To replace one of the dicts create a new graph class by changing the class(!) variable holding the factory for that dict-like structure. The variable names are node_dict_factory, adjlist_dict_factory, edge_key_dict_factory and edge_attr_dict_factory.
Examples
Create a multigraph object that tracks the order nodes are added.
>>> from collections import OrderedDict
>>> class OrderedGraph(nx.MultiGraph):
... node_dict_factory = OrderedDict
>>> G = OrderedGraph()
>>> G.add_nodes_from( (2,1) )
>>> G.nodes()
[2, 1]
>>> G.add_edges_from( ((2,2), (2,1), (2,1), (1,1)) )
>>> G.edges()
[(2, 1), (2, 1), (2, 2), (1, 1)]
Create a multgraph object that tracks the order nodes are added and for each node track the order that neighbors are added and for each neighbor tracks the order that multiedges are added.
>>> class OrderedGraph(nx.MultiGraph):
... node_dict_factory = OrderedDict
... adjlist_dict_factory = OrderedDict
... edge_key_dict_factory = OrderedDict
>>> G = OrderedGraph()
>>> G.add_nodes_from( (2,1) )
>>> G.nodes()
[2, 1]
>>> G.add_edges_from( ((2,2), (2,1,2,{'weight':0.1}), (2,1,1,{'weight':0.2}), (1,1)) )
>>> G.edges(keys=True)
[(2, 2, 0), (2, 1, 2), (2, 1, 1), (1, 1, 0)]
MultiGraph.__init__ ([data]) |
|
MultiGraph.add_node (n[, attr_dict]) |
Add a single node n and update node attributes. |
MultiGraph.add_nodes_from (nodes, **attr) |
Add multiple nodes. |
MultiGraph.remove_node (n) |
Remove node n. |
MultiGraph.remove_nodes_from (nodes) |
Remove multiple nodes. |
MultiGraph.add_edge (u, v[, key, attr_dict]) |
Add an edge between u and v. |
MultiGraph.add_edges_from (ebunch[, attr_dict]) |
Add all the edges in ebunch. |
MultiGraph.add_weighted_edges_from (ebunch[, ...]) |
Add all the edges in ebunch as weighted edges with specified weights. |
MultiGraph.remove_edge (u, v[, key]) |
Remove an edge between u and v. |
MultiGraph.remove_edges_from (ebunch) |
Remove all edges specified in ebunch. |
MultiGraph.add_star (nodes, **attr) |
Add a star. |
MultiGraph.add_path (nodes, **attr) |
Add a path. |
MultiGraph.add_cycle (nodes, **attr) |
Add a cycle. |
MultiGraph.clear () |
Remove all nodes and edges from the graph. |
MultiGraph.nodes ([data]) |
Return a list of the nodes in the graph. |
MultiGraph.nodes_iter ([data]) |
Return an iterator over the nodes. |
MultiGraph.__iter__ () |
Iterate over the nodes. |
MultiGraph.edges ([nbunch, data, keys, default]) |
Return a list of edges. |
MultiGraph.edges_iter ([nbunch, data, keys, ...]) |
Return an iterator over the edges. |
MultiGraph.get_edge_data (u, v[, key, default]) |
Return the attribute dictionary associated with edge (u,v). |
MultiGraph.neighbors (n) |
Return a list of the nodes connected to the node n. |
MultiGraph.neighbors_iter (n) |
Return an iterator over all neighbors of node n. |
MultiGraph.__getitem__ (n) |
Return a dict of neighbors of node n. |
MultiGraph.adjacency_list () |
Return an adjacency list representation of the graph. |
MultiGraph.adjacency_iter () |
Return an iterator of (node, adjacency dict) tuples for all nodes. |
MultiGraph.nbunch_iter ([nbunch]) |
Return an iterator of nodes contained in nbunch that are also in the graph. |
MultiGraph.has_node (n) |
Return True if the graph contains the node n. |
MultiGraph.__contains__ (n) |
Return True if n is a node, False otherwise. |
MultiGraph.has_edge (u, v[, key]) |
Return True if the graph has an edge between nodes u and v. |
MultiGraph.order () |
Return the number of nodes in the graph. |
MultiGraph.number_of_nodes () |
Return the number of nodes in the graph. |
MultiGraph.__len__ () |
Return the number of nodes. |
MultiGraph.degree ([nbunch, weight]) |
Return the degree of a node or nodes. |
MultiGraph.degree_iter ([nbunch, weight]) |
Return an iterator for (node, degree). |
MultiGraph.size ([weight]) |
Return the number of edges. |
MultiGraph.number_of_edges ([u, v]) |
Return the number of edges between two nodes. |
MultiGraph.nodes_with_selfloops () |
Return a list of nodes with self loops. |
MultiGraph.selfloop_edges ([data, keys, default]) |
Return a list of selfloop edges. |
MultiGraph.number_of_selfloops () |
Return the number of selfloop edges. |
MultiGraph.copy () |
Return a copy of the graph. |
MultiGraph.to_undirected () |
Return an undirected copy of the graph. |
MultiGraph.to_directed () |
Return a directed representation of the graph. |
MultiGraph.subgraph (nbunch) |
Return the subgraph induced on nodes in nbunch. |
MultiDiGraph
(data=None, **attr)[source]¶A directed graph class that can store multiedges.
Multiedges are multiple edges between two nodes. Each edge can hold optional data or attributes.
A MultiDiGraph holds directed edges. Self loops are allowed.
Nodes can be arbitrary (hashable) Python objects with optional key/value attributes.
Edges are represented as links between nodes with optional key/value attributes.
Parameters: |
|
---|
See also
Examples
Create an empty graph structure (a “null graph”) with no nodes and no edges.
>>> G = nx.MultiDiGraph()
G can be grown in several ways.
Nodes:
Add one node at a time:
>>> G.add_node(1)
Add the nodes from any container (a list, dict, set or even the lines from a file or the nodes from another graph).
>>> G.add_nodes_from([2,3])
>>> G.add_nodes_from(range(100,110))
>>> H=nx.Graph()
>>> H.add_path([0,1,2,3,4,5,6,7,8,9])
>>> G.add_nodes_from(H)
In addition to strings and integers any hashable Python object (except None) can represent a node, e.g. a customized node object, or even another Graph.
>>> G.add_node(H)
Edges:
G can also be grown by adding edges.
Add one edge,
>>> G.add_edge(1, 2)
a list of edges,
>>> G.add_edges_from([(1,2),(1,3)])
or a collection of edges,
>>> G.add_edges_from(H.edges())
If some edges connect nodes not yet in the graph, the nodes are added automatically. If an edge already exists, an additional edge is created and stored using a key to identify the edge. By default the key is the lowest unused integer.
>>> G.add_edges_from([(4,5,dict(route=282)), (4,5,dict(route=37))])
>>> G[4]
{5: {0: {}, 1: {'route': 282}, 2: {'route': 37}}}
Attributes:
Each graph, node, and edge can hold key/value attribute pairs in an associated attribute dictionary (the keys must be hashable). By default these are empty, but can be added or changed using add_edge, add_node or direct manipulation of the attribute dictionaries named graph, node and edge respectively.
>>> G = nx.MultiDiGraph(day="Friday")
>>> G.graph
{'day': 'Friday'}
Add node attributes using add_node(), add_nodes_from() or G.node
>>> G.add_node(1, time='5pm')
>>> G.add_nodes_from([3], time='2pm')
>>> G.node[1]
{'time': '5pm'}
>>> G.node[1]['room'] = 714
>>> del G.node[1]['room'] # remove attribute
>>> G.nodes(data=True)
[(1, {'time': '5pm'}), (3, {'time': '2pm'})]
Warning: adding a node to G.node does not add it to the graph.
Add edge attributes using add_edge(), add_edges_from(), subscript notation, or G.edge.
>>> G.add_edge(1, 2, weight=4.7 )
>>> G.add_edges_from([(3,4),(4,5)], color='red')
>>> G.add_edges_from([(1,2,{'color':'blue'}), (2,3,{'weight':8})])
>>> G[1][2][0]['weight'] = 4.7
>>> G.edge[1][2][0]['weight'] = 4
Shortcuts:
Many common graph features allow python syntax to speed reporting.
>>> 1 in G # check if node in graph
True
>>> [n for n in G if n<3] # iterate through nodes
[1, 2]
>>> len(G) # number of nodes in graph
5
>>> G[1] # adjacency dict keyed by neighbor to edge attributes
... # Note: you should not change this dict manually!
{2: {0: {'weight': 4}, 1: {'color': 'blue'}}}
The fastest way to traverse all edges of a graph is via adjacency_iter(), but the edges() method is often more convenient.
>>> for n,nbrsdict in G.adjacency_iter():
... for nbr,keydict in nbrsdict.items():
... for key,eattr in keydict.items():
... if 'weight' in eattr:
... (n,nbr,eattr['weight'])
(1, 2, 4)
(2, 3, 8)
>>> G.edges(data='weight')
[(1, 2, 4), (1, 2, None), (2, 3, 8), (3, 4, None), (4, 5, None)]
Reporting:
Simple graph information is obtained using methods. Iterator versions of many reporting methods exist for efficiency. Methods exist for reporting nodes(), edges(), neighbors() and degree() as well as the number of nodes and edges.
For details on these and other miscellaneous methods, see below.
Subclasses (Advanced):
The MultiDiGraph class uses a dict-of-dict-of-dict-of-dict structure. The outer dict (node_dict) holds adjacency lists keyed by node. The next dict (adjlist) represents the adjacency list and holds edge_key dicts keyed by neighbor. The edge_key dict holds each edge_attr dict keyed by edge key. The inner dict (edge_attr) represents the edge data and holds edge attribute values keyed by attribute names.
Each of these four dicts in the dict-of-dict-of-dict-of-dict structure can be replaced by a user defined dict-like object. In general, the dict-like features should be maintained but extra features can be added. To replace one of the dicts create a new graph class by changing the class(!) variable holding the factory for that dict-like structure. The variable names are node_dict_factory, adjlist_dict_factory, edge_key_dict_factory and edge_attr_dict_factory.
Examples
Create a multigraph object that tracks the order nodes are added.
>>> from collections import OrderedDict
>>> class OrderedGraph(nx.MultiDiGraph):
... node_dict_factory = OrderedDict
>>> G = OrderedGraph()
>>> G.add_nodes_from( (2,1) )
>>> G.nodes()
[2, 1]
>>> G.add_edges_from( ((2,2), (2,1), (2,1), (1,1)) )
>>> G.edges()
[(2, 1), (2, 1), (2, 2), (1, 1)]
Create a multdigraph object that tracks the order nodes are added and for each node track the order that neighbors are added and for each neighbor tracks the order that multiedges are added.
>>> class OrderedGraph(nx.MultiDiGraph):
... node_dict_factory = OrderedDict
... adjlist_dict_factory = OrderedDict
... edge_key_dict_factory = OrderedDict
>>> G = OrderedGraph()
>>> G.add_nodes_from( (2,1) )
>>> G.nodes()
[2, 1]
>>> G.add_edges_from( ((2,2), (2,1,2,{'weight':0.1}), (2,1,1,{'weight':0.2}), (1,1)) )
>>> G.edges(keys=True)
[(2, 2, 0), (2, 1, 2), (2, 1, 1), (1, 1, 0)]
MultiDiGraph.__init__ ([data]) |
|
MultiDiGraph.add_node (n[, attr_dict]) |
Add a single node n and update node attributes. |
MultiDiGraph.add_nodes_from (nodes, **attr) |
Add multiple nodes. |
MultiDiGraph.remove_node (n) |
Remove node n. |
MultiDiGraph.remove_nodes_from (nbunch) |
Remove multiple nodes. |
MultiDiGraph.add_edge (u, v[, key, attr_dict]) |
Add an edge between u and v. |
MultiDiGraph.add_edges_from (ebunch[, attr_dict]) |
Add all the edges in ebunch. |
MultiDiGraph.add_weighted_edges_from (ebunch) |
Add all the edges in ebunch as weighted edges with specified weights. |
MultiDiGraph.remove_edge (u, v[, key]) |
Remove an edge between u and v. |
MultiDiGraph.remove_edges_from (ebunch) |
Remove all edges specified in ebunch. |
MultiDiGraph.add_star (nodes, **attr) |
Add a star. |
MultiDiGraph.add_path (nodes, **attr) |
Add a path. |
MultiDiGraph.add_cycle (nodes, **attr) |
Add a cycle. |
MultiDiGraph.clear () |
Remove all nodes and edges from the graph. |
MultiDiGraph.nodes ([data]) |
Return a list of the nodes in the graph. |
MultiDiGraph.nodes_iter ([data]) |
Return an iterator over the nodes. |
MultiDiGraph.__iter__ () |
Iterate over the nodes. |
MultiDiGraph.edges ([nbunch, data, keys, default]) |
Return a list of edges. |
MultiDiGraph.edges_iter ([nbunch, data, ...]) |
Return an iterator over the edges. |
MultiDiGraph.out_edges ([nbunch, keys, data]) |
Return a list of the outgoing edges. |
MultiDiGraph.out_edges_iter ([nbunch, data, ...]) |
Return an iterator over the edges. |
MultiDiGraph.in_edges ([nbunch, keys, data]) |
Return a list of the incoming edges. |
MultiDiGraph.in_edges_iter ([nbunch, data, keys]) |
Return an iterator over the incoming edges. |
MultiDiGraph.get_edge_data (u, v[, key, default]) |
Return the attribute dictionary associated with edge (u,v). |
MultiDiGraph.neighbors (n) |
Return a list of successor nodes of n. |
MultiDiGraph.neighbors_iter (n) |
Return an iterator over successor nodes of n. |
MultiDiGraph.__getitem__ (n) |
Return a dict of neighbors of node n. |
MultiDiGraph.successors (n) |
Return a list of successor nodes of n. |
MultiDiGraph.successors_iter (n) |
Return an iterator over successor nodes of n. |
MultiDiGraph.predecessors (n) |
Return a list of predecessor nodes of n. |
MultiDiGraph.predecessors_iter (n) |
Return an iterator over predecessor nodes of n. |
MultiDiGraph.adjacency_list () |
Return an adjacency list representation of the graph. |
MultiDiGraph.adjacency_iter () |
Return an iterator of (node, adjacency dict) tuples for all nodes. |
MultiDiGraph.nbunch_iter ([nbunch]) |
Return an iterator of nodes contained in nbunch that are also in the graph. |
MultiDiGraph.has_node (n) |
Return True if the graph contains the node n. |
MultiDiGraph.__contains__ (n) |
Return True if n is a node, False otherwise. |
MultiDiGraph.has_edge (u, v[, key]) |
Return True if the graph has an edge between nodes u and v. |
MultiDiGraph.order () |
Return the number of nodes in the graph. |
MultiDiGraph.number_of_nodes () |
Return the number of nodes in the graph. |
MultiDiGraph.__len__ () |
Return the number of nodes. |
MultiDiGraph.degree ([nbunch, weight]) |
Return the degree of a node or nodes. |
MultiDiGraph.degree_iter ([nbunch, weight]) |
Return an iterator for (node, degree). |
MultiDiGraph.in_degree ([nbunch, weight]) |
Return the in-degree of a node or nodes. |
MultiDiGraph.in_degree_iter ([nbunch, weight]) |
Return an iterator for (node, in-degree). |
MultiDiGraph.out_degree ([nbunch, weight]) |
Return the out-degree of a node or nodes. |
MultiDiGraph.out_degree_iter ([nbunch, weight]) |
Return an iterator for (node, out-degree). |
MultiDiGraph.size ([weight]) |
Return the number of edges. |
MultiDiGraph.number_of_edges ([u, v]) |
Return the number of edges between two nodes. |
MultiDiGraph.nodes_with_selfloops () |
Return a list of nodes with self loops. |
MultiDiGraph.selfloop_edges ([data, keys, ...]) |
Return a list of selfloop edges. |
MultiDiGraph.number_of_selfloops () |
Return the number of selfloop edges. |
MultiDiGraph.copy () |
Return a copy of the graph. |
MultiDiGraph.to_undirected ([reciprocal]) |
Return an undirected representation of the digraph. |
MultiDiGraph.to_directed () |
Return a directed copy of the graph. |
MultiDiGraph.subgraph (nbunch) |
Return the subgraph induced on nodes in nbunch. |
MultiDiGraph.reverse ([copy]) |
Return the reverse of the graph. |
Fast approximation for node connectivity
all_pairs_node_connectivity (G[, nbunch, cutoff]) |
Compute node connectivity between all pairs of nodes. |
local_node_connectivity (G, source, target[, ...]) |
Compute node connectivity between source and target. |
node_connectivity (G[, s, t]) |
Returns an approximation for node connectivity for a graph or digraph G. |
Fast approximation for k-component structure
k_components (G[, min_density]) |
Returns the approximate k-component structure of a graph G. |
Cliques.
max_clique (G) |
Find the Maximum Clique |
clique_removal (G) |
Repeatedly remove cliques from the graph. |
average_clustering (G[, trials]) |
Estimates the average clustering coefficient of G. |
Functions for finding node and edge dominating sets.
A `dominating set`_[1] for an undirected graph *G with vertex set V and edge set E is a subset D of V such that every vertex not in D is adjacent to at least one member of D. An `edge dominating set`_[2] is a subset *F of E such that every edge not in F is incident to an endpoint of at least one edge in F.
[1] | dominating set: https://en.wikipedia.org/wiki/Dominating_set |
[2] | edge dominating set: https://en.wikipedia.org/wiki/Edge_dominating_set |
min_weighted_dominating_set (G[, weight]) |
Returns a dominating set that approximates the minimum weight node dominating set. |
min_edge_dominating_set (G) |
Return minimum cardinality edge dominating set. |
Independent Set
Independent set or stable set is a set of vertices in a graph, no two of which are adjacent. That is, it is a set I of vertices such that for every two vertices in I, there is no edge connecting the two. Equivalently, each edge in the graph has at most one endpoint in I. The size of an independent set is the number of vertices it contains.
A maximum independent set is a largest independent set for a given graph G and its size is denoted α(G). The problem of finding such a set is called the maximum independent set problem and is an NP-hard optimization problem. As such, it is unlikely that there exists an efficient algorithm for finding a maximum independent set of a graph.
http://en.wikipedia.org/wiki/Independent_set_(graph_theory)
Independent set algorithm is based on the following paper:
apx of maximum clique/independent set.
Boppana, R., & Halldórsson, M. M. (1992). Approximating maximum independent sets by excluding subgraphs. BIT Numerical Mathematics, 32(2), 180–196. Springer. doi:10.1007/BF01994876
maximum_independent_set (G) |
Return an approximate maximum independent set. |
Given a graph G = (V,E), a matching M in G is a set of pairwise non-adjacent edges; that is, no two edges share a common vertex.
min_maximal_matching (G) |
Returns the minimum maximal matching of G. |
Given an undirected graph and a function w assigning nonnegative weights to its vertices, find a minimum weight subset of V such that each edge in E is incident to at least one vertex in the subset.
min_weighted_vertex_cover (G[, weight]) |
2-OPT Local Ratio for Minimum Weighted Vertex Cover |
degree_assortativity_coefficient (G[, x, y, ...]) |
Compute degree assortativity of graph. |
attribute_assortativity_coefficient (G, attribute) |
Compute assortativity for node attributes. |
numeric_assortativity_coefficient (G, attribute) |
Compute assortativity for numerical node attributes. |
degree_pearson_correlation_coefficient (G[, ...]) |
Compute degree assortativity of graph. |
average_neighbor_degree (G[, source, target, ...]) |
Returns the average degree of the neighborhood of each node. |
average_degree_connectivity (G[, source, ...]) |
Compute the average degree connectivity of graph. |
k_nearest_neighbors (G[, source, target, ...]) |
Compute the average degree connectivity of graph. |
attribute_mixing_matrix (G, attribute[, ...]) |
Return mixing matrix for attribute. |
degree_mixing_matrix (G[, x, y, weight, ...]) |
Return mixing matrix for attribute. |
degree_mixing_dict (G[, x, y, weight, nodes, ...]) |
Return dictionary representation of mixing matrix for degree. |
attribute_mixing_dict (G, attribute[, nodes, ...]) |
Return dictionary representation of mixing matrix for attribute. |
This module provides functions and operations for bipartite graphs. Bipartite graphs have two node sets and edges in that only connect nodes from opposite sets. It is common in the literature to use an spatial analogy referring to the two node sets as top and bottom nodes.
The bipartite algorithms are not imported into the networkx namespace at the top level so the easiest way to use them is with:
>>> import networkx as nx
>>> from networkx.algorithms import bipartite
NetworkX does not have a custom bipartite graph class but the Graph() or DiGraph() classes can be used to represent bipartite graphs. However, you have to keep track of which set each node belongs to, and make sure that there is no edge between nodes of the same set. The convention used in NetworkX is to use a node attribute named “bipartite” with values 0 or 1 to identify the sets each node belongs to.
For example:
>>> B = nx.Graph()
>>> B.add_nodes_from([1,2,3,4], bipartite=0) # Add the node attribute "bipartite"
>>> B.add_nodes_from(['a','b','c'], bipartite=1)
>>> B.add_edges_from([(1,'a'), (1,'b'), (2,'b'), (2,'c'), (3,'c'), (4,'a')])
Many algorithms of the bipartite module of NetworkX require, as an argument, a container with all the nodes that belong to one set, in addition to the bipartite graph . If is connected, you can find the node sets using a two-coloring algorithm:
>>> nx.is_connected(B)
True
>>> bottom_nodes, top_nodes = bipartite.sets(B)
list(top_nodes) [1, 2, 3, 4] list(bottom_nodes) [‘a’, ‘c’, ‘b’]
However, if the input graph is not connected, there are more than one possible colorations. Thus, the following result is correct:
>>> B.remove_edge(2,'c')
>>> nx.is_connected(B)
False
>>> bottom_nodes, top_nodes = bipartite.sets(B)
list(top_nodes) [1, 2, 4, ‘c’] list(bottom_nodes) [‘a’, 3, ‘b’]
Using the “bipartite” node attribute, you can easily get the two node sets:
>>> top_nodes = set(n for n,d in B.nodes(data=True) if d['bipartite']==0)
>>> bottom_nodes = set(B) - top_nodes
list(top_nodes) [1, 2, 3, 4] list(bottom_nodes) [‘a’, ‘c’, ‘b’]
So you can easily use the bipartite algorithms that require, as an argument, a container with all nodes that belong to one node set:
>>> print(round(bipartite.density(B, bottom_nodes),2))
0.42
>>> G = bipartite.projected_graph(B, top_nodes)
>>> G.edges()
[(1, 2), (1, 4)]
All bipartite graph generators in NetworkX build bipartite graphs with the “bipartite” node attribute. Thus, you can use the same approach:
>>> RB = bipartite.random_graph(5, 7, 0.2)
>>> RB_top = set(n for n,d in RB.nodes(data=True) if d['bipartite']==0)
>>> RB_bottom = set(RB) - RB_top
>>> list(RB_top)
[0, 1, 2, 3, 4]
>>> list(RB_bottom)
[5, 6, 7, 8, 9, 10, 11]
For other bipartite graph generators see the bipartite section of Graph generators.
is_bipartite (G) |
Returns True if graph G is bipartite, False if not. |
is_bipartite_node_set (G, nodes) |
Returns True if nodes and G/nodes are a bipartition of G. |
sets (G) |
Returns bipartite node sets of graph G. |
color (G) |
Returns a two-coloring of the graph. |
density (B, nodes) |
Return density of bipartite graph B. |
degrees (B, nodes[, weight]) |
Return the degrees of the two node sets in the bipartite graph B. |
Provides functions for computing a maximum cardinality matching in a bipartite graph.
If you don’t care about the particular implementation of the maximum matching
algorithm, simply use the maximum_matching()
. If you do care, you can
import one of the named maximum matching algorithms directly.
For example, to find a maximum matching in the complete bipartite graph with two vertices on the left and three vertices on the right:
>>> import networkx as nx
>>> G = nx.complete_bipartite_graph(2, 3)
>>> left, right = nx.bipartite.sets(G)
>>> list(left)
[0, 1]
>>> list(right)
[2, 3, 4]
>>> nx.bipartite.maximum_matching(G)
{0: 2, 1: 3, 2: 0, 3: 1}
The dictionary returned by maximum_matching()
includes a mapping for
vertices in both the left and right vertex sets.
eppstein_matching (G) |
Returns the maximum cardinality matching of the bipartite graph . |
hopcroft_karp_matching (G) |
Returns the maximum cardinality matching of the bipartite graph . |
to_vertex_cover (G, matching) |
Returns the minimum vertex cover corresponding to the given maximum matching of the bipartite graph . |
biadjacency_matrix (G, row_order[, ...]) |
Return the biadjacency matrix of the bipartite graph G. |
from_biadjacency_matrix (A[, create_using, ...]) |
Creates a new bipartite graph from a biadjacency matrix given as a SciPy sparse matrix. |
One-mode (unipartite) projections of bipartite graphs.
projected_graph (B, nodes[, multigraph]) |
Returns the projection of B onto one of its node sets. |
weighted_projected_graph (B, nodes[, ratio]) |
Returns a weighted projection of B onto one of its node sets. |
collaboration_weighted_projected_graph (B, nodes) |
Newman’s weighted projection of B onto one of its node sets. |
overlap_weighted_projected_graph (B, nodes[, ...]) |
Overlap weighted projection of B onto one of its node sets. |
generic_weighted_projected_graph (B, nodes[, ...]) |
Weighted projection of B with a user-specified weight function. |
Spectral bipartivity measure.
spectral_bipartivity (G[, nodes, weight]) |
Returns the spectral bipartivity. |
clustering (G[, nodes, mode]) |
Compute a bipartite clustering coefficient for nodes. |
average_clustering (G[, nodes, mode]) |
Compute the average bipartite clustering coefficient. |
latapy_clustering (G[, nodes, mode]) |
Compute a bipartite clustering coefficient for nodes. |
robins_alexander_clustering (G) |
Compute the bipartite clustering of G. |
Node redundancy for bipartite graphs.
node_redundancy (G[, nodes]) |
Computes the node redundancy coefficients for the nodes in the bipartite graph G . |
closeness_centrality (G, nodes[, normalized]) |
Compute the closeness centrality for nodes in a bipartite network. |
degree_centrality (G, nodes) |
Compute the degree centrality for nodes in a bipartite network. |
betweenness_centrality (G, nodes) |
Compute betweenness centrality for nodes in a bipartite network. |
Generators and functions for bipartite graphs.
complete_bipartite_graph (n1, n2[, create_using]) |
Return the complete bipartite graph . |
configuration_model (aseq, bseq[, ...]) |
Return a random bipartite graph from two given degree sequences. |
havel_hakimi_graph (aseq, bseq[, create_using]) |
Return a bipartite graph from two given degree sequences using a Havel-Hakimi style construction. |
reverse_havel_hakimi_graph (aseq, bseq[, ...]) |
Return a bipartite graph from two given degree sequences using a Havel-Hakimi style construction. |
alternating_havel_hakimi_graph (aseq, bseq[, ...]) |
Return a bipartite graph from two given degree sequences using an alternating Havel-Hakimi style construction. |
preferential_attachment_graph (aseq, p[, ...]) |
Create a bipartite graph with a preferential attachment model from a given single degree sequence. |
random_graph (n, m, p[, seed, directed]) |
Return a bipartite random graph. |
gnmk_random_graph (n, m, k[, seed, directed]) |
Return a random bipartite graph G_{n,m,k}. |
Functions for creating network blockmodels from node partitions.
Created by Drew Conway <drew.conway@nyu.edu> Copyright (c) 2010. All rights reserved.
blockmodel (G, partitions[, multigraph]) |
Returns a reduced graph constructed using the generalized block modeling technique. |
Routines to find the boundary of a set of nodes.
Edge boundaries are edges that have only one end in the set of nodes.
Node boundaries are nodes outside the set of nodes that have an edge to a node in the set.
edge_boundary (G, nbunch1[, nbunch2]) |
Return the edge boundary. |
node_boundary (G, nbunch1[, nbunch2]) |
Return the node boundary. |
degree_centrality (G) |
Compute the degree centrality for nodes. |
in_degree_centrality (G) |
Compute the in-degree centrality for nodes. |
out_degree_centrality (G) |
Compute the out-degree centrality for nodes. |
closeness_centrality (G[, u, distance, ...]) |
Compute closeness centrality for nodes. |
betweenness_centrality (G[, k, normalized, ...]) |
Compute the shortest-path betweenness centrality for nodes. |
edge_betweenness_centrality (G[, k, ...]) |
Compute betweenness centrality for edges. |
current_flow_closeness_centrality (G[, ...]) |
Compute current-flow closeness centrality for nodes. |
current_flow_betweenness_centrality (G[, ...]) |
Compute current-flow betweenness centrality for nodes. |
edge_current_flow_betweenness_centrality (G) |
Compute current-flow betweenness centrality for edges. |
approximate_current_flow_betweenness_centrality (G) |
Compute the approximate current-flow betweenness centrality for nodes. |
eigenvector_centrality (G[, max_iter, tol, ...]) |
Compute the eigenvector centrality for the graph G. |
eigenvector_centrality_numpy (G[, weight]) |
Compute the eigenvector centrality for the graph G. |
katz_centrality (G[, alpha, beta, max_iter, ...]) |
Compute the Katz centrality for the nodes of the graph G. |
katz_centrality_numpy (G[, alpha, beta, ...]) |
Compute the Katz centrality for the graph G. |
communicability (G) |
Return communicability between all pairs of nodes in G. |
communicability_exp (G) |
Return communicability between all pairs of nodes in G. |
communicability_centrality (G) |
Return communicability centrality for each node in G. |
communicability_centrality_exp (G) |
Return the communicability centrality for each node of G |
communicability_betweenness_centrality (G[, ...]) |
Return communicability betweenness for all pairs of nodes in G. |
estrada_index (G) |
Return the Estrada index of a the graph G. |
load_centrality (G[, v, cutoff, normalized, ...]) |
Compute load centrality for nodes. |
edge_load (G[, nodes, cutoff]) |
Compute edge load. |
dispersion (G[, u, v, normalized, alpha, b, c]) |
Calculate dispersion between and in . |
Algorithms for chordal graphs.
A graph is chordal if every cycle of length at least 4 has a chord (an edge joining two nodes not adjacent in the cycle). http://en.wikipedia.org/wiki/Chordal_graph
is_chordal (G) |
Checks whether G is a chordal graph. |
chordal_graph_cliques (G) |
Returns the set of maximal cliques of a chordal graph. |
chordal_graph_treewidth (G) |
Returns the treewidth of the chordal graph G. |
find_induced_nodes (G, s, t[, treewidth_bound]) |
Returns the set of induced nodes in the path from s to t. |
Find and manipulate cliques of graphs.
Note that finding the largest clique of a graph has been shown to be an NP-complete problem; the algorithms here could take a long time to run.
enumerate_all_cliques (G) |
Returns all cliques in an undirected graph. |
find_cliques (G) |
Search for all maximal cliques in a graph. |
make_max_clique_graph (G[, create_using, name]) |
Create the maximal clique graph of a graph. |
make_clique_bipartite (G[, fpos, ...]) |
Create a bipartite clique graph from a graph G. |
graph_clique_number (G[, cliques]) |
Return the clique number (size of the largest clique) for G. |
graph_number_of_cliques (G[, cliques]) |
Returns the number of maximal cliques in G. |
node_clique_number (G[, nodes, cliques]) |
Returns the size of the largest maximal clique containing each given node. |
number_of_cliques (G[, nodes, cliques]) |
Returns the number of maximal cliques for each node. |
cliques_containing_node (G[, nodes, cliques]) |
Returns a list of cliques containing the given node. |
Algorithms to characterize the number of triangles in a graph.
triangles (G[, nodes]) |
Compute the number of triangles. |
transitivity (G) |
Compute graph transitivity, the fraction of all possible triangles present in G. |
clustering (G[, nodes, weight]) |
Compute the clustering coefficient for nodes. |
average_clustering (G[, nodes, weight, ...]) |
Compute the average clustering coefficient for the graph G. |
square_clustering (G[, nodes]) |
Compute the squares clustering coefficient for nodes. |
greedy_color (G[, strategy, interchange]) |
Color a graph using various strategies of greedy graph coloring. |
k_clique_communities (G, k[, cliques]) |
Find k-clique communities in graph using the percolation method. |
Connected components.
is_connected (G) |
Return True if the graph is connected, false otherwise. |
number_connected_components (G) |
Return the number of connected components. |
connected_components (G) |
Generate connected components. |
connected_component_subgraphs (G[, copy]) |
Generate connected components as subgraphs. |
node_connected_component (G, n) |
Return the nodes in the component of graph containing node n. |
Strongly connected components.
is_strongly_connected (G) |
Test directed graph for strong connectivity. |
number_strongly_connected_components (G) |
Return number of strongly connected components in graph. |
strongly_connected_components (G) |
Generate nodes in strongly connected components of graph. |
strongly_connected_component_subgraphs (G[, copy]) |
Generate strongly connected components as subgraphs. |
strongly_connected_components_recursive (G) |
Generate nodes in strongly connected components of graph. |
kosaraju_strongly_connected_components (G[, ...]) |
Generate nodes in strongly connected components of graph. |
condensation (G[, scc]) |
Returns the condensation of G. |
Weakly connected components.
is_weakly_connected (G) |
Test directed graph for weak connectivity. |
number_weakly_connected_components (G) |
Return the number of weakly connected components in G. |
weakly_connected_components (G) |
Generate weakly connected components of G. |
weakly_connected_component_subgraphs (G[, copy]) |
Generate weakly connected components as subgraphs. |
Attracting components.
is_attracting_component (G) |
Returns True if consists of a single attracting component. |
number_attracting_components (G) |
Returns the number of attracting components in . |
attracting_components (G) |
Generates a list of attracting components in . |
attracting_component_subgraphs (G[, copy]) |
Generates a list of attracting component subgraphs from . |
Biconnected components and articulation points.
is_biconnected (G) |
Return True if the graph is biconnected, False otherwise. |
biconnected_components (G) |
Return a generator of sets of nodes, one set for each biconnected |
biconnected_component_edges (G) |
Return a generator of lists of edges, one list for each biconnected component of the input graph. |
biconnected_component_subgraphs (G[, copy]) |
Return a generator of graphs, one graph for each biconnected component of the input graph. |
articulation_points (G) |
Return a generator of articulation points, or cut vertices, of a graph. |
Semiconnectedness.
is_semiconnected (G) |
Return True if the graph is semiconnected, False otherwise. |
Connectivity and cut algorithms
Moody and White algorithm for k-components
k_components (G[, flow_func]) |
Returns the k-component structure of a graph G. |
Kanevsky all minimum node k cutsets algorithm.
all_node_cuts (G[, k, flow_func]) |
Returns all minimum k cutsets of an undirected graph G. |
Flow based connectivity algorithms
average_node_connectivity (G[, flow_func]) |
Returns the average connectivity of a graph G. |
all_pairs_node_connectivity (G[, nbunch, ...]) |
Compute node connectivity between all pairs of nodes of G. |
edge_connectivity (G[, s, t, flow_func]) |
Returns the edge connectivity of the graph or digraph G. |
local_edge_connectivity (G, u, v[, ...]) |
Returns local edge connectivity for nodes s and t in G. |
local_node_connectivity (G, s, t[, ...]) |
Computes local node connectivity for nodes s and t. |
node_connectivity (G[, s, t, flow_func]) |
Returns node connectivity for a graph or digraph G. |
Flow based cut algorithms
minimum_edge_cut (G[, s, t, flow_func]) |
Returns a set of edges of minimum cardinality that disconnects G. |
minimum_node_cut (G[, s, t, flow_func]) |
Returns a set of nodes of minimum cardinality that disconnects G. |
minimum_st_edge_cut (G, s, t[, flow_func, ...]) |
Returns the edges of the cut-set of a minimum (s, t)-cut. |
minimum_st_node_cut (G, s, t[, flow_func, ...]) |
Returns a set of nodes of minimum cardinality that disconnect source from target in G. |
Stoer-Wagner minimum cut algorithm.
stoer_wagner (G[, weight, heap]) |
Returns the weighted minimum edge cut using the Stoer-Wagner algorithm. |
Utilities for connectivity package
build_auxiliary_edge_connectivity (G) |
Auxiliary digraph for computing flow based edge connectivity |
build_auxiliary_node_connectivity (G) |
Creates a directed graph D from an undirected graph G to compute flow based node connectivity. |
Find the k-cores of a graph.
The k-core is found by recursively pruning nodes with degrees less than k.
See the following reference for details:
An O(m) Algorithm for Cores Decomposition of Networks Vladimir Batagelj and Matjaz Zaversnik, 2003. http://arxiv.org/abs/cs.DS/0310049
core_number (G) |
Return the core number for each vertex. |
k_core (G[, k, core_number]) |
Return the k-core of G. |
k_shell (G[, k, core_number]) |
Return the k-shell of G. |
k_crust (G[, k, core_number]) |
Return the k-crust of G. |
k_corona (G, k[, core_number]) |
Return the k-corona of G. |
cycle_basis (G[, root]) |
Returns a list of cycles which form a basis for cycles of G. |
simple_cycles (G) |
Find simple cycles (elementary circuits) of a directed graph. |
find_cycle (G[, source, orientation]) |
Returns the edges of a cycle found via a directed, depth-first traversal. |
ancestors (G, source) |
Return all nodes having a path to in G. |
descendants (G, source) |
Return all nodes reachable from in G. |
topological_sort (G[, nbunch, reverse]) |
Return a list of nodes in topological sort order. |
topological_sort_recursive (G[, nbunch, reverse]) |
Return a list of nodes in topological sort order. |
is_directed_acyclic_graph (G) |
Return True if the graph G is a directed acyclic graph (DAG) or False if not. |
is_aperiodic (G) |
Return True if G is aperiodic. |
transitive_closure (G) |
Returns transitive closure of a directed graph |
antichains (G) |
Generates antichains from a DAG. |
dag_longest_path (G) |
Returns the longest path in a DAG |
dag_longest_path_length (G) |
Returns the longest path length in a DAG |
Graph diameter, radius, eccentricity and other properties.
center (G[, e]) |
Return the center of the graph G. |
diameter (G[, e]) |
Return the diameter of the graph G. |
eccentricity (G[, v, sp]) |
Return the eccentricity of nodes in G. |
periphery (G[, e]) |
Return the periphery of the graph G. |
radius (G[, e]) |
Return the radius of the graph G. |
is_distance_regular (G) |
Returns True if the graph is distance regular, False otherwise. |
intersection_array (G) |
Returns the intersection array of a distance-regular graph. |
global_parameters (b, c) |
Return global parameters for a given intersection array. |
Dominance algorithms.
immediate_dominators (G, start) |
Returns the immediate dominators of all nodes of a directed graph. |
dominance_frontiers (G, start) |
Returns the dominance frontiers of all nodes of a directed graph. |
dominating_set (G[, start_with]) |
Finds a dominating set for the graph G. |
is_dominating_set (G, nbunch) |
Checks if nodes in nbunch are a dominating set for G. |
Eulerian circuits and graphs.
is_eulerian (G) |
Return True if G is an Eulerian graph, False otherwise. |
eulerian_circuit (G[, source]) |
Return the edges of an Eulerian circuit in G. |
maximum_flow (G, s, t[, capacity, flow_func]) |
Find a maximum single-commodity flow. |
maximum_flow_value (G, s, t[, capacity, ...]) |
Find the value of maximum single-commodity flow. |
minimum_cut (G, s, t[, capacity, flow_func]) |
Compute the value and the node partition of a minimum (s, t)-cut. |
minimum_cut_value (G, s, t[, capacity, flow_func]) |
Compute the value of a minimum (s, t)-cut. |
edmonds_karp (G, s, t[, capacity, residual, ...]) |
Find a maximum single-commodity flow using the Edmonds-Karp algorithm. |
shortest_augmenting_path (G, s, t[, ...]) |
Find a maximum single-commodity flow using the shortest augmenting path algorithm. |
preflow_push (G, s, t[, capacity, residual, ...]) |
Find a maximum single-commodity flow using the highest-label preflow-push algorithm. |
build_residual_network (G, capacity) |
Build a residual network and initialize a zero flow. |
network_simplex (G[, demand, capacity, weight]) |
Find a minimum cost flow satisfying all demands in digraph G. |
min_cost_flow_cost (G[, demand, capacity, weight]) |
Find the cost of a minimum cost flow satisfying all demands in digraph G. |
min_cost_flow (G[, demand, capacity, weight]) |
Return a minimum cost flow satisfying all demands in digraph G. |
cost_of_flow (G, flowDict[, weight]) |
Compute the cost of the flow given by flowDict on graph G. |
max_flow_min_cost (G, s, t[, capacity, weight]) |
Return a maximum (s, t)-flow of minimum cost. |
capacity_scaling (G[, demand, capacity, ...]) |
Find a minimum cost flow satisfying all demands in digraph G. |
Test sequences for graphiness.
is_graphical (sequence[, method]) |
Returns True if sequence is a valid degree sequence. |
is_digraphical (in_sequence, out_sequence) |
Returns True if some directed graph can realize the in- and out-degree sequences. |
is_multigraphical (sequence) |
Returns True if some multigraph can realize the sequence. |
is_pseudographical (sequence) |
Returns True if some pseudograph can realize the sequence. |
is_valid_degree_sequence_havel_hakimi (...) |
Returns True if deg_sequence can be realized by a simple graph. |
is_valid_degree_sequence_erdos_gallai (...) |
Returns True if deg_sequence can be realized by a simple graph. |
Flow Hierarchy.
flow_hierarchy (G[, weight]) |
Returns the flow hierarchy of a directed network. |
Provides functions for finding and testing for locally -connected graphs.
kl_connected_subgraph (G, k, l[, low_memory, ...]) |
Returns the maximum locally -connected subgraph of G . |
is_kl_connected (G, k, l[, low_memory]) |
Returns True if and only if G is locally -connected. |
Functions for identifying isolate (degree zero) nodes.
is_isolate (G, n) |
Determine of node n is an isolate (degree zero). |
isolates (G) |
Return list of isolates in the graph. |
is_isomorphic (G1, G2[, node_match, edge_match]) |
Returns True if the graphs G1 and G2 are isomorphic and False otherwise. |
could_be_isomorphic (G1, G2) |
Returns False if graphs are definitely not isomorphic. |
fast_could_be_isomorphic (G1, G2) |
Returns False if graphs are definitely not isomorphic. |
faster_could_be_isomorphic (G1, G2) |
Returns False if graphs are definitely not isomorphic. |
An implementation of VF2 algorithm for graph ismorphism testing.
The simplest interface to use this module is to call networkx.is_isomorphic().
The GraphMatcher and DiGraphMatcher are responsible for matching graphs or directed graphs in a predetermined manner. This usually means a check for an isomorphism, though other checks are also possible. For example, a subgraph of one graph can be checked for isomorphism to a second graph.
Matching is done via syntactic feasibility. It is also possible to check for semantic feasibility. Feasibility, then, is defined as the logical AND of the two functions.
To include a semantic check, the (Di)GraphMatcher class should be subclassed, and the semantic_feasibility() function should be redefined. By default, the semantic feasibility function always returns True. The effect of this is that semantics are not considered in the matching of G1 and G2.
Examples
Suppose G1 and G2 are isomorphic graphs. Verification is as follows:
>>> from networkx.algorithms import isomorphism
>>> G1 = nx.path_graph(4)
>>> G2 = nx.path_graph(4)
>>> GM = isomorphism.GraphMatcher(G1,G2)
>>> GM.is_isomorphic()
True
GM.mapping stores the isomorphism mapping from G1 to G2.
>>> GM.mapping
{0: 0, 1: 1, 2: 2, 3: 3}
Suppose G1 and G2 are isomorphic directed graphs graphs. Verification is as follows:
>>> G1 = nx.path_graph(4, create_using=nx.DiGraph())
>>> G2 = nx.path_graph(4, create_using=nx.DiGraph())
>>> DiGM = isomorphism.DiGraphMatcher(G1,G2)
>>> DiGM.is_isomorphic()
True
DiGM.mapping stores the isomorphism mapping from G1 to G2.
>>> DiGM.mapping
{0: 0, 1: 1, 2: 2, 3: 3}
Graph theory literature can be ambiguious about the meaning of the above statement, and we seek to clarify it now.
In the VF2 literature, a mapping M is said to be a graph-subgraph isomorphism iff M is an isomorphism between G2 and a subgraph of G1. Thus, to say that G1 and G2 are graph-subgraph isomorphic is to say that a subgraph of G1 is isomorphic to G2.
Other literature uses the phrase ‘subgraph isomorphic’ as in ‘G1 does not have a subgraph isomorphic to G2’. Another use is as an in adverb for isomorphic. Thus, to say that G1 and G2 are subgraph isomorphic is to say that a subgraph of G1 is isomorphic to G2.
Finally, the term ‘subgraph’ can have multiple meanings. In this context, ‘subgraph’ always means a ‘node-induced subgraph’. Edge-induced subgraph isomorphisms are not directly supported, but one should be able to perform the check by making use of nx.line_graph(). For subgraphs which are not induced, the term ‘monomorphism’ is preferred over ‘isomorphism’. Currently, it is not possible to check for monomorphisms.
Let G=(N,E) be a graph with a set of nodes N and set of edges E.
References
See also
syntactic_feasibliity
, semantic_feasibility
Notes
Modified to handle undirected graphs. Modified to handle multiple edges.
In general, this problem is NP-Complete.
GraphMatcher.__init__ (G1, G2[, node_match, ...]) |
Initialize graph matcher. |
GraphMatcher.initialize () |
Reinitializes the state of the algorithm. |
GraphMatcher.is_isomorphic () |
Returns True if G1 and G2 are isomorphic graphs. |
GraphMatcher.subgraph_is_isomorphic () |
Returns True if a subgraph of G1 is isomorphic to G2. |
GraphMatcher.isomorphisms_iter () |
Generator over isomorphisms between G1 and G2. |
GraphMatcher.subgraph_isomorphisms_iter () |
Generator over isomorphisms between a subgraph of G1 and G2. |
GraphMatcher.candidate_pairs_iter () |
Iterator over candidate pairs of nodes in G1 and G2. |
GraphMatcher.match () |
Extends the isomorphism mapping. |
GraphMatcher.semantic_feasibility (G1_node, ...) |
Returns True if mapping G1_node to G2_node is semantically feasible. |
GraphMatcher.syntactic_feasibility (G1_node, ...) |
Returns True if adding (G1_node, G2_node) is syntactically feasible. |
DiGraphMatcher.__init__ (G1, G2[, ...]) |
Initialize graph matcher. |
DiGraphMatcher.initialize () |
Reinitializes the state of the algorithm. |
DiGraphMatcher.is_isomorphic () |
Returns True if G1 and G2 are isomorphic graphs. |
DiGraphMatcher.subgraph_is_isomorphic () |
Returns True if a subgraph of G1 is isomorphic to G2. |
DiGraphMatcher.isomorphisms_iter () |
Generator over isomorphisms between G1 and G2. |
DiGraphMatcher.subgraph_isomorphisms_iter () |
Generator over isomorphisms between a subgraph of G1 and G2. |
DiGraphMatcher.candidate_pairs_iter () |
Iterator over candidate pairs of nodes in G1 and G2. |
DiGraphMatcher.match () |
Extends the isomorphism mapping. |
DiGraphMatcher.semantic_feasibility (G1_node, ...) |
Returns True if mapping G1_node to G2_node is semantically feasible. |
DiGraphMatcher.syntactic_feasibility (...) |
Returns True if adding (G1_node, G2_node) is syntactically feasible. |
categorical_node_match (attr, default) |
Returns a comparison function for a categorical node attribute. |
categorical_edge_match (attr, default) |
Returns a comparison function for a categorical edge attribute. |
categorical_multiedge_match (attr, default) |
Returns a comparison function for a categorical edge attribute. |
numerical_node_match (attr, default[, rtol, atol]) |
Returns a comparison function for a numerical node attribute. |
numerical_edge_match (attr, default[, rtol, atol]) |
Returns a comparison function for a numerical edge attribute. |
numerical_multiedge_match (attr, default[, ...]) |
Returns a comparison function for a numerical edge attribute. |
generic_node_match (attr, default, op) |
Returns a comparison function for a generic attribute. |
generic_edge_match (attr, default, op) |
Returns a comparison function for a generic attribute. |
generic_multiedge_match (attr, default, op) |
Returns a comparison function for a generic attribute. |
PageRank analysis of graph structure.
pagerank (G[, alpha, personalization, ...]) |
Return the PageRank of the nodes in the graph. |
pagerank_numpy (G[, alpha, personalization, ...]) |
Return the PageRank of the nodes in the graph. |
pagerank_scipy (G[, alpha, personalization, ...]) |
Return the PageRank of the nodes in the graph. |
google_matrix (G[, alpha, personalization, ...]) |
Return the Google matrix of the graph. |
Hubs and authorities analysis of graph structure.
hits (G[, max_iter, tol, nstart, normalized]) |
Return HITS hubs and authorities values for nodes. |
hits_numpy (G[, normalized]) |
Return HITS hubs and authorities values for nodes. |
hits_scipy (G[, max_iter, tol, normalized]) |
Return HITS hubs and authorities values for nodes. |
hub_matrix (G[, nodelist]) |
Return the HITS hub matrix. |
authority_matrix (G[, nodelist]) |
Return the HITS authority matrix. |
Link prediction algorithms.
resource_allocation_index (G[, ebunch]) |
Compute the resource allocation index of all node pairs in ebunch. |
jaccard_coefficient (G[, ebunch]) |
Compute the Jaccard coefficient of all node pairs in ebunch. |
adamic_adar_index (G[, ebunch]) |
Compute the Adamic-Adar index of all node pairs in ebunch. |
preferential_attachment (G[, ebunch]) |
Compute the preferential attachment score of all node pairs in ebunch. |
cn_soundarajan_hopcroft (G[, ebunch, community]) |
Count the number of common neighbors of all node pairs in ebunch using community information. |
ra_index_soundarajan_hopcroft (G[, ebunch, ...]) |
Compute the resource allocation index of all node pairs in ebunch using community information. |
within_inter_cluster (G[, ebunch, delta, ...]) |
Compute the ratio of within- and inter-cluster common neighbors of all node pairs in ebunch. |
maximal_matching (G) |
Find a maximal cardinality matching in the graph. |
max_weight_matching (G[, maxcardinality]) |
Compute a maximum-weighted matching of G. |
Provides functions for computing minors of a graph.
contracted_edge (G, edge[, self_loops]) |
Returns the graph that results from contracting the specified edge. |
contracted_nodes (G, u, v[, self_loops]) |
Returns the graph that results from contracting u and v . |
identified_nodes (G, u, v[, self_loops]) |
Returns the graph that results from contracting u and v . |
quotient_graph (G, node_relation[, ...]) |
Returns the quotient graph of G under the specified equivalence relation on nodes. |
Algorithm to find a maximal (not maximum) independent set.
maximal_independent_set (G[, nodes]) |
Return a random maximal independent set guaranteed to contain a given set of nodes. |
Computes minimum spanning tree of a weighted graph.
minimum_spanning_tree (G[, weight]) |
Return a minimum spanning tree or forest of an undirected weighted graph. |
minimum_spanning_edges (G[, weight, data]) |
Generate edges in a minimum spanning forest of an undirected weighted graph. |
Unary operations on graphs
complement (G[, name]) |
Return the graph complement of G. |
reverse (G[, copy]) |
Return the reverse directed graph of G. |
Operations on graphs including union, intersection, difference.
compose (G, H[, name]) |
Return a new graph of G composed with H. |
union (G, H[, rename, name]) |
Return the union of graphs G and H. |
disjoint_union (G, H) |
Return the disjoint union of graphs G and H. |
intersection (G, H) |
Return a new graph that contains only the edges that exist in both G and H. |
difference (G, H) |
Return a new graph that contains the edges that exist in G but not in H. |
symmetric_difference (G, H) |
Return new graph with edges that exist in either G or H but not both. |
Operations on many graphs.
compose_all (graphs[, name]) |
Return the composition of all graphs. |
union_all (graphs[, rename, name]) |
Return the union of all graphs. |
disjoint_union_all (graphs) |
Return the disjoint union of all graphs. |
intersection_all (graphs) |
Return a new graph that contains only the edges that exist in all graphs. |
Graph products.
cartesian_product (G, H) |
Return the Cartesian product of G and H. |
lexicographic_product (G, H) |
Return the lexicographic product of G and H. |
strong_product (G, H) |
Return the strong product of G and H. |
tensor_product (G, H) |
Return the tensor product of G and H. |
power (G, k) |
Returns the specified power of a graph. |
rich_club_coefficient (G[, normalized, Q]) |
Return the rich-club coefficient of the graph G. |
Compute the shortest paths and path lengths between nodes in the graph.
These algorithms work with undirected and directed graphs.
shortest_path (G[, source, target, weight]) |
Compute shortest paths in the graph. |
all_shortest_paths (G, source, target[, weight]) |
Compute all shortest paths in the graph. |
shortest_path_length (G[, source, target, weight]) |
Compute shortest path lengths in the graph. |
average_shortest_path_length (G[, weight]) |
Return the average shortest path length. |
has_path (G, source, target) |
Return True if G has a path from source to target, False otherwise. |
Shortest path algorithms for unweighted graphs.
single_source_shortest_path (G, source[, cutoff]) |
Compute shortest path between source and all other nodes reachable from source. |
single_source_shortest_path_length (G, source) |
Compute the shortest path lengths from source to all reachable nodes. |
all_pairs_shortest_path (G[, cutoff]) |
Compute shortest paths between all nodes. |
all_pairs_shortest_path_length (G[, cutoff]) |
Computes the shortest path lengths between all nodes in G . |
predecessor (G, source[, target, cutoff, ...]) |
Returns dictionary of predecessors for the path from source to all nodes in G. |
Shortest path algorithms for weighed graphs.
dijkstra_path (G, source, target[, weight]) |
Returns the shortest path from source to target in a weighted graph G. |
dijkstra_path_length (G, source, target[, weight]) |
Returns the shortest path length from source to target in a weighted graph. |
single_source_dijkstra_path (G, source[, ...]) |
Compute shortest path between source and all other reachable nodes for a weighted graph. |
single_source_dijkstra_path_length (G, source) |
Compute the shortest path length between source and all other reachable nodes for a weighted graph. |
all_pairs_dijkstra_path (G[, cutoff, weight]) |
Compute shortest paths between all nodes in a weighted graph. |
all_pairs_dijkstra_path_length (G[, cutoff, ...]) |
Compute shortest path lengths between all nodes in a weighted graph. |
single_source_dijkstra (G, source[, target, ...]) |
Compute shortest paths and lengths in a weighted graph G. |
bidirectional_dijkstra (G, source, target[, ...]) |
Dijkstra’s algorithm for shortest paths using bidirectional search. |
dijkstra_predecessor_and_distance (G, source) |
Compute shortest path length and predecessors on shortest paths in weighted graphs. |
bellman_ford (G, source[, weight]) |
Compute shortest path lengths and predecessors on shortest paths in weighted graphs. |
negative_edge_cycle (G[, weight]) |
Return True if there exists a negative edge cycle anywhere in G. |
johnson (G[, weight]) |
Compute shortest paths between all nodes in a weighted graph using Johnson’s algorithm. |
Floyd-Warshall algorithm for shortest paths.
floyd_warshall (G[, weight]) |
Find all-pairs shortest path lengths using Floyd’s algorithm. |
floyd_warshall_predecessor_and_distance (G[, ...]) |
Find all-pairs shortest path lengths using Floyd’s algorithm. |
floyd_warshall_numpy (G[, nodelist, weight]) |
Find all-pairs shortest path lengths using Floyd’s algorithm. |
Shortest paths and path lengths using A* (“A star”) algorithm.
astar_path (G, source, target[, heuristic, ...]) |
Return a list of nodes in a shortest path between source and target using the A* (“A-star”) algorithm. |
astar_path_length (G, source, target[, ...]) |
Return the length of the shortest path between source and target using the A* (“A-star”) algorithm. |
all_simple_paths (G, source, target[, cutoff]) |
Generate all simple paths in the graph G from source to target. |
shortest_simple_paths (G, source, target[, ...]) |
Generate all simple paths in the graph G from source to target, starting from shortest ones. |
Swap edges in a graph.
double_edge_swap (G[, nswap, max_tries]) |
Swap two edges in the graph while keeping the node degrees fixed. |
connected_double_edge_swap (G[, nswap, ...]) |
Attempts the specified number of double-edge swaps in the graph G . |
Basic algorithms for depth-first searching the nodes of a graph.
Based on http://www.ics.uci.edu/~eppstein/PADS/DFS.py by D. Eppstein, July 2004.
dfs_edges (G[, source]) |
Produce edges in a depth-first-search (DFS). |
dfs_tree (G, source) |
Return oriented tree constructed from a depth-first-search from source. |
dfs_predecessors (G[, source]) |
Return dictionary of predecessors in depth-first-search from source. |
dfs_successors (G[, source]) |
Return dictionary of successors in depth-first-search from source. |
dfs_preorder_nodes (G[, source]) |
Produce nodes in a depth-first-search pre-ordering starting from source. |
dfs_postorder_nodes (G[, source]) |
Produce nodes in a depth-first-search post-ordering starting from source. |
dfs_labeled_edges (G[, source]) |
Produce edges in a depth-first-search (DFS) labeled by type. |
Basic algorithms for breadth-first searching the nodes of a graph.
bfs_edges (G, source[, reverse]) |
Produce edges in a breadth-first-search starting at source. |
bfs_tree (G, source[, reverse]) |
Return an oriented tree constructed from of a breadth-first-search starting at source. |
bfs_predecessors (G, source) |
Return dictionary of predecessors in breadth-first-search from source. |
bfs_successors (G, source) |
Return dictionary of successors in breadth-first-search from source. |
A forest is an acyclic, undirected graph, and a tree is a connected forest. Depending on the subfield, there are various conventions for generalizing these definitions to directed graphs.
In one convention, directed variants of forest and tree are defined in an identical manner, except that the direction of the edges is ignored. In effect, each directed edge is treated as a single undirected edge. Then, additional restrictions are imposed to define branchings and arborescences.
In another convention, directed variants of forest and tree correspond to the previous convention’s branchings and arborescences, respectively. Then two new terms, polyforest and polytree, are defined to correspond to the other convention’s forest and tree.
Summarizing:
+-----------------------------+
| Convention A | Convention B |
+=============================+
| forest | polyforest |
| tree | polytree |
| branching | forest |
| arborescence | tree |
+-----------------------------+
Each convention has its reasons. The first convention emphasizes definitional similarity in that directed forests and trees are only concerned with acyclicity and do not have an in-degree constraint, just as their undirected counterparts do not. The second convention emphasizes functional similarity in the sense that the directed analog of a spanning tree is a spanning arborescence. That is, take any spanning tree and choose one node as the root. Then every edge is assigned a direction such there is a directed path from the root to every other node. The result is a spanning arborescence.
NetworkX follows convention “A”. Explicitly, these are:
For trees and arborescences, the adjective “spanning” may be added to designate that the graph, when considered as a forest/branching, consists of a single tree/arborescence that includes all nodes in the graph. It is true, by definition, that every tree/arborescence is spanning with respect to the nodes that define the tree/arborescence and so, it might seem redundant to introduce the notion of “spanning”. However, the nodes may represent a subset of nodes from a larger graph, and it is in this context that the term “spanning” becomes a useful notion.
is_tree (G) |
Returns True if G is a tree. |
is_forest (G) |
Returns True if G is a forest. |
is_arborescence (G) |
Returns True if G is an arborescence. |
is_branching (G) |
Returns True if G is a branching. |
Algorithms for finding optimum branchings and spanning arborescences.
This implementation is based on:
J. Edmonds, Optimum branchings, J. Res. Natl. Bur. Standards 71B (1967), 233–240. URL: http://archive.org/details/jresv71Bn4p233
branching_weight (G[, attr, default]) |
Returns the total weight of a branching. |
greedy_branching (G[, attr, default, kind]) |
Returns a branching obtained through a greedy algorithm. |
maximum_branching (G[, attr, default]) |
Returns a maximum branching from G. |
minimum_branching (G[, attr, default]) |
Returns a minimum branching from G. |
maximum_spanning_arborescence (G[, attr, default]) |
Returns a maximum spanning arborescence from G. |
minimum_spanning_arborescence (G[, attr, default]) |
Returns a minimum spanning arborescence from G. |
Edmonds (G[, seed]) |
Edmonds algorithm for finding optimal branchings and spanning arborescences. |
Functions for analyzing triads of a graph.
triadic_census (G) |
Determines the triadic census of a directed graph. |
Functional interface to graph methods and assorted utilities.
degree (G[, nbunch, weight]) |
Return degree of single node or of nbunch of nodes. |
degree_histogram (G) |
Return a list of the frequency of each degree value. |
density (G) |
Return the density of a graph. |
info (G[, n]) |
Print short summary of information for the graph G or the node n. |
create_empty_copy (G[, with_nodes]) |
Return a copy of the graph G with all of the edges removed. |
is_directed (G) |
Return True if graph is directed. |
nodes (G) |
Return a copy of the graph nodes in a list. |
number_of_nodes (G) |
Return the number of nodes in the graph. |
nodes_iter (G) |
Return an iterator over the graph nodes. |
all_neighbors (graph, node) |
Returns all of the neighbors of a node in the graph. |
non_neighbors (graph, node) |
Returns the non-neighbors of the node in the graph. |
common_neighbors (G, u, v) |
Return the common neighbors of two nodes in a graph. |
edges (G[, nbunch]) |
Return list of edges incident to nodes in nbunch. |
number_of_edges (G) |
Return the number of edges in the graph. |
edges_iter (G[, nbunch]) |
Return iterator over edges incident to nodes in nbunch. |
non_edges (graph) |
Returns the non-existent edges in the graph. |
set_node_attributes (G, name, values) |
Set node attributes from dictionary of nodes and values |
get_node_attributes (G, name) |
Get node attributes from graph |
set_edge_attributes (G, name, values) |
Set edge attributes from dictionary of edge tuples and values. |
get_edge_attributes (G, name) |
Get edge attributes from graph |
Generators for the small graph atlas.
See “An Atlas of Graphs” by Ronald C. Read and Robin J. Wilson, Oxford University Press, 1998.
Because of its size, this module is not imported by default.
graph_atlas_g () |
Return the list [G0,G1,...,G1252] of graphs as named in the Graph Atlas. |
Generators for some classic graphs.
The typical graph generator is called as follows:
>>> G=nx.complete_graph(100)
returning the complete graph on n nodes labeled 0,..,99 as a simple graph. Except for empty_graph, all the generators in this module return a Graph class (i.e. a simple, undirected graph).
balanced_tree (r, h[, create_using]) |
Return the perfectly balanced r-tree of height h. |
barbell_graph (m1, m2[, create_using]) |
Return the Barbell Graph: two complete graphs connected by a path. |
complete_graph (n[, create_using]) |
Return the complete graph K_n with n nodes. |
complete_multipartite_graph (*block_sizes) |
Returns the complete multipartite graph with the specified block sizes. |
circular_ladder_graph (n[, create_using]) |
Return the circular ladder graph CL_n of length n. |
cycle_graph (n[, create_using]) |
Return the cycle graph C_n over n nodes. |
dorogovtsev_goltsev_mendes_graph (n[, ...]) |
Return the hierarchically constructed Dorogovtsev-Goltsev-Mendes graph. |
empty_graph ([n, create_using]) |
Return the empty graph with n nodes and zero edges. |
grid_2d_graph (m, n[, periodic, create_using]) |
Return the 2d grid graph of mxn nodes, each connected to its nearest neighbors. |
grid_graph (dim[, periodic]) |
Return the n-dimensional grid graph. |
hypercube_graph (n) |
Return the n-dimensional hypercube. |
ladder_graph (n[, create_using]) |
Return the Ladder graph of length n. |
lollipop_graph (m, n[, create_using]) |
Return the Lollipop Graph; connected to . |
null_graph ([create_using]) |
Return the Null graph with no nodes or edges. |
path_graph (n[, create_using]) |
Return the Path graph P_n of n nodes linearly connected by n-1 edges. |
star_graph (n[, create_using]) |
Return the Star graph with n+1 nodes: one center node, connected to n outer nodes. |
trivial_graph ([create_using]) |
Return the Trivial graph with one node (with integer label 0) and no edges. |
wheel_graph (n[, create_using]) |
Return the wheel graph: a single hub node connected to each node of the (n-1)-node cycle graph. |
Provides explicit constructions of expander graphs.
margulis_gabber_galil_graph (n[, create_using]) |
Return the Margulis-Gabber-Galil undirected MultiGraph on nodes. |
chordal_cycle_graph (p[, create_using]) |
Return the chordal cycle graph on nodes. |
Various small and named graphs, together with some compact generators.
make_small_graph (graph_description[, ...]) |
Return the small graph described by graph_description. |
LCF_graph (n, shift_list, repeats[, create_using]) |
Return the cubic graph specified in LCF notation. |
bull_graph ([create_using]) |
Return the Bull graph. |
chvatal_graph ([create_using]) |
Return the Chvátal graph. |
cubical_graph ([create_using]) |
Return the 3-regular Platonic Cubical graph. |
desargues_graph ([create_using]) |
Return the Desargues graph. |
diamond_graph ([create_using]) |
Return the Diamond graph. |
dodecahedral_graph ([create_using]) |
Return the Platonic Dodecahedral graph. |
frucht_graph ([create_using]) |
Return the Frucht Graph. |
heawood_graph ([create_using]) |
Return the Heawood graph, a (3,6) cage. |
house_graph ([create_using]) |
Return the House graph (square with triangle on top). |
house_x_graph ([create_using]) |
Return the House graph with a cross inside the house square. |
icosahedral_graph ([create_using]) |
Return the Platonic Icosahedral graph. |
krackhardt_kite_graph ([create_using]) |
Return the Krackhardt Kite Social Network. |
moebius_kantor_graph ([create_using]) |
Return the Moebius-Kantor graph. |
octahedral_graph ([create_using]) |
Return the Platonic Octahedral graph. |
pappus_graph () |
Return the Pappus graph. |
petersen_graph ([create_using]) |
Return the Petersen graph. |
sedgewick_maze_graph ([create_using]) |
Return a small maze with a cycle. |
tetrahedral_graph ([create_using]) |
Return the 3-regular Platonic Tetrahedral graph. |
truncated_cube_graph ([create_using]) |
Return the skeleton of the truncated cube. |
truncated_tetrahedron_graph ([create_using]) |
Return the skeleton of the truncated Platonic tetrahedron. |
tutte_graph ([create_using]) |
Return the Tutte graph. |
Generators for random graphs.
fast_gnp_random_graph (n, p[, seed, directed]) |
Returns a random graph, also known as an Erdős-Rényi graph or a binomial graph. |
gnp_random_graph (n, p[, seed, directed]) |
Returns a random graph, also known as an Erdős-Rényi graph or a binomial graph. |
dense_gnm_random_graph (n, m[, seed]) |
Returns a random graph. |
gnm_random_graph (n, m[, seed, directed]) |
Returns a random graph. |
erdos_renyi_graph (n, p[, seed, directed]) |
Returns a random graph, also known as an Erdős-Rényi graph or a binomial graph. |
binomial_graph (n, p[, seed, directed]) |
Returns a random graph, also known as an Erdős-Rényi graph or a binomial graph. |
newman_watts_strogatz_graph (n, k, p[, seed]) |
Return a Newman–Watts–Strogatz small-world graph. |
watts_strogatz_graph (n, k, p[, seed]) |
Return a Watts–Strogatz small-world graph. |
connected_watts_strogatz_graph (n, k, p[, ...]) |
Returns a connected Watts–Strogatz small-world graph. |
random_regular_graph (d, n[, seed]) |
Returns a random d -regular graph on n nodes. |
barabasi_albert_graph (n, m[, seed]) |
Returns a random graph according to the Barabási–Albert preferential attachment model. |
powerlaw_cluster_graph (n, m, p[, seed]) |
Holme and Kim algorithm for growing graphs with powerlaw degree distribution and approximate average clustering. |
duplication_divergence_graph (n, p[, seed]) |
Returns an undirected graph using the duplication-divergence model. |
random_lobster (n, p1, p2[, seed]) |
Returns a random lobster graph. |
random_shell_graph (constructor[, seed]) |
Returns a random shell graph for the constructor given. |
random_powerlaw_tree (n[, gamma, seed, tries]) |
Returns a tree with a power law degree distribution. |
random_powerlaw_tree_sequence (n[, gamma, ...]) |
Returns a degree sequence for a tree with a power law distribution. |
Generate graphs with a given degree sequence or expected degree sequence.
configuration_model (deg_sequence[, ...]) |
Return a random graph with the given degree sequence. |
directed_configuration_model (...[, ...]) |
Return a directed_random graph with the given degree sequences. |
expected_degree_graph (w[, seed, selfloops]) |
Return a random graph with given expected degrees. |
havel_hakimi_graph (deg_sequence[, create_using]) |
Return a simple graph with given degree sequence constructed using the Havel-Hakimi algorithm. |
directed_havel_hakimi_graph (in_deg_sequence, ...) |
Return a directed graph with the given degree sequences. |
degree_sequence_tree (deg_sequence[, ...]) |
Make a tree for the given degree sequence. |
random_degree_sequence_graph (sequence[, ...]) |
Return a simple random graph with the given degree sequence. |
Generate graphs with given degree and triangle sequence.
random_clustered_graph (joint_degree_sequence) |
Generate a random graph with the given joint independent edge degree and triangle degree sequence. |
Generators for some directed graphs, including growing network (GN) graphs and scale-free graphs.
gn_graph (n[, kernel, create_using, seed]) |
Return the growing network (GN) digraph with n nodes. |
gnr_graph (n, p[, create_using, seed]) |
Return the growing network with redirection (GNR) digraph with n nodes and redirection probability p . |
gnc_graph (n[, create_using, seed]) |
Return the growing network with copying (GNC) digraph with n nodes. |
scale_free_graph (n[, alpha, beta, gamma, ...]) |
Returns a scale-free directed graph. |
Generators for geometric graphs.
random_geometric_graph (n, radius[, dim, pos]) |
Returns a random geometric graph in the unit cube. |
geographical_threshold_graph (n, theta[, ...]) |
Returns a geographical threshold graph. |
waxman_graph (n[, alpha, beta, L, domain]) |
Return a Waxman random graph. |
navigable_small_world_graph (n[, p, q, r, ...]) |
Return a navigable small-world graph. |
Functions for generating line graphs.
line_graph (G[, create_using]) |
Returns the line graph of the graph or digraph G . |
Ego graph.
ego_graph (G, n[, radius, center, ...]) |
Returns induced subgraph of neighbors centered at node n within a given radius. |
Functions for generating stochastic graphs from a given weighted directed graph.
stochastic_graph (G[, copy, weight]) |
Returns a right-stochastic representation of the directed graph G . |
Generators for random intersection graphs.
uniform_random_intersection_graph (n, m, p[, ...]) |
Return a uniform random intersection graph. |
k_random_intersection_graph (n, m, k) |
Return a intersection graph with randomly chosen attribute sets for each node that are of equal size (k). |
general_random_intersection_graph (n, m, p) |
Return a random intersection graph with independent probabilities for connections between node and attribute sets. |
Famous social networks.
karate_club_graph () |
Return Zachary’s Karate Club graph. |
davis_southern_women_graph () |
Return Davis Southern women social network. |
florentine_families_graph () |
Return Florentine families graph. |
Generators for classes of graphs used in studying social networks.
caveman_graph (l, k) |
Returns a caveman graph of l cliques of size k . |
connected_caveman_graph (l, k) |
Returns a connected caveman graph of l cliques of size k . |
relaxed_caveman_graph (l, k, p[, seed]) |
Return a relaxed caveman graph. |
random_partition_graph (sizes, p_in, p_out[, ...]) |
Return the random partition graph with a partition of sizes. |
planted_partition_graph (l, k, p_in, p_out[, ...]) |
Return the planted l-partition graph. |
gaussian_random_partition_graph (n, s, v, ...) |
Generate a Gaussian random partition graph. |
Implementation of the Wright, Richmond, Odlyzko and McKay (WROM) algorithm for the enumeration of all non-isomorphic free trees of a given order. Rooted trees are represented by level sequences, i.e., lists in which the i-th element specifies the distance of vertex i to the root.
nonisomorphic_trees (order[, create]) |
Returns a list of nonisomporphic trees |
number_of_nonisomorphic_trees (order) |
Returns the number of nonisomorphic trees |
Adjacency matrix and incidence matrix of graphs.
adjacency_matrix (G[, nodelist, weight]) |
Return adjacency matrix of G. |
incidence_matrix (G[, nodelist, edgelist, ...]) |
Return incidence matrix of G. |
Laplacian matrix of graphs.
laplacian_matrix (G[, nodelist, weight]) |
Return the Laplacian matrix of G. |
normalized_laplacian_matrix (G[, nodelist, ...]) |
Return the normalized Laplacian matrix of G. |
directed_laplacian_matrix (G[, nodelist, ...]) |
Return the directed Laplacian matrix of G. |
Eigenvalue spectrum of graphs.
laplacian_spectrum (G[, weight]) |
Return eigenvalues of the Laplacian of G |
adjacency_spectrum (G[, weight]) |
Return eigenvalues of the adjacency matrix of G. |
Algebraic connectivity and Fiedler vectors of undirected graphs.
algebraic_connectivity (G[, weight, ...]) |
Return the algebraic connectivity of an undirected graph. |
fiedler_vector (G[, weight, normalized, tol, ...]) |
Return the Fiedler vector of a connected undirected graph. |
spectral_ordering (G[, weight, normalized, ...]) |
Compute the spectral_ordering of a graph. |
Functions for constructing matrix-like objects from graph attributes.
attr_matrix (G[, edge_attr, node_attr, ...]) |
Returns a NumPy matrix using attributes from G. |
attr_sparse_matrix (G[, edge_attr, ...]) |
Returns a SciPy sparse matrix using attributes from G. |
Functions to convert NetworkX graphs to and from other formats.
The preferred way of converting data to a NetworkX graph is through the graph constuctor. The constructor calls the to_networkx_graph() function which attempts to guess the input type and convert it automatically.
Examples
Create a graph with a single edge from a dictionary of dictionaries
>>> d={0: {1: 1}} # dict-of-dicts single edge (0,1)
>>> G=nx.Graph(d)
See also
nx_pygraphviz
, nx_pydot
to_networkx_graph (data[, create_using, ...]) |
Make a NetworkX graph from a known data structure. |
to_dict_of_dicts (G[, nodelist, edge_data]) |
Return adjacency representation of graph as a dictionary of dictionaries. |
from_dict_of_dicts (d[, create_using, ...]) |
Return a graph from a dictionary of dictionaries. |
to_dict_of_lists (G[, nodelist]) |
Return adjacency representation of graph as a dictionary of lists. |
from_dict_of_lists (d[, create_using]) |
Return a graph from a dictionary of lists. |
to_edgelist (G[, nodelist]) |
Return a list of edges in the graph. |
from_edgelist (edgelist[, create_using]) |
Return a graph from a list of edges. |
Functions to convert NetworkX graphs to and from numpy/scipy matrices.
The preferred way of converting data to a NetworkX graph is through the graph constuctor. The constructor calls the to_networkx_graph() function which attempts to guess the input type and convert it automatically.
Examples
Create a 10 node random graph from a numpy matrix
>>> import numpy
>>> a = numpy.reshape(numpy.random.random_integers(0,1,size=100),(10,10))
>>> D = nx.DiGraph(a)
or equivalently
>>> D = nx.to_networkx_graph(a,create_using=nx.DiGraph())
See also
nx_pygraphviz
, nx_pydot
to_numpy_matrix (G[, nodelist, dtype, order, ...]) |
Return the graph adjacency matrix as a NumPy matrix. |
to_numpy_recarray (G[, nodelist, dtype, order]) |
Return the graph adjacency matrix as a NumPy recarray. |
from_numpy_matrix (A[, parallel_edges, ...]) |
Return a graph from numpy matrix. |
to_scipy_sparse_matrix (G[, nodelist, dtype, ...]) |
Return the graph adjacency matrix as a SciPy sparse matrix. |
from_scipy_sparse_matrix (A[, ...]) |
Creates a new graph from an adjacency matrix given as a SciPy sparse matrix. |
to_pandas_dataframe (G[, nodelist, ...]) |
Return the graph adjacency matrix as a Pandas DataFrame. |
from_pandas_dataframe (df, source, target[, ...]) |
Return a graph from Pandas DataFrame. |
convert_node_labels_to_integers (G[, ...]) |
Return a copy of the graph G with the nodes relabeled using consecutive integers. |
relabel_nodes (G, mapping[, copy]) |
Relabel the nodes of the graph G. |
Read and write NetworkX graphs as adjacency lists.
Adjacency list format is useful for graphs without data associated with nodes or edges and for nodes that can be meaningfully represented as strings.
The adjacency list format consists of lines with node labels. The first label in a line is the source node. Further labels in the line are considered target nodes and are added to the graph along with an edge between the source node and target node.
The graph with edges a-b, a-c, d-e can be represented as the following adjacency list (anything following the # in a line is a comment):
a b c # source target target
d e
read_adjlist (path[, comments, delimiter, ...]) |
Read graph in adjacency list format from path. |
write_adjlist (G, path[, comments, ...]) |
Write graph G in single-line adjacency-list format to path. |
parse_adjlist (lines[, comments, delimiter, ...]) |
Parse lines of a graph adjacency list representation. |
generate_adjlist (G[, delimiter]) |
Generate a single line of the graph G in adjacency list format. |
Read and write NetworkX graphs as multi-line adjacency lists.
The multi-line adjacency list format is useful for graphs with nodes that can be meaningfully represented as strings. With this format simple edge data can be stored but node or graph data is not.
The first label in a line is the source node label followed by the node degree d. The next d lines are target node labels and optional edge data. That pattern repeats for all nodes in the graph.
The graph with edges a-b, a-c, d-e can be represented as the following adjacency list (anything following the # in a line is a comment):
# example.multiline-adjlist
a 2
b
c
d 1
e
read_multiline_adjlist (path[, comments, ...]) |
Read graph in multi-line adjacency list format from path. |
write_multiline_adjlist (G, path[, ...]) |
Write the graph G in multiline adjacency list format to path |
parse_multiline_adjlist (lines[, comments, ...]) |
Parse lines of a multiline adjacency list representation of a graph. |
generate_multiline_adjlist (G[, delimiter]) |
Generate a single line of the graph G in multiline adjacency list format. |
Read and write NetworkX graphs as edge lists.
The multi-line adjacency list format is useful for graphs with nodes that can be meaningfully represented as strings. With the edgelist format simple edge data can be stored but node or graph data is not. There is no way of representing isolated nodes unless the node has a self-loop edge.
You can read or write three formats of edge lists with these functions.
Node pairs with no data:
1 2
Python dictionary as data:
1 2 {'weight':7, 'color':'green'}
Arbitrary data:
1 2 7 green
read_edgelist (path[, comments, delimiter, ...]) |
Read a graph from a list of edges. |
write_edgelist (G, path[, comments, ...]) |
Write graph as a list of edges. |
read_weighted_edgelist (path[, comments, ...]) |
Read a graph as list of edges with numeric weights. |
write_weighted_edgelist (G, path[, comments, ...]) |
Write graph G as a list of edges with numeric weights. |
generate_edgelist (G[, delimiter, data]) |
Generate a single line of the graph G in edge list format. |
parse_edgelist (lines[, comments, delimiter, ...]) |
Parse lines of an edge list representation of a graph. |
Read and write graphs in GEXF format.
GEXF (Graph Exchange XML Format) is a language for describing complex network structures, their associated data and dynamics.
This implementation does not support mixed graphs (directed and undirected edges together).
GEXF is an XML format. See http://gexf.net/format/schema.html for the specification and http://gexf.net/format/basic.html for examples.
read_gexf (path[, node_type, relabel, version]) |
Read graph in GEXF format from path. |
write_gexf (G, path[, encoding, prettyprint, ...]) |
Write G in GEXF format to path. |
relabel_gexf_graph (G) |
Relabel graph using “label” node keyword for node label. |
Read graphs in GML format.
“GML, the G>raph Modelling Language, is our proposal for a portable file format for graphs. GML’s key features are portability, simple syntax, extensibility and flexibility. A GML file consists of a hierarchical key-value lists. Graphs can be annotated with arbitrary data structures. The idea for a common file format was born at the GD‘95; this proposal is the outcome of many discussions. GML is the standard file format in the Graphlet graph editor system. It has been overtaken and adapted by several other systems for drawing graphs.”
See http://www.infosun.fim.uni-passau.de/Graphlet/GML/gml-tr.html
See http://www.infosun.fim.uni-passau.de/Graphlet/GML/gml-tr.html for format specification.
Example graphs in GML format: http://www-personal.umich.edu/~mejn/netdata/
read_gml (path[, label, destringizer]) |
Read graph in GML format from path. |
write_gml (G, path[, stringizer]) |
Write a graph G in GML format to the file or file handle path . |
parse_gml (lines[, label, destringizer]) |
Parse GML graph from a string or iterable. |
generate_gml (G[, stringizer]) |
Generate a single entry of the graph G in GML format. |
literal_destringizer (rep) |
Convert a Python literal to the value it represents. |
literal_stringizer (value) |
Convert a value to a Python literal in GML representation. |
Read and write NetworkX graphs as Python pickles.
“The pickle module implements a fundamental, but powerful algorithm for serializing and de-serializing a Python object structure. “Pickling” is the process whereby a Python object hierarchy is converted into a byte stream, and “unpickling” is the inverse operation, whereby a byte stream is converted back into an object hierarchy.”
Note that NetworkX graphs can contain any hashable Python object as node (not just integers and strings). For arbitrary data types it may be difficult to represent the data as text. In that case using Python pickles to store the graph data can be used.
read_gpickle (path) |
Read graph object in Python pickle format. |
write_gpickle (G, path[, protocol]) |
Write graph in Python pickle format. |
Read and write graphs in GraphML format.
This implementation does not support mixed graphs (directed and unidirected edges together), hyperedges, nested graphs, or ports.
“GraphML is a comprehensive and easy-to-use file format for graphs. It consists of a language core to describe the structural properties of a graph and a flexible extension mechanism to add application-specific data. Its main features include support of
- directed, undirected, and mixed graphs,
- hypergraphs,
- hierarchical graphs,
- graphical representations,
- references to external data,
- application-specific attribute data, and
- light-weight parsers.
Unlike many other file formats for graphs, GraphML does not use a custom syntax. Instead, it is based on XML and hence ideally suited as a common denominator for all kinds of services generating, archiving, or processing graphs.”
http://graphml.graphdrawing.org/
GraphML is an XML format. See http://graphml.graphdrawing.org/specification.html for the specification and http://graphml.graphdrawing.org/primer/graphml-primer.html for examples.
read_graphml (path[, node_type]) |
Read graph in GraphML format from path. |
write_graphml (G, path[, encoding, prettyprint]) |
Write G in GraphML XML format to path |
Generate and parse JSON serializable data for NetworkX graphs.
These formats are suitable for use with the d3.js examples http://d3js.org/
The three formats that you can generate with NetworkX are:
- node-link like in the d3.js example http://bl.ocks.org/mbostock/4062045
- tree like in the d3.js example http://bl.ocks.org/mbostock/4063550
- adjacency like in the d3.js example http://bost.ocks.org/mike/miserables/
node_link_data (G[, attrs]) |
Return data in node-link format that is suitable for JSON serialization and use in Javascript documents. |
node_link_graph (data[, directed, ...]) |
Return graph from node-link data format. |
adjacency_data (G[, attrs]) |
Return data in adjacency format that is suitable for JSON serialization and use in Javascript documents. |
adjacency_graph (data[, directed, ...]) |
Return graph from adjacency data format. |
tree_data (G, root[, attrs]) |
Return data in tree format that is suitable for JSON serialization and use in Javascript documents. |
tree_graph (data[, attrs]) |
Return graph from tree data format. |
Read graphs in LEDA format.
LEDA is a C++ class library for efficient data types and algorithms.
See http://www.algorithmic-solutions.info/leda_guide/graphs/leda_native_graph_fileformat.html
read_leda (path[, encoding]) |
Read graph in LEDA format from path. |
parse_leda (lines) |
Read graph in LEDA format from string or iterable. |
Read and write NetworkX graphs in YAML format.
“YAML is a data serialization format designed for human readability and interaction with scripting languages.” See http://www.yaml.org for documentation.
read_yaml (path) |
Read graph in YAML format from path. |
write_yaml (G, path[, encoding]) |
Write graph G in YAML format to path. |
Graph6
Read and write graphs in graph6 format.
“graph6 and sparse6 are formats for storing undirected graphs in a compact manner, using only printable ASCII characters. Files in these formats have text type and contain one line per graph.”
See http://cs.anu.edu.au/~bdm/data/formats.txt for details.
parse_graph6 (string) |
Read a simple undirected graph in graph6 format from string. |
read_graph6 (path) |
Read simple undirected graphs in graph6 format from path. |
generate_graph6 (G[, nodes, header]) |
Generate graph6 format string from a simple undirected graph. |
write_graph6 (G, path[, nodes, header]) |
Write a simple undirected graph to path in graph6 format. |
Sparse6
Read and write graphs in sparse6 format.
“graph6 and sparse6 are formats for storing undirected graphs in a compact manner, using only printable ASCII characters. Files in these formats have text type and contain one line per graph.”
See http://cs.anu.edu.au/~bdm/data/formats.txt for details.
parse_sparse6 (string) |
Read an undirected graph in sparse6 format from string. |
read_sparse6 (path) |
Read an undirected graph in sparse6 format from path. |
generate_sparse6 (G[, nodes, header]) |
Generate sparse6 format string from an undirected graph. |
write_sparse6 (G, path[, nodes, header]) |
Write graph G to given path in sparse6 format. |
Read graphs in Pajek format.
This implementation handles directed and undirected graphs including those with self loops and parallel edges.
See http://vlado.fmf.uni-lj.si/pub/networks/pajek/doc/draweps.htm for format information.
read_pajek (path[, encoding]) |
Read graph in Pajek format from path. |
write_pajek (G, path[, encoding]) |
Write graph in Pajek format to path. |
parse_pajek (lines) |
Parse Pajek format graph from string or iterable. |
Generates a networkx.DiGraph from point and line shapefiles.
“The Esri Shapefile or simply a shapefile is a popular geospatial vector data format for geographic information systems software. It is developed and regulated by Esri as a (mostly) open specification for data interoperability among Esri and other software products.” See http://en.wikipedia.org/wiki/Shapefile for additional information.
read_shp (path[, simplify]) |
Generates a networkx.DiGraph from shapefiles. |
write_shp (G, outdir) |
Writes a networkx.DiGraph to two shapefiles, edges and nodes. |
NetworkX provides basic functionality for visualizing graphs, but its main goal is to enable graph analysis rather than perform graph visualization. In the future, graph visualization functionality may be removed from NetworkX or only available as an add-on package.
Proper graph visualization is hard, and we highly recommend that people visualize their graphs with tools dedicated to that task. Notable examples of dedicated and fully-featured graph visualization tools are Cytoscape, Gephi, Graphviz and, for LaTeX typesetting, PGF/TikZ. To use these and other such tools, you should export your NetworkX graph into a format that can be read by those tools. For example, Cytoscape can read the GraphML format, and so, might be an appropriate choice.
Draw networks with matplotlib.
See also
matplotlib
pygraphviz
draw (G[, pos, ax, hold]) |
Draw the graph G with Matplotlib. |
draw_networkx (G[, pos, arrows, with_labels]) |
Draw the graph G using Matplotlib. |
draw_networkx_nodes (G, pos[, nodelist, ...]) |
Draw the nodes of the graph G. |
draw_networkx_edges (G, pos[, edgelist, ...]) |
Draw the edges of the graph G. |
draw_networkx_labels (G, pos[, labels, ...]) |
Draw node labels on the graph G. |
draw_networkx_edge_labels (G, pos[, ...]) |
Draw edge labels. |
draw_circular (G, **kwargs) |
Draw the graph G with a circular layout. |
draw_random (G, **kwargs) |
Draw the graph G with a random layout. |
draw_spectral (G, **kwargs) |
Draw the graph G with a spectral layout. |
draw_spring (G, **kwargs) |
Draw the graph G with a spring layout. |
draw_shell (G, **kwargs) |
Draw networkx graph with shell layout. |
draw_graphviz (G[, prog]) |
Draw networkx graph with graphviz layout. |
Interface to pygraphviz AGraph class.
Examples
>>> G=nx.complete_graph(5)
>>> A=nx.to_agraph(G)
>>> H=nx.from_agraph(A)
See also
Pygraphviz
from_agraph (A[, create_using]) |
Return a NetworkX Graph or DiGraph from a PyGraphviz graph. |
to_agraph (N) |
Return a pygraphviz graph from a NetworkX graph N. |
write_dot (G, path) |
Write NetworkX graph G to Graphviz dot format on path. |
read_dot (path) |
Return a NetworkX graph from a dot file on path. |
graphviz_layout (G[, prog, root, args]) |
Create node positions for G using Graphviz. |
pygraphviz_layout (G[, prog, root, args]) |
Create node positions for G using Graphviz. |
Import and export NetworkX graphs in Graphviz dot format using pydot.
Either this module or nx_pygraphviz can be used to interface with graphviz.
See also
DOT
from_pydot (P) |
Return a NetworkX graph from a Pydot graph. |
to_pydot (N[, strict]) |
Return a pydot graph from a NetworkX graph N. |
write_dot (G, path) |
Write NetworkX graph G to Graphviz dot format on path. |
read_dot (path) |
Return a NetworkX MultiGraph or MultiDiGraph from a dot file on path. |
graphviz_layout (G[, prog, root]) |
Create node positions using Pydot and Graphviz. |
pydot_layout (G[, prog, root]) |
Create node positions using Pydot and Graphviz. |
Node positioning algorithms for graph drawing.
circular_layout (G[, dim, scale, center]) |
Position nodes on a circle. |
random_layout (G[, dim, center]) |
Position nodes uniformly at random in the unit square. |
shell_layout (G[, nlist, dim, scale, center]) |
Position nodes in concentric circles. |
spring_layout (G[, dim, k, pos, fixed, ...]) |
Position nodes using Fruchterman-Reingold force-directed algorithm. |
spectral_layout (G[, dim, weight, scale, center]) |
Position nodes using the eigenvectors of the graph Laplacian. |
Base exceptions and errors for NetworkX.
NetworkXPointlessConcept
[source]¶Harary, F. and Read, R. “Is the Null Graph a Pointless Concept?” In Graphs and Combinatorics Conference, George Washington University. New York: Springer-Verlag, 1973.
NetworkXUnfeasible
[source]¶Exception raised by algorithms trying to solve a problem instance that has no feasible solution.
Miscellaneous Helpers for NetworkX.
These are not imported into the base networkx namespace but can be accessed, for example, as
>>> import networkx
>>> networkx.utils.is_string_like('spam')
True
is_string_like (obj) |
Check if obj is string. |
flatten (obj[, result]) |
Return flattened version of (possibly nested) iterable object. |
iterable (obj) |
Return True if obj is iterable with a well-defined len(). |
is_list_of_ints (intlist) |
Return True if list is a list of ints. |
make_str (x) |
Return the string representation of t. |
generate_unique_node () |
Generate a unique node label. |
default_opener (filename) |
Opens using system’s default program. |
Union-find data structure.
UnionFind.union (*objects) |
Find the sets containing the objects and merge them all. |
Utilities for generating random numbers, random sequences, and random selections.
create_degree_sequence (n[, sfunction, max_tries]) |
|
pareto_sequence (n[, exponent]) |
Return sample sequence of length n from a Pareto distribution. |
powerlaw_sequence (n[, exponent]) |
Return sample sequence of length n from a power law distribution. |
uniform_sequence (n) |
Return sample sequence of length n from a uniform distribution. |
cumulative_distribution (distribution) |
Return normalized cumulative distribution from discrete distribution. |
discrete_sequence (n[, distribution, ...]) |
Return sample sequence of length n from a given discrete distribution or discrete cumulative distribution. |
zipf_sequence (n[, alpha, xmin]) |
Return a sample sequence of length n from a Zipf distribution with exponent parameter alpha and minimum value xmin. |
zipf_rv (alpha[, xmin, seed]) |
Return a random value chosen from the Zipf distribution. |
random_weighted_sample (mapping, k) |
Return k items without replacement from a weighted sample. |
weighted_choice (mapping) |
Return a single element from a weighted sample. |
Cuthill-McKee ordering of graph nodes to produce sparse matrices
cuthill_mckee_ordering (G[, heuristic]) |
Generate an ordering (permutation) of the graph nodes to make a sparse matrix. |
reverse_cuthill_mckee_ordering (G[, heuristic]) |
Generate an ordering (permutation) of the graph nodes to make a sparse matrix. |
NetworkX is distributed with the BSD license.
Copyright (C) 2004-2012, NetworkX Developers
Aric Hagberg <hagberg@lanl.gov>
Dan Schult <dschult@colgate.edu>
Pieter Swart <swart@lanl.gov>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of the NetworkX Developers nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
To cite NetworkX please use the following publication:
Aric A. Hagberg, Daniel A. Schult and Pieter J. Swart, “Exploring network structure, dynamics, and function using NetworkX”, in Proceedings of the 7th Python in Science Conference (SciPy2008), Gäel Varoquaux, Travis Vaught, and Jarrod Millman (Eds), (Pasadena, CA USA), pp. 11–15, Aug 2008
NetworkX was originally written by Aric Hagberg, Dan Schult, and Pieter Swart, and has been developed with the help of many others. Thanks to everyone who has improved NetworkX by contributing code, bug reports (and fixes), documentation, and input on design, features, and the future of NetworkX.
This section aims to provide a list of people and projects that have
contributed to networkx
. It is intended to be an inclusive list, and
anyone who has contributed and wishes to make that contribution known is
welcome to add an entry into this file. Generally, no name should be added to
this list without the approval of the person associated with that name.
Creating a comprehensive list of contributors can be difficult, and the list within this file is almost certainly incomplete. Contributors include testers, bug reporters, contributors who wish to remain anonymous, funding sources, academic advisors, end users, and even build/integration systems (such as TravisCI, coveralls, and readthedocs).
Do you want to make your contribution known? If you have commit access, edit this file and add your name. If you do not have commit access, feel free to open an issue, submit a pull request, or get in contact with one of the official team members.
A supplementary (but still incomplete) list of contributors is given by the
list of names that have commits in networkx
‘s
git repository. This can be obtained via:
git log --raw | grep "^Author: " | sort | uniq
A historical, partial listing of contributors and their contributions to some of the earlier versions of NetworkX can be found here.
Optionally, add your desired name and include a few relevant links. The order is partially historical, and now, mostly arbitrary.
networkx
and those who have contributed to networkx
have received
support throughout the years from a variety of sources. We list them below.
If you have provided support to networkx
and a support acknowledgment does
not appear below, please help us remedy the situation, and similarly, please
let us know if you’d like something modified or corrected.
networkx
acknowledges support from the following:
networkx
acknowledges support from the following:
An object is hashable if it has a hash value which never changes during its lifetime (it needs a __hash__() method), and can be compared to other objects (it needs an __eq__() or __cmp__() method). Hashable objects which compare equal must have the same hash value.
Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally.
All of Python’s immutable built-in objects are hashable, while no mutable containers (such as lists or dictionaries) are. Objects which are instances of user-defined classes are hashable by default; they all compare unequal, and their hash value is their id().
Definition from http://docs.python.org/glossary.html
NetworkX uses the Python nose testing package. If you don’t already have that package installed, follow the directions here http://somethingaboutorange.com/mrl/projects/nose
You can test the complete package from the unpacked source directory with:
python setup_egg.py nosetests
If you have a file-based (not a Python egg) installation you can test the installed package with
>>> import networkx
>>> networkx.test()
or:
python -c "import networkx; networkx.test()"
You can test any or all of NetworkX by using the “nosetests” test runner.
First make sure the NetworkX version you want to test is in your PYTHONPATH (either installed or pointing to your unpacked source directory).
Then you can run individual test files with:
nosetests path/to/file
or all tests found in dir and an directories contained in dir:
nosetests path/to/dir
By default nosetests doesn’t test docutils style tests in Python modules but you can turn that on with:
nosetests --with-doctest
For doctests in stand-alone files NetworkX uses the extension txt so you can add:
nosetests --with-doctest --doctest-extension=txt
to also execute those tests.
These options are on by default if you run nosetests from the root of the NetworkX distribution since they are specified in the setup.cfg file found there.
Contents:
These pages describe a git and github workflow for the networkx project.
There are several different workflows here, for different ways of working with networkx.
This is not a comprehensive git reference, it’s just a workflow for our own project. It’s tailored to the github hosting service. You may well find better or quicker ways of getting stuff done with git, but these should get you started.
For general resources for learning git, see git resources.
Debian / Ubuntu | sudo apt-get install git |
Fedora | sudo yum install git-core |
Windows | Download and install msysGit |
OS X | Use the git-osx-installer |
See the git page for the most recent information.
Have a look at the github install help pages available from github help
There are good instructions here: http://book.git-scm.com/2_installing_git.html
These are the instructions if you just want to follow the latest networkx source, but you don’t need to do any development for now.
The steps are:
From the command line:
git clone git://github.com/networkx/networkx.git
You now have a copy of the code tree in the new networkx
directory.
From time to time you may want to pull down the latest code. It is necessary to add the networkx repository as a remote to your configuration file. We call it upstream.
git remote set-url upstream https://github.com/networkx/networkx.git
Now git knows where to fetch updates from.
cd networkx git fetch upstream
The tree in networkx
will now have the latest changes from the initial
repository, unless you have made local changes in the meantime. In this case, you have to merge.
git merge upstream/master
It is also possible to update your local fork directly from GitHub:
- Open your fork on GitHub.
- Click on ‘Pull Requests’.
- Click on ‘New Pull Request’. By default, GitHub will compare the original with your fork. If you didn’t make any changes, there is nothing to compare.
- Click on ‘Switching the base’ or click ‘Edit’ and switch the base manually. Now GitHub will compare your fork with the original, and you should see all the latest changes.
- Click on ‘Click to create a pull request for this comparison’ and name your pull request.
- Click on Send pull request.
- Scroll down and click ‘Merge pull request’ and finally ‘Confirm merge’. You will be able to merge it automatically unless you did not change you local repo.
You’ve discovered a bug or something else you want to change in networkx .. — excellent!
You’ve worked out a way to fix it — even better!
You want to tell us about it — best of all!
The easiest way is to make a patch or set of patches. Here we explain how. Making a patch is the simplest and quickest, but if you’re going to be doing anything more than simple quick things, please consider following the Git for development model instead.
# tell git who you are
git config --global user.email you@yourdomain.example.com
git config --global user.name "Your Name Comes Here"
# get the repository if you don't have it
git clone git://github.com/networkx/networkx.git
# make a branch for your patching
cd networkx
git branch the-fix-im-thinking-of
git checkout the-fix-im-thinking-of
# hack, hack, hack
# Tell git about any new files you've made
git add somewhere/tests/test_my_bug.py
# commit work in progress as you go
git commit -am 'BF - added tests for Funny bug'
# hack hack, hack
git commit -am 'BF - added fix for Funny bug'
# make the patch files
git format-patch -M -C master
Then, send the generated patch files to the networkx mailing list — where we will thank you warmly.
Tell git who you are so it can label the commits you’ve made:
git config --global user.email you@yourdomain.example.com
git config --global user.name "Your Name Comes Here"
If you don’t already have one, clone a copy of the networkx repository:
git clone git://github.com/networkx/networkx.git
cd networkx
Make a ‘feature branch’. This will be where you work on your bug fix. It’s nice and safe and leaves you with access to an unmodified copy of the code in the main branch:
git branch the-fix-im-thinking-of
git checkout the-fix-im-thinking-of
Do some edits, and commit them as you go:
# hack, hack, hack
# Tell git about any new files you've made
git add somewhere/tests/test_my_bug.py
# commit work in progress as you go
git commit -am 'BF - added tests for Funny bug'
# hack hack, hack
git commit -am 'BF - added fix for Funny bug'
Note the -am
options to commit
. The m
flag just
signals that you’re going to type a message on the command
line. The a
flag — you can just take on faith —
or see why the -a flag?.
When you have finished, check you have committed all your changes:
git status
Finally, make your commits into patches. You want all the
commits since you branched from the master
branch:
git format-patch -M -C master
You will now have several files named for the commits:
0001-BF-added-tests-for-Funny-bug.patch
0002-BF-added-fix-for-Funny-bug.patch
Send these files to the networkx mailing list.
When you are done, to switch back to the main copy of the
code, just return to the master
branch:
git checkout master
If you find you have done some patches, and you have one or more feature branches, you will probably want to switch to development mode. You can do this with the repository you have.
Fork the networkx repository on github — Making your own copy (fork) of networkx. Then:
# checkout and refresh master branch from main repo
git checkout master
git pull origin master
# rename pointer to main repository to 'upstream'
git remote rename origin upstream
# point your repo to default read / write to your fork on github
git remote add origin git@github.com:your-user-name/networkx.git
# push up any branches you've made and want to keep
git push origin the-fix-im-thinking-of
Then you can, if you want, follow the Development workflow.
Contents:
You need to do this only once. The instructions here are very similar to the instructions at https://help.github.com/articles/fork-a-repo/ — please see that page for more detail. We’re repeating some of it here just to give the specifics for the networkx project, and to suggest some default names.
If you don’t have a github account, go to the github page, and make one.
You then need to configure your account to allow write access — see
the Generating SSH keys
help on github help.
Log into your github account.
Go to the networkx github home at networkx github.
Click on the fork button:
Now, after a short pause and some ‘Hardcore forking action’, you should find yourself at the home page for your own forked copy of networkx.
First you follow the instructions for Making your own copy (fork) of networkx.
git clone git@github.com:your-user-name/networkx.git
cd networkx
git remote add upstream git://github.com/networkx/networkx.git
Clone your fork to the local computer with git clone
git@github.com:your-user-name/networkx.git
Investigate. Change directory to your new repo: cd networkx
. Then
git branch -a
to show you all branches. You’ll get something
like:
* master
remotes/origin/master
This tells you that you are currently on the master
branch, and
that you also have a remote
connection to origin/master
.
What remote repository is remote/origin
? Try git remote -v
to
see the URLs for the remote. They will point to your github fork.
Now you want to connect to the upstream networkx github repository, so you can merge in changes from trunk.
cd networkx
git remote add upstream git://github.com/networkx/networkx.git
upstream
here is just the arbitrary name we’re using to refer to the
main networkx repository at networkx github.
Note that we’ve used git://
for the URL rather than git@
. The
git://
URL is read only. This means we that we can’t accidentally
(or deliberately) write to the upstream repo, and we are only going to
use it to merge into our own code.
Just for your own satisfaction, show yourself that you now have a new
‘remote’, with git remote -v show
, giving you something like:
upstream git://github.com/networkx/networkx.git (fetch)
upstream git://github.com/networkx/networkx.git (push)
origin git@github.com:your-user-name/networkx.git (fetch)
origin git@github.com:your-user-name/networkx.git (push)
Your personal git configurations are saved in the .gitconfig
file in
your home directory.
Here is an example .gitconfig
file:
[user]
name = Your Name
email = you@yourdomain.example.com
[alias]
ci = commit -a
co = checkout
st = status
stat = status
br = branch
wdiff = diff --color-words
[core]
editor = vim
[merge]
summary = true
You can edit this file directly or you can use the git config --global
command:
git config --global user.name "Your Name"
git config --global user.email you@yourdomain.example.com
git config --global alias.ci "commit -a"
git config --global alias.co checkout
git config --global alias.st "status -a"
git config --global alias.stat "status -a"
git config --global alias.br branch
git config --global alias.wdiff "diff --color-words"
git config --global core.editor vim
git config --global merge.summary true
To set up on another computer, you can copy your ~/.gitconfig
file,
or run the commands above.
It is good practice to tell git who you are, for labeling any changes you make to the code. The simplest way to do this is from the command line:
git config --global user.name "Your Name"
git config --global user.email you@yourdomain.example.com
This will write the settings into your git configuration file, which should now contain a user section with your name and email:
[user]
name = Your Name
email = you@yourdomain.example.com
Of course you’ll need to replace Your Name
and you@yourdomain.example.com
with your actual name and email address.
You might well benefit from some aliases to common commands.
For example, you might well want to be able to shorten git checkout
to git co
. Or you may want to alias git diff --color-words
(which gives a nicely formatted output of the diff) to git wdiff
The following git config --global
commands:
git config --global alias.ci "commit -a"
git config --global alias.co checkout
git config --global alias.st "status -a"
git config --global alias.stat "status -a"
git config --global alias.br branch
git config --global alias.wdiff "diff --color-words"
will create an alias
section in your .gitconfig
file with contents
like this:
[alias]
ci = commit -a
co = checkout
st = status -a
stat = status -a
br = branch
wdiff = diff --color-words
You may also want to make sure that your editor of choice is used
git config --global core.editor vim
To enforce summaries when doing merges (~/.gitconfig
file again):
[merge]
log = true
Or from the command line:
git config --global merge.log true
This is a very nice alias to get a fancy log output; it should go in the
alias
section of your .gitconfig
file:
lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)[%an]%Creset' --abbrev-commit --date=relative
You use the alias with:
git lg
and it gives graph / text output something like this (but with color!):
* 6d8e1ee - (HEAD, origin/my-fancy-feature, my-fancy-feature) NF - a fancy file (45 minutes ago) [Matthew Brett]
* d304a73 - (origin/placeholder, placeholder) Merge pull request #48 from hhuuggoo/master (2 weeks ago) [Jonathan Terhorst]
|\
| * 4aff2a8 - fixed bug 35, and added a test in test_bugfixes (2 weeks ago) [Hugo]
|/
* a7ff2e5 - Added notes on discussion/proposal made during Data Array Summit. (2 weeks ago) [Corran Webster]
* 68f6752 - Initial implimentation of AxisIndexer - uses 'index_by' which needs to be changed to a call on an Axes object - this is all very sketchy right now. (2 weeks ago) [Corr
* 376adbd - Merge pull request #46 from terhorst/master (2 weeks ago) [Jonathan Terhorst]
|\
| * b605216 - updated joshu example to current api (3 weeks ago) [Jonathan Terhorst]
| * 2e991e8 - add testing for outer ufunc (3 weeks ago) [Jonathan Terhorst]
| * 7beda5a - prevent axis from throwing an exception if testing equality with non-axis object (3 weeks ago) [Jonathan Terhorst]
| * 65af65e - convert unit testing code to assertions (3 weeks ago) [Jonathan Terhorst]
| * 956fbab - Merge remote-tracking branch 'upstream/master' (3 weeks ago) [Jonathan Terhorst]
| |\
| |/
Thanks to Yury V. Zaytsev for posting it.
You already have your own forked copy of the networkx repository, by following Making your own copy (fork) of networkx. You have Set up your fork. You have configured git by following Configure git. Now you are ready for some real work.
In what follows we’ll refer to the upstream networkx master
branch, as
“trunk”.
master
branch for anything. Consider deleting it.bugfix-for-issue-14
or refactor-database-code
.This way of working helps to keep work well organized, with readable history. This in turn makes it easier for project maintainers (that might be you) to see what you’ve done, and why you did it.
See ipython git workflow for some explanation.
It may sound strange, but deleting your own master
branch can help reduce
confusion about which branch you are on. See deleting master on github for
details.
First make sure you have done Linking your repository to the upstream repo.
From time to time you should fetch the upstream (trunk) changes from github:
git fetch upstream
This will pull down any commits you don’t have, and set the remote branches to
point to the right commit. For example, ‘trunk’ is the branch referred to by
(remote/branchname) upstream/master
- and if there have been commits since
you last checked, upstream/master
will change after you do the fetch.
When you are ready to make some changes to the code, you should start a new branch. Branches that are for a collection of related edits are often called ‘feature branches’.
Making an new branch for each set of related changes will make it easier for someone reviewing your branch to see what you are doing.
Choose an informative name for the branch to remind yourself and the rest of us
what the changes in the branch are for. For example add-ability-to-fly
, or
buxfix-for-issue-42
.
# Update the mirror of trunk
git fetch upstream
# Make new feature branch starting at current trunk
git branch my-new-feature upstream/master
git checkout my-new-feature
Generally, you will want to keep your feature branches on your public github
fork of networkx. To do this, you git push this new branch up to your
github repo. Generally (if you followed the instructions in these pages, and by
default), git will have a link to your github repo, called origin
. You push
up to your own repo on github with:
git push origin my-new-feature
In git >= 1.7 you can ensure that the link is correctly set by using the
--set-upstream
option:
git push --set-upstream origin my-new-feature
From now on git will know that my-new-feature
is related to the
my-new-feature
branch in the github repo.
# hack hack
git add my_new_file
git commit -am 'NF - some message'
git push
Make some changes
See which files have changed with git status
(see git status).
You’ll see a listing like this one:
# On branch ny-new-feature
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: README
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# INSTALL
no changes added to commit (use "git add" and/or "git commit -a")
Check what the actual changes are with git diff
(git diff).
Add any new files to version control git add new_file_name
(see
git add).
To commit all modified files into the local copy of your repo,, do
git commit -am 'A commit message'
. Note the -am
options to
commit
. The m
flag just signals that you’re going to type a
message on the command line. The a
flag — you can just take on
faith — or see why the -a flag? — and the helpful use-case
description in the tangled working copy problem. The git commit manual
page might also be useful.
To push the changes up to your forked repo on github, do a git
push
(see git push).
When you are ready to ask for someone to review your code and consider a merge:
Go to the URL of your forked repo, say
http://github.com/your-user-name/networkx
.
Use the ‘Switch Branches’ dropdown menu near the top left of the page to select the branch with your changes:
Click on the ‘Pull request’ button:
Enter a title for the set of changes, and some explanation of what you’ve done. Say if there is anything you’d like particular attention for - like a complicated change or some code you are not happy with.
If you don’t think your request is ready to be merged, just say so in your pull request message. This is still a good way of getting some preliminary code review.
git checkout master
# delete branch locally
git branch -D my-unwanted-branch
# delete branch on github
git push origin :my-unwanted-branch
(Note the colon :
before test-branch
. See also:
http://github.com/guides/remove-a-remote-branch
If you want to work on some stuff with other people, where you are all committing into the same repository, or even the same branch, then just share it via github.
First fork networkx into your account, as from Making your own copy (fork) of networkx.
Then, go to your forked repository github page, say
http://github.com/your-user-name/networkx
Click on the ‘Admin’ button, and add anyone else to the repo as a collaborator:
Now all those people can do:
git clone git@githhub.com:your-user-name/networkx.git
Remember that links starting with git@
use the ssh protocol and are
read-write; links starting with git://
are read-only.
Your collaborators can then commit directly into that repo with the usual:
git commit -am 'ENH - much better code'
git push origin master # pushes directly into your repo
To see a graphical representation of the repository branches and commits:
gitk --all
To see a linear list of commits for this branch:
git log
You can also look at the network graph visualizer for your github repo.
Finally the Fancy log output lg
alias will give you a reasonable text-based
graph of the repository.
Let’s say you thought of some work you’d like to do. You
Update the mirror of trunk and Make a new feature branch called
cool-feature
. At this stage trunk is at some commit, let’s call it E. Now
you make some new commits on your cool-feature
branch, let’s call them A, B,
C. Maybe your changes take a while, or you come back to them after a while. In
the meantime, trunk has progressed from commit E to commit (say) G:
A---B---C cool-feature
/
D---E---F---G trunk
At this stage you consider merging trunk into your feature branch, and you remember that this here page sternly advises you not to do that, because the history will get messy. Most of the time you can just ask for a review, and not worry that trunk has got a little ahead. But sometimes, the changes in trunk might affect your changes, and you need to harmonize them. In this situation you may prefer to do a rebase.
rebase takes your changes (A, B, C) and replays them as if they had been made to
the current state of trunk
. In other words, in this case, it takes the
changes represented by A, B, C and replays them on top of G. After the rebase,
your history will look like this:
A'--B'--C' cool-feature
/
D---E---F---G trunk
See rebase without tears for more detail.
To do a rebase on trunk:
# Update the mirror of trunk
git fetch upstream
# go to the feature branch
git checkout cool-feature
# make a backup in case you mess up
git branch tmp cool-feature
# rebase cool-feature onto trunk
git rebase --onto upstream/master upstream/master cool-feature
In this situation, where you are already on branch cool-feature
, the last
command can be written more succinctly as:
git rebase upstream/master
When all looks good you can delete your backup branch:
git branch -D tmp
If it doesn’t look good you may need to have a look at Recovering from mess-ups.
If you have made changes to files that have also changed in trunk, this may generate merge conflicts that you need to resolve - see the git rebase man page for some instructions at the end of the “Description” section. There is some related help on merging in the git user manual - see resolving a merge.
Sometimes, you mess up merges or rebases. Luckily, in git it is relatively straightforward to recover from such mistakes.
If you mess up during a rebase:
git rebase --abort
If you notice you messed up after the rebase:
# reset branch back to the saved point
git reset --hard tmp
If you forgot to make a backup branch:
# look at the reflog of the branch
git reflog show cool-feature
8630830 cool-feature@{0}: commit: BUG: io: close file handles immediately
278dd2a cool-feature@{1}: rebase finished: refs/heads/my-feature-branch onto 11ee694744f2552d
26aa21a cool-feature@{2}: commit: BUG: lib: make seek_gzip_factory not leak gzip obj
...
# reset the branch to where it was before the botched rebase
git reset --hard cool-feature@{2}
Note
Do this only for your own feature branches.
There’s an embarassing typo in a commit you made? Or perhaps the you made several false starts you would like the posterity not to see.
This can be done via interactive rebasing.
Suppose that the commit history looks like this:
git log --oneline
eadc391 Fix some remaining bugs
a815645 Modify it so that it works
2dec1ac Fix a few bugs + disable
13d7934 First implementation
6ad92e5 * masked is now an instance of a new object, MaskedConstant
29001ed Add pre-nep for a copule of structured_array_extensions.
...
and 6ad92e5
is the last commit in the cool-feature
branch. Suppose we
want to make the following changes:
13d7934
to something more sensible.2dec1ac
, a815645
, eadc391
into a single one.We do as follows:
# make a backup of the current state
git branch tmp HEAD
# interactive rebase
git rebase -i 6ad92e5
This will open an editor with the following text in it:
pick 13d7934 First implementation
pick 2dec1ac Fix a few bugs + disable
pick a815645 Modify it so that it works
pick eadc391 Fix some remaining bugs
# Rebase 6ad92e5..eadc391 onto 6ad92e5
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
To achieve what we want, we will make the following changes to it:
r 13d7934 First implementation
pick 2dec1ac Fix a few bugs + disable
f a815645 Modify it so that it works
f eadc391 Fix some remaining bugs
This means that (i) we want to edit the commit message for
13d7934
, and (ii) collapse the last three commits into one. Now we
save and quit the editor.
Git will then immediately bring up an editor for editing the commit message. After revising it, we get the output:
[detached HEAD 721fc64] FOO: First implementation
2 files changed, 199 insertions(+), 66 deletions(-)
[detached HEAD 0f22701] Fix a few bugs + disable
1 files changed, 79 insertions(+), 61 deletions(-)
Successfully rebased and updated refs/heads/my-feature-branch.
and the history looks now like this:
0f22701 Fix a few bugs + disable
721fc64 ENH: Sophisticated feature
6ad92e5 * masked is now an instance of a new object, MaskedConstant
If it went wrong, recovery is again possible as explained above.
This page is for maintainers — those of us who merge our own or other peoples’ changes into the upstream repository.
Being as how you’re a maintainer, you are completely on top of the basic stuff in Development workflow.
The instructions in Linking your repository to the upstream repo add a remote that has read-only access to the upstream repo. Being a maintainer, you’ve got read-write access.
It’s good to have your upstream remote have a scary name, to remind you that it’s a read-write remote:
git remote add upstream-rw git@github.com:networkx/networkx.git
git fetch upstream-rw
Let’s say you have some changes that need to go into trunk
(upstream-rw/master
).
The changes are in some branch that you are currently on. For example, you are looking at someone’s changes like this:
git remote add someone git://github.com/someone/networkx.git
git fetch someone
git branch cool-feature --track someone/cool-feature
git checkout cool-feature
So now you are on the branch with the changes to be incorporated upstream. The rest of this section assumes you are on this branch.
If there are only a few commits, consider rebasing to upstream:
# Fetch upstream changes
git fetch upstream-rw
# rebase
git rebase upstream-rw/master
Remember that, if you do a rebase, and push that, you’ll have to close any github pull requests manually, because github will not be able to detect the changes have already been merged.
If there are a longer series of related commits, consider a merge instead:
git fetch upstream-rw
git merge --no-ff upstream-rw/master
The merge will be detected by github, and should close any related pull requests automatically.
Note the --no-ff
above. This forces git to make a merge commit, rather than
doing a fast-forward, so that these set of commits branch off trunk then rejoin
the main history with a merge, rather than appearing to have been made directly
on top of trunk.
Now, in either case, you should check that the history is sensible and you have the right commits:
git log --oneline --graph
git log -p upstream-rw/master..
The first line above just shows the history in a compact way, with a text
representation of the history graph. The second line shows the log of commits
excluding those that can be reached from trunk (upstream-rw/master
), and
including those that can be reached from current HEAD (implied with the ..
at the end). So, it shows the commits unique to this branch compared to trunk.
The -p
option shows the diff for these commits in patch form.
git push upstream-rw my-new-feature:master
This pushes the my-new-feature
branch in this repository to the master
branch in the upstream-rw
repository.
github help is Git’s own help and tutorial site. github more help lists more resources for learning Git and GitHub, including YouTube channels. The list is constantly updated. In case you are used to subversion , you can directly consult the git svn crash course.
To make full use of Git, you need to understand the concept behind Git.
The following pages might help you:
Other than that, many devlopers list their personal tips and tricks. Among others there are Fernando Perez, Nick Quaranto and Linus Torvalds.
You can get these on your own machine with (e.g) git help push
or
(same thing) git push --help
, but, for convenience, here are the
online manual pages for some common commands:
Original Creators:
Aric Hagberg, hagberg@lanl.gov
Pieter Swart, swart@lanl.gov
Dan Schult, dschult@colgate.edu
This page includes more detailed release information and API changes from NetworkX 1.9 to NetworkX 1.10.
Please send comments and questions to the networkx-discuss mailing list: <http://groups.google.com/group/networkx-discuss>.
connected_components
, weakly_connected_components
, and
strongly_connected_components
return now a generator of sets of
nodes. Previously the generator was of lists of nodes. This PR also
refactored the connected_components
and weakly_connected_components
implementations making them faster, especially for large graphs.func_iter
functions in Di/Multi/Graphs classes are slated for
removal in NetworkX 2.0 release. func
will behave like func_iter
and return an iterator instead of list. These functions are deprecated in
NetworkX 1.10 release.enumerate_all_cliques
function is added in the clique package
(networkx.algorithms.clique
) for enumerating all cliques (including
nonmaximal ones) of undirected graphs.networkx.algorithms.coloring
) is created for
graph coloring algorithms. Initially, a greedy_color
function is
provided for coloring graphs using various greedy heuristics.edge_dfs
, added to networkx.algorithms.traversal
,
implements a depth-first traversal of the edges in a graph. This complements
functionality provided by a depth-first traversal of the nodes in a graph.
For multigraphs, it allows the user to know precisely which edges were
followed in a traversal. All NetworkX graph types are supported. A traversal
can also reverse edge orientations or ignore them.find_cycle
function is added to the networkx.algorithms.cycles
package to find a cycle in a graph. Edge orientations can be optionally
reversed or ignored.networkx.algorithms.dominance
package is added for
dominance/dominator algorithms on directed graphs. It contains a
immediate_dominators
function for computing immediate
dominators/dominator trees and a dominance_frontiers
function for
computing dominance frontiers.networkx.algorithms.flow
package is
rewritten to improve its performance and support multi- and disconnected
networks. For some cases, the new implementation is two or three orders of
magnitude faster than the old implementation.networkx.generators
.networkx.generators.expanders
.to_pandas_dataframe
and from_pandas_dataframe
.from_pandas_dataframe
function that accepts Pandas DataFrames
and returns a new graph object. At a minimum, the DataFrame must have two
columns, which define the nodes that make up an edge. However, the function
can also process an arbitrary number of additional columns as edge
attributes, such as ‘weight’.network.algorithms.centrality
.generators.bipartite
have been moved to
algorithms.bipartite.generators
. The functions are not imported in the
main namespace, so to use it, the bipartite package has to be imported.algorithms.dag
. The antichains function was contributed
by Peter Jipsen and Franco Saliola and originally developed for the
SAGE project.networkx.generators.classic
module.networkx.algorithms.minors
.networkx.algorithms.minors
.networkx.linalg
,
and associated spectrum functions to the networkx.linalg.spectrum
module.algorithms.simple_paths
.networkx.linalg.modularity_matrix
module.triadic_census
function; also creates a new module,
networkx.algorithms.triads
.is_weighted
, is_negatively_weighted
, and is_empty
.johnson
at
algorithms.shortest_paths
k_components
in a
graph, which is based on Kanevsky’s algorithm for finding all minimum-size
node cut-sets (implemented in all_node_cuts
#1391).k_components
to the
networkx.approximation
package. This is based on White and Newman
approximation algorithm for finding node independent paths between two
nodes (see #1405).This page reflects API changes from NetworkX 1.8 to NetworkX 1.9.
Please send comments and questions to the networkx-discuss mailing list: <http://groups.google.com/group/networkx-discuss>.
The flow package (networkx.algorithms.flow
) is completely rewritten
with backward incompatible changes. It introduces a new interface to flow
algorithms. Existing code that uses the flow package will not work unmodified
with NetworkX 1.9.
preflow_push
and
shortest_augmenting_path
) and rewrote the Edmonds–Karp algorithm in
flow_fulkerson
which is now in edmonds_karp
.
@ysitu contributed implementations of all new
maximum flow algorithms. The legacy Edmonds–Karp algorithm implementation in
ford_fulkerson
is still available but will be removed in the next
release.ford_fulkerson
) output now a residual network (i.e., a
DiGraph
) after computing the maximum flow. See maximum_flow
documentation for the details on the conventions that NetworkX uses for
defining a residual network.max_flow
and min_cut
functions. The main
entry points to flow algorithms are now the functions maximum_flow
,
maximum_flow_value
, minimum_cut
and
minimum_cut_value
, which have new parameters that control maximum
flow computation: flow_func
for specifying the algorithm that will
do the actual computation (it accepts a function as argument that implements
a maximum flow algorithm), cutoff
for suggesting a maximum flow
value at which the algorithm stops, value_only
for stopping the
computation as soon as we have the value of the flow, and residual
that accepts as argument a residual network to be reused in repeated maximum
flow computation.preflow_push
algorithm can stop after the preflow phase without
computing a maximum flow if we only need the flow value, but both
edmonds_karp
and shortest_augmenting_path
always compute a
maximum flow to obtain the flow value.minimum_cut
returns the cut value and a node
partition that defines the minimum cut. The function
minimum_cut_value
returns only the value of the cut, which is what
the removed min_cut
function used to return before 1.9.preflow_push
,
edmonds_karp
, shortest_augmenting_path
and
ford_fulkerson
) are not imported to the base NetworkX namespace. You
have to explicitly import them from the flow package:>>> from networkx.algorithms.flow import (ford_fulkerson, preflow_push,
... edmonds_karp, shortest_augmenting_path)
capacity_scaling
. It supports MultiDiGraph
and disconnected
networks.Below are some small examples illustrating how to obtain the same output than in NetworkX 1.8.1 using the new interface to flow algorithms introduced in 1.9:
>>> import networkx as nx
>>> G = nx.icosahedral_graph()
>>> nx.set_edge_attributes(G, 'capacity', 1)
With NetworkX 1.8:
>>> flow_value = nx.max_flow(G, 0, 6)
>>> cut_value = nx.min_cut(G, 0, 6)
>>> flow_value == cut_value
True
>>> flow_value, flow_dict = nx.ford_fulkerson(G, 0, 6)
With NetworkX 1.9:
>>> from networkx.algorithms.flow import (ford_fulkerson, preflow_push,
... edmonds_karp, shortest_augmenting_path)
>>> flow_value = nx.maximum_flow_value(G, 0, 6)
>>> cut_value = nx.minimum_cut_value(G, 0, 6)
>>> flow_value == cut_value
True
>>> # Legacy: this returns the exact same output than ford_fulkerson in 1.8.1
>>> flow_value, flow_dict = nx.maximum_flow(G, 0, 6, flow_func=ford_fulkerson)
>>> # We strongly recommend to use the new algorithms:
>>> flow_value, flow_dict = nx.maximum_flow(G, 0, 6)
>>> # If no flow_func is passed as argument, the default flow_func
>>> # (preflow-push) is used. Therefore this is the same than:
>>> flow_value, flow_dict = nx.maximum_flow(G, 0, 6, flow_func=preflow_push)
>>> # You can also use alternative maximum flow algorithms:
>>> flow_value, flow_dict = nx.maximum_flow(G, 0, 6, flow_func=shortest_augmenting_path)
>>> flow_value, flow_dict = nx.maximum_flow(G, 0, 6, flow_func=edmonds_karp)
The flow-based connecitivity and cut algorithms from the connectivity
package (networkx.algorithms.connectivity
) are adapted to take
advantage of the new interface to flow algorithms. As a result, flow-based
connectivity algorithms are up to 10x faster than in NetworkX 1.8 for some
problems, such as sparse networks with highly skewed degree distributions.
A few backwards incompatible changes were introduced.
flow_func
for defining the algorithm that will perform the
underlying maximum flow computations, residual
that accepts
as argument a residual network to be reused in repeated maximum
flow computations, and cutoff
for defining a maximum flow
value at which the underlying maximum flow algorithm stops. The big
speed improvement with respect to 1.8 comes mainly from the reuse
of the residual network and the use of cutoff
.edge_connectivity
,
node_connectivity
, minimum_edge_cut
, and
minimum_node_cut
. All these functions accept a couple of nodes
as optional arguments for computing local connectivity and cuts.mapping
parameter from the local versions of connectivity and cut
functions. We also changed the parameter name for the auxuliary digraph
from aux_digraph
to auxiliary
.all_pairs_node_connectiviy_matrix
to all_pairs_node_connectivity
. This function now returns a dictionary
instead of a NumPy 2D array. We added a new parameter nbunch
for
computing node connectivity only among pairs of nodes in nbunch
.stoer_wagner
function is added to the connectivity package
for computing the weighted minimum cuts of undirected graphs using
the Stoer–Wagner algorithm. This algorithm is not based on maximum flows.
Several heap implementations are also added in the utility package
(networkx.utils
) for use in this function.
BinaryHeap
is recommeded over PairingHeap
for Python
implementations without optimized attribute accesses (e.g., CPython)
despite a slower asymptotic running time. For Python implementations
with optimized attribute accesses (e.g., PyPy), PairingHeap
provides better performance.disperson
function is added in the centrality package
(networkx.algorithms.centrality
) for computing the dispersion of
graphs.networkx.generators.community
) is added for
generating community graphs.is_semiconnected
function is added in the connectivity package
(networkx.algorithms.connectivity
) for recognizing semiconnected
graphs.eulerian_circuit
function in the Euler package
(networkx.algorithm.euler
) is changed to use a linear-time algorithm.non_edges
function in added in the function package
(networkx.functions
) for enumerating nonexistent edges between
existing nodes of graphs.networkx.linalg
) is changed to use SciPy
sparse matrices.algebraic_connectivity
, fiedler_vector
and
spectral_ordering
are added in the linear algebra package
(networkx.linalg
) for computing the algebraic connectivity, Fiedler
vectors and spectral orderings of undirected graphs.networkx.algorithms.link_prediction
) is
added to provide link prediction-related functionalities.networx.readwrite
).goldberg_radzik
function is added in the shortest path package
(networkx.algorithms.shortest_paths
) for computing shortest paths
using the Goldberg–Radzik algorithm.networkx.tree
) is added to provide tree recognition
functionalities.reversed
is added in the utility package
(networkx.utils
) for temporary in-place reversal of graphs.networkx.algorithms.components
) such as connected_components
,
connected_components_subgraph
now return generators instead of lists.
To recover the earlier behavior, use list(connected_components(G))
.networkx.readwrite.json_graph
)
are removed. Use functions from the standard library (e.g.,
json.dumps
) instead.This page reflects API changes from networkx-1.7 to networkx-1.8.
Please send comments and questions to the networkx-discuss mailing list: http://groups.google.com/group/networkx-discuss .
This page reflects API changes from networkx-1.6 to networkx-1.7.
Please send comments and questions to the networkx-discuss mailing list: http://groups.google.com/group/networkx-discuss .
This page reflects API changes from networkx-1.5 to networkx-1.6.
Please send comments and questions to the networkx-discuss mailing list: http://groups.google.com/group/networkx-discuss .
The degree* methods in the graph classes (Graph, DiGraph, MultiGraph, MultiDiGraph) now take an optional weight= keyword that allows computing weighted degree with arbitrary (numerical) edge attributes. Setting weight=None is equivalent to the previous weighted=False.
Many ‘weighted’ graph algorithms now take optional parameter to specifiy which edge attribute should be used for the weight (default=’weight’) (:ticket:`573`)
In some cases the parameter name was changed from weighted, to weight. Here is how to specify which edge attribute will be used in the algorithms:
Algorithms affected are:
to_scipy_sparse_matrix, clustering, average_clustering, bipartite.degree, spectral_layout, neighbor_degree, is_isomorphic, betweenness_centrality, betweenness_centrality_subset, vitality, load_centrality, mincost, shortest_path, shortest_path_length, average_shortest_path_length
Node and edge attributes are now more easily incorporated into isomorphism checks via the ‘node_match’ and ‘edge_match’ parameters. As part of this change, the following classes were removed:
WeightedGraphMatcher
WeightedDiGraphMatcher
WeightedMultiGraphMatcher
WeightedMultiDiGraphMatcher
The function signature for ‘is_isomorphic’ is now simply:
is_isomorphic(g1, g2, node_match=None, edge_match=None)
See its docstring for more details. To aid in the creation of ‘node_match’ and ‘edge_match’ functions, users are encouraged to work with:
categorical_node_match
categorical_edge_match
categroical_multiedge_match
numerical_node_match
numerical_edge_match
numerical_multiedge_match
generic_node_match
generic_edge_match
generic_multiedge_match
These functions construct functions which can be passed to ‘is_isomorphic’. Finally, note that the above functions are not imported into the top-level namespace and should be accessed from ‘networkx.algorithms.isomorphism’. A useful import statement that will be repeated throughout documentation is:
import networkx.algorithms.isomorphism as iso
attracting_components
A list of lists is returned instead of a list of tuples.
condensation
The condensation algorithm now takes a second argument (scc) and returns a graph with nodes labeled as integers instead of node tuples.
degree connectivity
average_in_degree_connectivity and average_out_degree_connectivity have have been replaced with
average_degree_connectivity(G, source=’in’, target=’in’)
and
average_degree_connectivity(G, source=’out’, target=’out’)
neighbor degree
average_neighbor_in_degree and average_neighbor_out_degreey have have been replaced with
average_neighbor_degree(G, source=’in’, target=’in’)
and
average_neighbor_degree(G, source=’out’, target=’out’)
This page reflects API changes from networkx-1.4 to networkx-1.5.
Please send comments and questions to the networkx-discuss mailing list: http://groups.google.com/group/networkx-discuss .
Many ‘weighted’ graph algorithms now take optional parameter to specifiy which edge attribute should be used for the weight (default=’weight’) (:ticket:`509`)
In some cases the parameter name was changed from weighted_edges, or weighted, to weight. Here is how to specify which edge attribute will be used in the algorithms:
Algorithms affected are:
betweenness_centrality, closeness_centrality, edge_bewteeness_centrality, betweeness_centrality_subset, edge_betweenness_centrality_subset, betweenness_centrality_source, load, closness_vitality, weiner_index, spectral_bipartivity current_flow_betweenness_centrality, edge_current_flow_betweenness_centrality, current_flow_betweenness_centrality_subset, edge_current_flow_betweenness_centrality_subset, laplacian, normalized_laplacian, adj_matrix, adjacency_spectrum, shortest_path, shortest_path_length, average_shortest_path_length, single_source_dijkstra_path_basic, astar_path, astar_path_length
The random geometric graph generator has been simplified. It no longer supports the create_using, repel, or verbose parameters. An optional pos keyword was added to allow specification of node positions.
We have made some API changes, detailed below, to add clarity. This page reflects changes from networkx-1.3 to networkx-1.4. For changes from earlier versions to networkx-1.0 see Version 1.0 API changes.
Please send comments and questions to the networkx-discuss mailing list: http://groups.google.com/group/networkx-discuss .
These algorithms now raise an exception when a source and a target are specified and no path exist between these two nodes. The exception is a NetworkXNoPath exception.
We have made some significant API changes, detailed below, to add functionality and clarity. This page reflects changes from networkx-0.99 to networkx-1.0. For changes from earlier versions to networkx-0.99 see Version 0.99 API changes.
Version 1.0 requires Python 2.4 or greater.
Please send comments and questions to the networkx-discuss mailing list: http://groups.google.com/group/networkx-discuss .
In the future we will use a more standard release numbering system with major.minor[build] labels where major and minor are numbers and [build] is a label such as “dev1379” to indicate a development version or “rc1” to indicate a release candidate.
We plan on sticking closer to a time-based release schedule with smaller incremental changes released on a roughly quarterly basis. The graph classes API will remain fixed, unless we determine there are serious bugs or other defects in the existing classes, until networkx-2.0 is released at some time in the future.
The most significant changes in are in the graph classes. All of the graph classes now allow optional graph, node, and edge attributes. Those attributes are stored internally in the graph classes as dictionaries and can be accessed simply like Python dictionaries in most cases.
Each graph keeps a dictionary of key=value attributes in the member G.graph. These attributes can be accessed directly using G.graph or added at instantiation using keyword arguments.
>>> G=nx.Graph(region='Africa')
>>> G.graph['color']='green'
>>> G.graph
{'color': 'green', 'region': 'Africa'}
Each node has a corresponding dictionary of attributes. Adding attributes to nodes is optional.
Add node attributes using add_node(), add_nodes_from() or G.node
>>> G.add_node(1, time='5pm')
>>> G.add_nodes_from([3], time='2pm')
>>> G.node[1]
{'time': '5pm'}
>>> G.node[1]['room'] = 714
>>> G.nodes(data=True)
[(1, {'room': 714, 'time': '5pm'}), (3, {'time': '2pm'})]
Each edge has a corresponding dictionary of attributes. The default edge data is now an empty dictionary of attributes and adding attributes to edges is optional.
A common use case is to add a weight attribute to an edge:
>>> G.add_edge(1,2,weight=3.14159)
Add edge attributes using add_edge(), add_edges_from(), subscript notation, or G.edge.
>>> G.add_edge(1, 2, weight=4.7 )
>>> G.add_edges_from([(3,4),(4,5)], color='red')
>>> G.add_edges_from([(1,2,{'color':'blue'}), (2,3,{'weight':8})])
>>> G[1][2]['weight'] = 4.7
>>> G.edge[1][2]['weight'] = 4
Now takes optional keyword=value attributes on initialization.
>>> G=nx.Graph(year='2009',city='New York')
Now takes optional keyword=value attributes or a dictionary of attributes.
>>> G.add_node(1,room=714)
Now takes optional keyword=value attributes or a dictionary of attributes applied to all affected nodes.
>>> G.add_nodes_from([1,2],time='2pm') # all nodes have same attribute
Now takes optional keyword=value attributes or a dictionary of attributes.
>>> G.add_edge(1, 2, weight=4.7 )
Now takes optional keyword=value attributes or a dictionary of attributes applied to all affected edges.
>>> G.add_edges_from([(3,4),(4,5)], color='red') >>> G.add_edges_from([(1,2,{'color':'blue'}), (2,3,{'weight':8})])
New keyword data=True|False keyword determines whether to return two-tuples (n,dict) (True) with node attribution dictionary
>>> G=nx.Graph([(1,2),(3,4)]) >>> G.nodes(data=True) [(1, {}), (2, {}), (3, {}), (4, {})]
Now returns a deep copy of the graph (copies all underlying data and attributes for nodes and edges). Use the class initializer to make a shallow copy:
>>> G=nx.Graph() >>> G_shallow=nx.Graph(G) # shallow copy >>> G_deep=G.copy() # deep copy
Now returns a deep copy of the graph (copies all underlying data and attributes for nodes and edges). Use the class initializer to make a shallow copy:
>>> G=nx.Graph() >>> D_shallow=nx.DiGraph(G) # shallow copy >>> D_deep=G.to_directed() # deep copy
With copy=True now returns a deep copy of the graph (copies all underlying data and attributes for nodes and edges).
>>> G=nx.Graph() >>> # note: copy keyword deprecated in networkx>1.0 >>> # H=G.subgraph([],copy=True) # deep copy of all data
Now take optional keyword=value attributes or a dictionary of attributes which are applied to all edges affected by the method.
>>> G=nx.Graph() >>> G.add_path([0,1,2,3],width=3.2)
The preferred name is now remove_node().
No longer raises an exception on an attempt to delete a node not in the graph. The preferred name is now remove_nodes_from().
Now raises an exception on an attempt to delete an edge not in the graph. The preferred name is now remove_edge().
Renamed to get_edge_data(). Returns the edge attribute dictionary.
The fastest way to get edge data for edge (u,v) is to use G[u][v] instead of G.get_edge_data(u,v)
Use methods G.is_directed() and G.is_multigraph(). All graphs are weighted graphs now if they have numeric values in the ‘weight’ edge attribute.
Convenience method to add weighted edges to graph using a list of 3-tuples (u,v,weight).
Renamed from get_edge().
The fastest way to get edge data for edge (u,v) is to use G[u][v] instead of G.get_edge_data(u,v)
replaces member G.directed
replaces member G.multigraph
ego_graph, stochastic_graph, PageRank algorithm, HITS algorithm, GraphML writer, freeze, is_frozen, A* algorithm, directed scale-free generator, random clustered graph.
Edge information is now stored in an attribution dictionary so all edge data must be given a key to identify it.
There is currently only one standard/reserved key, ‘weight’, which is used by algorithms and functions that use weighted edges. The associated value should be numeric. All other keys are available for users to assign as needed.
>>> G=nx.Graph()
>>> G.add_edge(1,2,weight=3.1415) # add the edge 1-2 with a weight
>>> G[1][2]['weight']=2.3 # set the weight to 2.3
Similarly, for direct access the edge data, use the key of the edge data to retrieve it.
>>> w = G[1][2]['weight']
All NetworkX algorithms that require/use weighted edges now use the ‘weight’ edge attribute. If you have existing algorithms that assumed the edge data was numeric, you should replace G[u][v] and G.get_edge(u,v) with G[u][v][‘weight’].
An idiom for getting a weight for graphs with or without an assigned weight key is
>>> w= G[1][2].get('weight',1) # set w to 1 if there is no 'weight' key
The version networkx-0.99 is the penultimate release before networkx-1.0. We have bumped the version from 0.37 to 0.99 to indicate (in our unusual version number scheme) that this is a major change to NetworkX.
We have made some significant changes, detailed below, to NetworkX to improve performance, functionality, and clarity.
Version 0.99 requires Python 2.4 or greater.
Please send comments and questions to the networkx-discuss mailing list. http://groups.google.com/group/networkx-discuss
The most significant changes are in the graph classes. We have redesigned the Graph() and DiGraph() classes to optionally allow edge data. This change allows Graph and DiGraph to naturally represent weighted graphs and to hold arbitrary information on edges.
- Both Graph and DiGraph take an optional argument weighted=True|False. When weighted=True the graph is assumed to have numeric edge data (with default 1). The Graph and DiGraph classes in earlier versions used the Python None as data (which is still allowed as edge data).
- The Graph and DiGraph classes now allow self loops.
- The XGraph and XDiGraph classes are removed and replaced with MultiGraph and MultiDiGraph. MultiGraph and MultiDiGraph optionally allow parallel (multiple) edges between two nodes.
The mapping from old to new classes is as follows:
- Graph -> Graph (self loops allowed now, default edge data is 1)
- DiGraph -> DiGraph (self loops allowed now, default edge data is 1)
- XGraph(multiedges=False) -> Graph
- XGraph(multiedges=True) -> MultiGraph
- XDiGraph(multiedges=False) -> DiGraph
- XDiGraph(multiedges=True) -> MultiDiGraph
New keyword data=True|False keyword determines whether to return two-tuples (u,v) (False) or three-tuples (u,v,d) (True)
The preferred name is now remove_node().
No longer raises an exception on an attempt to delete a node not in the graph. The preferred name is now remove_nodes_from().
Now raises an exception on an attempt to delete an edge not in the graph. The preferred name is now remove_edge().
The preferred name is now remove_edges_from().
The add_edge() method no longer accepts an edge tuple (u,v) directly. The tuple must be unpacked into individual nodes.
>>> import networkx as nx >>> u='a' >>> v='b' >>> e=(u,v) >>> G=nx.Graph()Old
>>> # G.add_edge((u,v)) # or G.add_edge(e)New
>>> G.add_edge(*e) # or G.add_edge(*(u,v))The * operator unpacks the edge tuple in the argument list.
Add edge now has a data keyword parameter for setting the default (data=1) edge data.
>>> # G.add_edge('a','b','foo') # add edge with string "foo" as data >>> # G.add_edge(1,2,5.0) # add edge with float 5 as data
Now can take list or iterator of either 2-tuples (u,v), 3-tuples (u,v,data) or a mix of both.
Now has data keyword parameter (default 1) for setting the edge data for any edge in the edge list that is a 2-tuple.
The has_edge() method no longer accepts an edge tuple (u,v) directly. The tuple must be unpacked into individual nodes.
Old:
>>> # G.has_edge((u,v)) # or has_edge(e)New:
>>> G.has_edge(*e) # or has_edge(*(u,v)) TrueThe * operator unpacks the edge tuple in the argument list.
Now has the keyword argument “default” to specify what value to return if no edge is found. If not specified an exception is raised if no edge is found.
The fastest way to get edge data for edge (u,v) is to use G[u][v] instead of G.get_edge(u,v)
The degree_iter method now returns an iterator over pairs of (node, degree). This was the previous behavior of degree_iter(with_labels=true) Also there is a new keyword weighted=False|True for weighted degree.
The argument inplace=False|True has been replaced with copy=True|False.
Subgraph no longer takes create_using keyword. To change the graph type either make a copy of the graph first and then change type or change type and make a subgraph. E.g.
>>> G=nx.path_graph(5) >>> H=nx.DiGraph(G.subgraph([0,1])) # digraph of copy of induced subgraph
Getting node neighbors from the graph with G[v] now returns a dictionary.
>>> G=nx.path_graph(5) >>> # G[0] # {1: 1}To get a list of neighbors you can either use the keys of that dictionary or use
>>> G.neighbors(0) [1]This change allows algorithms to use the underlying dict-of-dict representation through G[v] for substantial performance gains. Warning: The returned dictionary should not be modified as it may corrupt the graph data structure. Make a copy G[v].copy() if you wish to modify the dict.
now a function
>>> G=nx.Graph(name='test me') >>> nx.info(G) Name: test me Type: Graph Number of nodes: 0 Number of edges: 0
now a function
now a function
use the directed attribute
>>> G=nx.DiGraph() >>> # G.directed # True
use G.edges()
use
>>> G=nx.DiGraph() >>> R=G.reverse() >>> R.edges() []or
>>> [(v,u) for (u,v) in G.edges()] []
Some of the code modules were moved into subdirectories.
Import statements such as:
import networkx.centrality
from networkx.centrality import *
may no longer work (including that example).
Use either
>>> import networkx # e.g. centrality functions available as networkx.fcn()
or
>>> from networkx import * # e.g. centrality functions available as fcn()
For Graph and DiGraph self loops are now allowed. This might affect code or algorithms that add self loops which were intended to be ignored.
Use the methods
- nodes_with_selfloops()
- selfloop_edges()
- number_of_selfloops()
to discover any self loops.
Copies of NetworkX graphs including using the copy() method now return complete copies of the graph. This means that all connection information is copied–subsequent changes in the copy do not change the old graph. But node keys and edge data in the original and copy graphs are pointers to the same data.
Used internally - now called nbunch_iter and returns an iterator.
Mostly you can just run the code and python will raise an exception for features that changed. Common places for changes are
- Converting XGraph() to either Graph or MultiGraph
- Converting XGraph.edges() to Graph.edges(data=True)
- Switching some rarely used methods to attributes (e.g. directed) or to functions (e.g. node_boundary)
- If you relied on the old default edge data being None, you will have to account for it now being 1.
You may also want to look through your code for places which could improve speed or readability. The iterators are helpful with large graphs and getting edge data via G[u][v] is quite fast. You may also want to change G.neighbors(n) to G[n] which returns the dict keyed by neighbor nodes to the edge data. It is faster for many purposes but does not work well when you are changing the graph.
Release date: 13 September 2014
Bugfix release for minor installation and documentation issues.
https://github.com/networkx/networkx/milestones/networkx-1.9.1
Release date: 21 June 2014
Support for Python 3.1 is dropped in this release.
Release date: 28 July 2013
For full details of the issues closed for this release (added features and bug fixes) see: https://github.com/networkx/networkx/issues?milestone=1&page=1&state=closed
Release date: 4 July 2012
For full details of the tickets closed for this release (added features and bug fixes) see: https://networkx.lanl.gov/trac/query?status=closed&group=milestone&milestone=networkx-1.7
Release date: 20 November 2011
New functions for finding articulation points, generating random bipartite graphs, constructing adjacency matrix representations, forming graph products, computing assortativity coefficients, measuring subgraph centrality and communicability, finding k-clique communities, and writing JSON format output.
New examples for drawing with D3 Javascript library, and ordering matrices with the Cuthill-McKee algorithm.
More memory efficient implementation of current-flow betweenness and new approximation algorithms for current-flow betweenness and shortest-path betweenness.
Simplified handling of “weight” attributes for algorithms that use weights/costs/values. See Version 1.6 notes and API changes.
Updated all code to work with the PyPy Python implementation http://pypy.org which produces faster performance on many algorithms.
For full details of the tickets closed for this release (added features and bug fixes) see: https://networkx.lanl.gov/trac/query?status=closed&group=milestone&milestone=networkx-1.6
Release date: 4 June 2011
For full details of the tickets closed for this release see: https://networkx.lanl.gov/trac/query?status=closed&group=milestone&milestone=networkx-1.5
- Algorithms for
generating
andanalyzing
bipartite graphsMaximal independent set
algorithmErdős-Gallai graphical degree sequence test
Negative edge cycle test
- More memory efficient
Dijkstra path length
with cutoff parameterWeighted clustering coefficient
- Read and write version 1.2 of
GEXF reader
formatNeighbor degree correlation
that handle subsets of nodesIn-place node relabeling
- Many ‘weighted’ graph algorithms now take optional parameter to use specified edge attribute (default=’weight’) (:ticket:`509`)
- Test for
distance regular
graphs- Fast
directed Erdős-Renyi graph
generator- Fast
expected degree graph
generatorNavigable small world
generatorWaxman model
generatorGeographical threshold graph
generatorKarate Club, Florentine Families, and Davis' Women's Club
graphs
- Fix edge handling for multigraphs in networkx/graphviz interface (:ticket:`507`)
- Update networkx/pydot interface for new versions of pydot (:ticket:`506`), (:ticket:`535`)
- Fix negative cycle handling in Bellman-Ford (:ticket:`502`)
- Write more attributes with GraphML and GML formats (:ticket:`480`)
- Handle white space better in read_edgelist (:ticket:`513`)
- Better parsing of Pajek format files (:ticket:`524`) (:ticket:`542`)
- Isolates functions work with directed graphs (:ticket:`526`)
- Faster conversion to numpy matrices (:ticket:`529`)
- Add graph[‘name’] and use properties to access Graph.name (:ticket:`544`)
- Topological sort confused None and 0 (:ticket:`546`)
- GEXF writer mishandled weight=0 (:ticket:`550`)
- Speedup in SciPy version of PageRank (:ticket:`554`)
- Numpy PageRank node order incorrect + speedups (:ticket:`555`)
Release date: 23 January 2011
k-shell,k-crust,k-corona
read GraphML files from yEd
read/write GEXF format files
find cycles in a directed graph
DFS
andBFS
algorithmschordal graph functions
Prim's algorithm for minimum spanning tree
r-ary tree generator
rich club coefficient
- NumPy matrix version of
Floyd's algorithm for all-pairs shortest path
read GIS shapefiles
functions to get and set node and edge attributes
- and more, see https://networkx.lanl.gov/trac/query?status=closed&group=milestone&milestone=networkx-1.4
gnp_random_graph()
now takes a directed=True|False keyword instead of create_usinggnm_random_graph()
now takes a directed=True|False keyword instead of create_using
Release date: 28 August 2010
See: https://networkx.lanl.gov/trac/timeline
- Works with Python versions 2.6, 2.7, 3.1, and 3.2 (but not 2.4 and 2.5).
Minimum cost flow algorithms
Bellman-Ford shortest paths
GraphML reader and writer
More exception/error types
- Updated many tests to unittest style. Run with: “import networkx; networkx.test()” (requires nose testing package)
- and more, see https://networkx.lanl.gov/trac/query?status=closed&group=milestone&milestone=networkx-1.3
Release date: 28 July 2010
See: https://networkx.lanl.gov/trac/timeline
Ford-Fulkerson max flow and min cut
Closeness vitality
Eulerian circuits
Functions for isolates
Simpler s_max generator
- Compatible with IronPython-2.6
- Improved testing functionality: import networkx; networkx.test() tests entire package and skips tests with missing optional packages
- All tests work with Python-2.4
- and more, see https://networkx.lanl.gov/trac/query?status=closed&group=milestone&milestone=networkx-1.2
Release date: 21 April 2010
See: https://networkx.lanl.gov/trac/timeline
Algorithm for finding a basis for graph cycles
Blockmodeling
Assortativity and mixing matrices
in-degree and out-degree centrality
Attracting components
andcondensation
.Weakly connected components
Simpler interface to shortest path algorithms
Edgelist format to read and write data with attributes
Attribute matrices
GML reader for nested attributes
- Current-flow (random walk)
betweenness
andcloseness
.Directed configuration model
, anddirected random graph model
.- Improved documentation of drawing, shortest paths, and other algorithms
- Many more tests, can be run with “import networkx; networkx.test()”
- and much more, see https://networkx.lanl.gov/trac/query?status=closed&group=milestone&milestone=networkx-1.1
Several of the algorithms and the degree() method now return dictionaries keyed by node instead of lists. In some cases there was a with_labels keyword which is no longer necessary. For example,
>>> G=nx.Graph()
>>> G.add_edge('a','b')
>>> G.degree() # returns dictionary of degree keyed by node
{'a': 1, 'b': 1}
Asking for the degree of a single node still returns a single number
>>> G.degree('a')
1
The following now return dictionaries by default (instead of lists) and the with_labels keyword has been removed:
Graph.degree()
,MultiGraph.degree()
,DiGraph.degree()
,DiGraph.in_degree()
,DiGraph.out_degree()
,MultiDiGraph.degree()
,MultiDiGraph.in_degree()
,MultiDiGraph.out_degree()
.clustering()
,triangles()
node_clique_number()
,number_of_cliques()
,cliques_containing_node()
eccentricity()
The following now return dictionaries by default (instead of lists)
pagerank()
hits()
add_nodes_from now accepts (node,attrdict) two-tuples
>>> G=nx.Graph()
>>> G.add_nodes_from([(1,{'color':'red'})])
- Support graph attributes with union, intersection, and other graph operations
- Improve subgraph speed (and related algorithms such as connected_components_subgraphs())
- Handle multigraphs in more operators (e.g. union)
- Handle double-quoted labels with pydot
- Normalize betweenness_centrality for undirected graphs correctly
- Normalize eigenvector_centrality by l2 norm
read_gml()
now returns multigraphs
Release date: 11 Jan 2010
See: https://networkx.lanl.gov/trac/timeline
Bug fix release for missing setup.py in manifest.
Release date: 8 Jan 2010
See: https://networkx.lanl.gov/trac/timeline
This release has significant changes to parts of the graph API to allow graph, node, and edge attributes. See http://networkx.lanl.gov//reference/api_changes.html
- Update Graph, DiGraph, and MultiGraph classes to allow attributes.
- Default edge data is now an empty dictionary (was the integer 1)
- Difference and intersection operators
- Average shortest path
- A* (A-Star) algorithm
- PageRank, HITS, and eigenvector centrality
- Read Pajek files
- Line graphs
- Minimum spanning tree (Kruskal’s algorithm)
- Dense and sparse Fruchterman-Reingold layout
- Random clustered graph generator
- Directed scale-free graph generator
- Faster random regular graph generator
- Improved edge color and label drawing with Matplotlib
- and much more, see https://networkx.lanl.gov/trac/query?status=closed&group=milestone&milestone=networkx-1.0
- Update to work with networkx-1.0 API
- Graph subclass example
Release date: 18 November 2008
See: https://networkx.lanl.gov/trac/timeline
This release has significant changes to parts of the graph API. See http://networkx.lanl.gov//reference/api_changes.html
- Update Graph and DiGraph classes to use weighted graphs as default Change in API for performance and code simplicity.
- New MultiGraph and MultiDiGraph classes (replace XGraph and XDiGraph)
- Update to use Sphinx documentation system http://networkx.lanl.gov/
- Developer site at https://networkx.lanl.gov/trac/
- Experimental LabeledGraph and LabeledDiGraph
- Moved package and file layout to subdirectories.
- handle root= option to draw_graphviz correctly
- Update to work with networkx-0.99 API
- Drawing examples now use matplotlib.pyplot interface
- Improved drawings in many examples
- New examples - see http://networkx.lanl.gov/examples/
Release date: 17 August 2008
See: https://networkx.lanl.gov/trac/timeline
NetworkX now requires Python 2.4 or later for full functionality.
- Edge coloring and node line widths with Matplotlib drawings
- Update pydot functions to work with pydot-1.0.2
- Maximum-weight matching algorithm
- Ubigraph interface for 3D OpenGL layout and drawing
- Pajek graph file format reader and writer
- p2g graph file format reader and writer
- Secondary sort in topological sort
- Better edge data handling with GML writer
- Edge betweenness fix for XGraph with default data of None
- Handle Matplotlib version strings (allow “pre”)
- Interface to PyGraphviz (to_agraph()) now handles parallel edges
- Fix bug in copy from XGraph to XGraph with multiedges
- Use SciPy sparse lil matrix format instead of coo format
- Clear up ambiguous cases for Barabasi-Albert model
- Better care of color maps with Matplotlib when drawing colored nodes and edges
- Fix error handling in layout.py
- Ubigraph examples showing 3D drawing
Release date: 13 January 2008
See: https://networkx.lanl.gov/trac/timeline
- GML format graph reader, tests, and example (football.py)
- edge_betweenness() and load_betweenness()
- remove obsolete parts of pygraphviz interface
- improve handling of Matplotlib version strings
- write_dot() now writes parallel edges and self loops
- is_bipartite() and bipartite_color() fixes
- configuration model speedup using random.shuffle()
- convert with specified nodelist now works correctly
- vf2 isomorphism checker updates
Release date: 27 July 2007
See: https://networkx.lanl.gov/trac/timeline
Small update to fix import readwrite problem and maintain Python2.3 compatibility.
Release date: 22 July 2007
See: https://networkx.lanl.gov/trac/timeline
- algorithms for strongly connected components.
- Brandes betweenness centrality algorithm (weighted and unweighted versions)
- closeness centrality for weighted graphs
- dfs_preorder, dfs_postorder, dfs_tree, dfs_successor, dfs_predecessor
- readers for GraphML, LEDA, sparse6, and graph6 formats.
- allow arguments in graphviz_layout to be passed directly to graphviz
- more detailed installation instructions
- replaced dfs_preorder,dfs_postorder (see search.py)
- allow initial node positions in spectral_layout
- report no error on attempting to draw empty graph
- report errors correctly when using tuples as nodes #114
- handle conversions from incomplete dict-of-dict data
Release date: 12 April 2007
See: https://networkx.lanl.gov/trac/timeline
- benchmarks for graph classes
- Brandes betweenness centrality algorithm
- Dijkstra predecessor and distance algorithm
- xslt to convert DIA graphs to NetworkX
- number_of_edges(u,v) counts edges between nodes u and v
- run tests with python setup_egg.py test (needs setuptools) else use python -c “import networkx; networkx.test()”
- is_isomorphic() that uses vf2 algorithm
- speedups of neighbors()
- simplified Dijkstra’s algorithm code
- better exception handling for shortest paths
- get_edge(u,v) returns None (instead of exception) if no edge u-v
- floyd_warshall_array fixes for negative weights
- bad G467, docs, and unittest fixes for graph atlas
- don’t put nans in numpy or scipy sparse adjacency matrix
- handle get_edge() exception (return None if no edge)
- remove extra kwds arguments in many places
- no multi counting edges in conversion to dict of lists for multigraphs
- allow passing tuple to get_edge()
- bad parameter order in node/edge betweenness
- edge betweenness doesn’t fail with XGraph
- don’t throw exceptions for nodes not in graph (silently ignore instead) in edges_* and degree_*
Release date: 27 November 2006
See: https://networkx.lanl.gov/trac/timeline
draw edges with specified colormap
more efficient version of Floyd’s algorithm for all pairs shortest path
use numpy only, Numeric is deprecated
include tests in source package (networkx/tests)
include documentation in source package (doc)
- tests can now be run with
>>> import networkx >>> networkx.test()
- read_gpickle now works correctly with Windows
- refactored large modules into smaller code files
- degree(nbunch) now returns degrees in same order as nbunch
- degree() now works for multiedges=True
- update node_boundary and edge_boundary for efficiency
- edited documentation for graph classes, now mostly in info.py
- Draw edges with colormap
Release date: 29 September 2006
See: https://networkx.lanl.gov/trac/timeline
- Update to work with numpy-1.0x
- Make egg usage optional: use python setup_egg.py bdist_egg to build egg
- Generators and functions for bipartite graphs
- Experimental classes for trees and forests
- Support for new pygraphviz update (in nx_agraph.py) , see http://networkx.lanl.gov/pygraphviz/ for pygraphviz details
- Handle special cases correctly in triangles function
- Typos in documentation
- Handle special cases in shortest_path and shortest_path_length, allow cutoff parameter for maximum depth to search
- Update examples: erdos_renyi.py, miles.py, roget,py, eigenvalues.py
- Expected degree sequence
- New pygraphviz interface
Release date: 20 July 2006
See: https://networkx.lanl.gov/trac/timeline
- arbitrary node relabeling (use relabel_nodes)
- conversion of NetworkX graphs to/from Python dict/list types, numpy matrix or array types, and scipy_sparse_matrix types
- generator for random graphs with given expected degree sequence
- Allow drawing graphs with no edges using pylab
- Use faster heapq in dijkstra
- Don’t complain if X windows is not available
- update drawing examples
Release date: 23 June 2006
See: https://networkx.lanl.gov/trac/timeline
- update to work with Python 2.5
- bidirectional version of shortest_path and Dijkstra
- single_source_shortest_path and all_pairs_shortest_path
- s-metric and experimental code to generate maximal s-metric graph
- double_edge_swap and connected_double_edge_swap
- Floyd’s algorithm for all pairs shortest path
- read and write unicode graph data to text files
- read and write YAML format text files, http://yaml.org
- speed improvements (faster version of subgraph, is_connected)
- added cumulative distribution and modified discrete distribution utilities
- report error if DiGraphs are sent to connected_components routines
- removed with_labels keywords for many functions where it was causing confusion
- function name changes in shortest_path routines
- saner internal handling of nbunch (node bunches), raise an exception if an nbunch isn’t a node or iterable
- better keyword handling in io.py allows reading multiple graphs
- don’t mix Numeric and numpy arrays in graph layouts and drawing
- avoid automatically rescaling matplotlib axes when redrawing graph layout
- unicode node labels
Release date: 28 April 2006
See: https://networkx.lanl.gov/trac/timeline
- Algorithms for betweenness, eigenvalues, eigenvectors, and spectral projection for threshold graphs
- Use numpy when available
- dense_gnm_random_graph generator
- Generators for some directed graphs: GN, GNR, and GNC by Krapivsky and Redner
- Grid graph generators now label by index tuples. Helper functions for manipulating labels.
- relabel_nodes_with_function
- Betweenness centrality now correctly uses Brandes definition and has normalization option outside main loop
- Empty graph now labeled as empty_graph(n)
- shortest_path_length used python2.4 generator feature
- degree_sequence_tree off by one error caused nonconsecutive labeling
- periodic_grid_2d_graph removed in favor of grid_2d_graph with periodic=True
Release date: 13 March 2006
See: https://networkx.lanl.gov/trac/timeline
- Option to construct Laplacian with rows and columns in specified order
- Option in convert_node_labels_to_integers to use sorted order
- predecessor(G,n) function that returns dictionary of nodes with predecessors from breadth-first search of G starting at node n. https://networkx.lanl.gov/trac/ticket/26
- Formation of giant component in binomial_graph:
- Chess masters matches:
- Gallery https://networkx.lanl.gov/gallery.html
- Adjusted names for random graphs.
- erdos_renyi_graph=binomial_graph=gnp_graph: n nodes with edge probability p
- gnm_graph: n nodes and m edges
- fast_gnp_random_graph: gnp for sparse graphs (small p)
Documentation contains correct spelling of Barabási, Bollobás, Erdős, and Rényi in UTF-8 encoding
Increased speed of connected_components and related functions by using faster BFS algorithm in networkx.paths https://networkx.lanl.gov/trac/ticket/27
XGraph and XDiGraph with multiedges=True produced error on delete_edge
Cleaned up docstring errors
Normalize names of some graphs to produce strings that represent calling sequence
Release date: 5 February 2006
See: https://networkx.lanl.gov/trac/timeline
- sparse_binomial_graph: faster graph generator for sparse random graphs
- read/write routines in io.py now handle XGraph() type and gzip and bzip2 files
- optional mapping of type for read/write routine to allow on-the-fly conversion of node and edge datatype on read
- Substantial changes related to digraphs and definitions of neighbors() and edges(). For digraphs edges=out_edges. Neighbors now returns a list of neighboring nodes with possible duplicates for graphs with parallel edges See https://networkx.lanl.gov/trac/ticket/24
- Addition of out_edges, in_edges and corresponding out_neighbors and in_neighbors for digraphs. For digraphs edges=out_edges.
- Minard’s data for Napoleon’s Russian campaign
- XGraph(multiedges=True) returns a copy of the list of edges for get_edge()
Release date: 6 January 2006
- Simpler interface to drawing with pylab
- G.info(node=None) function returns short information about graph or node
- adj_matrix now takes optional nodelist to force ordering of rows/columns in matrix
- optional pygraphviz and pydot interface to graphviz is now callable as “graphviz” with pygraphviz preferred. Use draw_graphviz(G).
- Several new examples showing how draw to graphs with various properties of nodes, edges, and labels
- Default data type for all graphs is now None (was the integer 1)
- add_nodes_from now won’t delete edges if nodes added already exist
- Added missing names to generated graphs
- Indexes for nodes in graphs start at zero by default (was 1)
Release date: 5 December 2005
- Uses setuptools for installation http://peak.telecommunity.com/DevCenter/setuptools
- Improved testing infrastructure, can now run python setup.py test
- Added interface to draw graphs with pygraphviz https://networkx.lanl.gov/pygraphviz/
- is_directed() function call
- Email example shows how to use XDiGraph with Python objects as edge data
- Reformat menu, minor changes to Readme, better stylesheet
- use create_using= instead of result= keywords for graph types in all cases
- missing weights for degree 0 and 1 nodes in clustering
- configuration model now uses XGraph, returns graph with identical degree sequence as input sequence
- fixed Dijkstra priority queue
- fixed non-recursive toposort and is_directed_acyclic graph
Release date: 20 August 2005
- Update of Dijkstra algorithm code
- dfs_successor now calls proper search method
- Changed to list comprehension in DiGraph.reverse() for python2.3 compatibility
- Barabasi-Albert graph generator fixed
- Attempt to add self loop should add node even if parallel edges not allowed
Release date: 14 July 2005
The NetworkX web locations have changed:
http://networkx.lanl.gov/ - main documentation site http://networkx.lanl.gov/svn/ - subversion source code repository https://networkx.lanl.gov/trac/ - bug tracking and info
The naming conventions in NetworkX have changed. The package name “NX” is now “networkx”.
The suggested ways to import the NetworkX package are
- import networkx
- import networkx as NX
- from networkx import *
DiGraph reverse
- Graph generators
- watts_strogatz_graph now does rewiring method
- old watts_strogatz_graph->newman_watts_strogatz_graph
- Changed to reflect NX-networkx change
- main site is now https://networkx.lanl.gov/
- Fixed logic in io.py for reading DiGraphs.
- Path based centrality measures (betweenness, closeness) modified so they work on graphs that are not connected and produce the same result as if each connected component were considered separately.
Release date: 17 June 2005
Topological sort, testing for directed acyclic graphs (DAGs)
Dijkstra’s algorithm for shortest paths in weighted graphs
Multidimensional layout with dim=n for drawing
3d rendering demonstration with vtk
- Graph generators
- random_powerlaw_tree
- dorogovtsev_goltsev_mendes_graph
- Kevin Bacon movie actor graph: Examples/kevin_bacon.py
- Compute eigenvalues of graph Laplacian: Examples/eigenvalues.py
- Atlas of small graphs: Examples/atlas.py
- Rewrite of setup scripts to install documentation and tests in documentation directory specified
- Handle calls to edges() with non-node, non-iterable items.
- truncated_tetrahedral_graph was just plain wrong
- Speedup of betweenness_centrality code
- bfs_path_length now returns correct lengths
- Catch error if target of search not in connected component of source
- Code cleanup to label internal functions with _name
- Changed import statement lines to always use “import NX” to protect name-spaces
- Other minor bug-fixes and testing added
[BA02] | R. Albert and A.-L. Barabási, “Statistical mechanics of complex networks”, Reviews of Modern Physics, 74, pp. 47-97, 2002. :arxiv:`cond-mat/0106096` |
[Bollobas01] | B. Bollobás, “Random Graphs”, Second Edition, Cambridge University Press, 2001. |
[BE05] | U. Brandes and T. Erlebach, “Network Analysis: Methodological Foundations”, Lecture Notes in Computer Science, Volume 3418, Springer-Verlag, 2005. |
[CL1996] | G. Chartrand and L. Lesniak, “Graphs and Digraphs”, Chapman and Hall/CRC, 1996. |
[choudum1986] | S.A. Choudum. “A simple proof of the Erdős-Gallai theorem on graph sequences.” Bulletin of the Australian Mathematical Society, 33, pp 67-70, 1986. :doi:`10.1017/S0004972700002872` |
[Diestel97] | R. Diestel, “Graph Theory”, Springer-Verlag, 1997. :url:`http://diestel-graph-theory.com/index.html` |
[DM03] | S.N. Dorogovtsev and J.F.F. Mendes, “Evolution of Networks”, Oxford University Press, 2003. |
[EppsteinPads] | David Eppstein. PADS, A library of Python Algorithms and Data Structures. :url:`http://www.ics.uci.edu/~eppstein/PADS` |
[EG1960] | Erdős and Gallai, Mat. Lapok 11 264, 1960. |
[hakimi1962] | Hakimi, S. “On the Realizability of a Set of Integers as Degrees of the Vertices of a Graph.” SIAM J. Appl. Math. 10, 496-506, 1962. |
[havel1955] | Havel, V. “A Remark on the Existence of Finite Graphs” Casopis Pest. Mat. 80, 477-480, 1955. |
[Langtangen04] | H.P. Langtangen, “Python Scripting for Computational Science.”, Springer Verlag Series in Computational Science and Engineering, 2004. |
[Martelli03] | A. Martelli, “Python in a Nutshell”, O’Reilly Media Inc, 2003. |
[Newman03] | M.E.J. Newman, “The Structure and Function of Complex Networks”, SIAM Review, 45, pp. 167-256, 2003. :url:`http://epubs.siam.org/doi/abs/10.1137/S003614450342480` |
[Sedgewick02] | R. Sedgewick, “Algorithms in C: Parts 1-4: Fundamentals, Data Structure, Sorting, Searching”, Addison Wesley Professional, 3rd ed., 2002. |
[Sedgewick01] | R. Sedgewick, “Algorithms in C, Part 5: Graph Algorithms”, Addison Wesley Professional, 3rd ed., 2001. |
[West01] | D. B. West, “Introduction to Graph Theory”, Prentice Hall, 2nd ed., 2001. |
[vanRossum98] | Guido van Rossum. Python Patterns - Implementing Graphs, 1998. :url:`http://www.python.org/doc/essays/graphs` |