summaryrefslogtreecommitdiff
path: root/networkx/classes/digraph.py
diff options
context:
space:
mode:
Diffstat (limited to 'networkx/classes/digraph.py')
-rw-r--r--networkx/classes/digraph.py182
1 files changed, 16 insertions, 166 deletions
diff --git a/networkx/classes/digraph.py b/networkx/classes/digraph.py
index 887bafbc..60a202ff 100644
--- a/networkx/classes/digraph.py
+++ b/networkx/classes/digraph.py
@@ -217,6 +217,20 @@ class DiGraph(Graph):
dict which holds attrbute values keyed by attribute name.
It should require no arguments and return a dict-like object.
+ Typically, if your extension doesn't impact the data structure all
+ methods will inherited without issue except: `to_directed/to_undirected`.
+ By default these methods create a DiGraph/Graph class and you probably
+ want them to create your extension of a DiGraph/Graph. To facilitate
+ this we define two class variables that you can set in your subclass.
+
+ to_directed_class : callable, (default: DiGraph or MultiDiGraph)
+ Class to create a new graph structure in the `to_directed` method.
+ If `None`, a NetworkX class (DiGraph or MultiDiGraph) is used.
+
+ to_undirected_class : callable, (default: Graph or MultiGraph)
+ Class to create a new graph structure in the `to_undirected` method.
+ If `None`, a NetworkX class (Graph or MultiGraph) is used.
+
Examples
--------
@@ -1037,107 +1051,6 @@ class DiGraph(Graph):
"""Return True if graph is directed, False otherwise."""
return True
- def fresh_copy(self):
- """Return a fresh copy graph with the same data structure.
-
- A fresh copy has no nodes, edges or graph attributes. It is
- the same data structure as the current graph. This method is
- typically used to create an empty version of the graph.
-
- Notes
- -----
- If you subclass the base class you should overwrite this method
- to return your class of graph.
- """
- return DiGraph()
-
- def copy(self, as_view=False):
- """Return a copy of the graph.
-
- The copy method by default returns an independent shallow copy
- of the graph and attributes. That is, if an attribute is a
- container, that container is shared by the original an the copy.
- Use Python's `copy.deepcopy` for new containers.
-
- If `as_view` is True then a view is returned instead of a copy.
-
- Notes
- -----
- All copies reproduce the graph structure, but data attributes
- may be handled in different ways. There are four types of copies
- of a graph that people might want.
-
- Deepcopy -- A "deepcopy" copies the graph structure as well as
- all data attributes and any objects they might contain.
- The entire graph object is new so that changes in the copy
- do not affect the original object. (see Python's copy.deepcopy)
-
- Data Reference (Shallow) -- For a shallow copy the graph structure
- is copied but the edge, node and graph attribute dicts are
- references to those in the original graph. This saves
- time and memory but could cause confusion if you change an attribute
- in one graph and it changes the attribute in the other.
- NetworkX does not provide this level of shallow copy.
-
- Independent Shallow -- This copy creates new independent attribute
- dicts and then does a shallow copy of the attributes. That is, any
- attributes that are containers are shared between the new graph
- and the original. This is exactly what `dict.copy()` provides.
- You can obtain this style copy using:
-
- >>> G = nx.path_graph(5)
- >>> H = G.copy()
- >>> H = G.copy(as_view=False)
- >>> H = nx.Graph(G)
- >>> H = G.fresh_copy().__class__(G)
-
- Fresh Data -- For fresh data, the graph structure is copied while
- new empty data attribute dicts are created. The resulting graph
- is independent of the original and it has no edge, node or graph
- attributes. Fresh copies are not enabled. Instead use:
-
- >>> H = G.fresh_copy()
- >>> H.add_nodes_from(G)
- >>> H.add_edges_from(G.edges)
-
- View -- Inspired by dict-views, graph-views act like read-only
- versions of the original graph, providing a copy of the original
- structure without requiring any memory for copying the information.
-
- See the Python copy module for more information on shallow
- and deep copies, https://docs.python.org/2/library/copy.html.
-
- Parameters
- ----------
- as_view : bool, optional (default=False)
- If True, the returned graph-view provides a read-only view
- of the original graph without actually copying any data.
-
- Returns
- -------
- G : Graph
- A copy of the graph.
-
- See Also
- --------
- to_directed: return a directed copy of the graph.
-
- Examples
- --------
- >>> G = nx.path_graph(4) # or DiGraph, MultiGraph, MultiDiGraph, etc
- >>> H = G.copy()
-
- """
- if as_view is True:
- return nx.graphviews.DiGraphView(self)
- G = self.fresh_copy()
- G.graph.update(self.graph)
- G.add_nodes_from((n, d.copy()) for n, d in self._node.items())
- G.add_edges_from((u, v, datadict.copy())
- for u, nbrs in self._adj.items()
- for v, datadict in nbrs.items())
- return G
-
def to_undirected(self, reciprocal=False, as_view=False):
"""Return an undirected representation of the digraph.
@@ -1195,8 +1108,9 @@ class DiGraph(Graph):
>>> list(G2.edges)
[(0, 1)]
"""
+ graph_class = self.to_undirected_class()
if as_view is True:
- return nx.graphviews.GraphView(self)
+ return nx.graphviews.generic_graph_view(self, Graph)
# deepcopy when not a view
G = Graph()
G.graph.update(deepcopy(self.graph))
@@ -1212,70 +1126,6 @@ class DiGraph(Graph):
for v, d in nbrs.items())
return G
- def subgraph(self, nodes):
- """Return a SubGraph view of the subgraph induced on `nodes`.
-
- The induced subgraph of the graph contains the nodes in `nodes`
- and the edges between those nodes.
-
- Parameters
- ----------
- nodes : list, iterable
- A container of nodes which will be iterated through once.
-
- Returns
- -------
- G : SubGraph View
- A subgraph view of the graph. The graph structure cannot be
- changed but node/edge attributes can and are shared with the
- original graph.
-
- Notes
- -----
- The graph, edge and node attributes are shared with the original graph.
- Changes to the graph structure is ruled out by the view, but changes
- to attributes are reflected in the original graph.
-
- To create a subgraph with its own copy of the edge/node attributes use:
- G.subgraph(nodes).copy()
-
- For an inplace reduction of a graph to a subgraph you can remove nodes:
- G.remove_nodes_from([n for n in G if n not in set(nodes)])
-
- Subgraph views are sometimes NOT what you want. In most cases where
- you want to do more than simply look at the induced edges, it makes
- more sense to just create the subgraph as its own graph with code like:
-
- ::
-
- # Create a subgraph SG based on a (possibly multigraph) G
- SG = G.fresh_copy()
- SG.add_nodes_from((n, G.nodes[n]) for n in largest_wcc)
- if SG.is_multigraph:
- SG.add_edges_from((n, nbr, key, d)
- for n, nbrs in G.adj.items() if n in largest_wcc
- for nbr, keydict in nbrs.items() if nbr in largest_wcc
- for key, d in keydict.items())
- else:
- SG.add_edges_from((n, nbr, d)
- for n, nbrs in G.adj.items() if n in largest_wcc
- for nbr, d in nbrs.items() if nbr in largest_wcc)
- SG.graph.update(G.graph)
-
- Examples
- --------
- >>> G = nx.path_graph(4) # or DiGraph, MultiGraph, MultiDiGraph, etc
- >>> H = G.subgraph([0, 1, 2])
- >>> list(H.edges)
- [(0, 1), (1, 2)]
- """
- induced_nodes = nx.filters.show_nodes(self.nbunch_iter(nodes))
- SubGraph = nx.graphviews.SubDiGraph
- # if already a subgraph, don't make a chain
- if hasattr(self, '_NODE_OK'):
- return SubGraph(self._graph, induced_nodes, self._EDGE_OK)
- return SubGraph(self, induced_nodes)
-
def reverse(self, copy=True):
"""Return the reverse of the graph.