#!/usr/bin/env python3# -*- coding: utf-8 -*-## This file digraph.py is referred and derived from project NetworkX,## https://github.com/networkx/networkx/blob/master/networkx/classes/digraph.py## which has the following license:## Copyright (C) 2004-2020, NetworkX Developers# Aric Hagberg <hagberg@lanl.gov># Dan Schult <dschult@colgate.edu># Pieter Swart <swart@lanl.gov># All rights reserved.## This file is part of NetworkX.## NetworkX is distributed under a BSD license; see LICENSE.txt for more# information.#importnetworkx.classes.functionasfuncfromgraphscope.nx.classes.cacheimportget_node_datafromgraphscope.nx.utils.compatimportpatch_docstring__all__=["nodes","edges","degree","degree_histogram","neighbors","number_of_nodes","number_of_edges","density","is_directed","info","freeze","is_frozen","subgraph","induced_subgraph","edge_subgraph","to_directed","to_undirected","add_star","add_path","add_cycle","create_empty_copy","all_neighbors","non_neighbors","non_edges","common_neighbors","set_node_attributes","get_node_attributes","set_edge_attributes","get_edge_attributes","is_weighted","is_negatively_weighted","is_empty","selfloop_edges","nodes_with_selfloops","number_of_selfloops",]# forward the NetworkX functionsfromnetworkx.classes.functionimportadd_cyclefromnetworkx.classes.functionimportadd_pathfromnetworkx.classes.functionimportadd_starfromnetworkx.classes.functionimportall_neighborsfromnetworkx.classes.functionimportcommon_neighborsfromnetworkx.classes.functionimportcreate_empty_copyfromnetworkx.classes.functionimportdegreefromnetworkx.classes.functionimportdegree_histogramfromnetworkx.classes.functionimportdensityfromnetworkx.classes.functionimportedgesfromnetworkx.classes.functionimportfreezefromnetworkx.classes.functionimportget_edge_attributesfromnetworkx.classes.functionimportget_node_attributesfromnetworkx.classes.functionimportinfofromnetworkx.classes.functionimportis_directedfromnetworkx.classes.functionimportis_emptyfromnetworkx.classes.functionimportis_frozenfromnetworkx.classes.functionimportis_negatively_weightedfromnetworkx.classes.functionimportis_weightedfromnetworkx.classes.functionimportneighborsfromnetworkx.classes.functionimportnodesfromnetworkx.classes.functionimportnodes_with_selfloopsfromnetworkx.classes.functionimportnon_edgesfromnetworkx.classes.functionimportnon_neighborsfromnetworkx.classes.functionimportnumber_of_edgesfromnetworkx.classes.functionimportnumber_of_nodesfromnetworkx.classes.functionimportselfloop_edgesfromnetworkx.classes.functionimportsubgraphfromnetworkx.classes.functionimportto_directedfromnetworkx.classes.functionimportto_undirected
[docs]definduced_subgraph(G,nbunch):"""Returns a independent deep copy subgraph induced on nbunch. The induced subgraph of a graph on a set of nodes N is the graph with nodes N and edges from G which have both ends in N. Parameters ---------- G : NetworkX Graph nbunch : node, container of nodes or None (for all nodes) Returns ------- subgraph : SubGraph A independent deep copy of the subgraph in `G` induced by the nodes. 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=G.nbunch_iter(nbunch)returnG.subgraph(induced_nodes)
[docs]defedge_subgraph(G,edges):"""Returns a independent deep copy subgraph induced by the specified edges. The induced subgraph contains each edge in `edges` and each node incident to any of those edges. Parameters ---------- G : NetworkX Graph edges : iterable An iterable of edges. Edges not present in `G` are ignored. Returns ------- subgraph : SubGraph A edge-induced subgraph of subgraph of `G`. Examples -------- >>> G = nx.path_graph(5) >>> H = G.edge_subgraph([(0, 1), (3, 4)]) >>> list(H.nodes) [0, 1, 3, 4] >>> list(H.edges) [(0, 1), (3, 4)] """returnG.edge_subgraph(edges)
[docs]@patch_docstring(func.number_of_selfloops)defnumber_of_selfloops(G):ifG.is_multigraph():# we forward the MultiGraph nd MultiDiGraphreturnsum(1for_inselfloop_edges(G))returnG.number_of_selfloops()
@patch_docstring(func.set_node_attributes)defset_node_attributes(G,values,name=None):ifG.is_multigraph():# multigraph forward NetworkXfunc.set_node_attributes(G,values,name)return# Set node attributes based on type of `values`ifnameisnotNone:# `values` must not be a dict of dicttry:# `values` is a dictforn,vinvalues.items():ifninG:dd=get_node_data(G,n)dd[name]=values[n]G.set_node_data(n,dd)exceptAttributeError:# `values` is a constantforninG:dd=get_node_data(G,n)dd[name]=valuesG.set_node_data(n,dd)else:# `values` must be dict of dictforn,dinvalues.items():ifninG:dd=get_node_data(G,n)dd.update(d)G.set_node_data(n,dd)@patch_docstring(func.set_edge_attributes)defset_edge_attributes(G,values,name=None):# noqa: C901ifG.is_multigraph():# multigraph forward NetworkXfunc.set_edge_attributes(G,values,name)returnifnameisnotNone:# `values` does not contain attribute namestry:# if `values` is a dict using `.items()` => {edge: value}for(u,v),valueinvalues.items():dd=G.get_edge_data(u,v)ifddisnotNone:dd[name]=valueG.set_edge_data(u,v,dd)exceptAttributeError:# treat `values` as a constantforu,v,datainG.edges(data=True):data[name]=valueselse:for(u,v),dinvalues.items():dd=G.get_edge_data(u,v)ifddisnotNone:dd.update(d)G.set_edge_data(u,v,dd)