我希望将单个节点S
替换为networkx图G
的子图N
,该节点再次包含整个子图S
。
我需要这样做,因为我需要从N
到我图的其他节点的边缘。
因为我没有得到网络x的子图方法,所以我编写了自己的代码来完成它。但我对结果感到困惑。
这是一个小例子脚本:
import networkx as nx
from copy import deepcopy
from collections import deque
class XGraph(nx.MultiDiGraph):
def dographthings(self, graph_edges, graph_nodes, subgraph_nodes):
self.add_edges_from(graph_edges)
subgraph = deepcopy(self)
# remove all nodes and their transitive children from subgraph,that are
# not in subgraph_nodes
remove_subtree(deque((set(graph_nodes) - set(subgraph_nodes))), subgraph)
# remove all nodes from self that are now in subgraph
self.remove_nodes_from(subgraph)
print "subgraph:"
print type(subgraph)
for node in subgraph.nodes_iter():
print node
print "self:"
print type(self)
for node in self.nodes_iter():
print node
self.add_node(subgraph)
print self.node[subgraph]
def remove_subtree(nodes, graph):
"""
Removes all nodes that are successors of the nodes in ``nodes``.
Is robust for cyclic graphs.
Parameters
----------
graph : referance to networkx.graph
graph to remove nodes from
nodes : deque of nodes-ids
the nodes the successors of which to remove from graph
"""
to_remove = set()
to_add = list()
for node in nodes:
to_remove.add(node)
if node in graph:
to_add.extend(graph.successors(node))
graph.remove_node(node)
for node in to_remove:
nodes.remove(node)
for node in to_add:
nodes.append(node)
if len(nodes) > 0:
graph = remove_subtree(nodes, graph)
g = XGraph()
g.dographthings([(1,2),(2,3),(2,4),(1,5)], [1,2,3,4,5], [3,2,1])
类XGraph
有一个方法可以为图形添加边,并且还可以构建如上所述的子图。
当我迭代图形和子图的节点时,一切看起来都是正确的。然后,当我添加
子图作为节点,并通过get_item方法访问它,它似乎已成为一个空字典而不是一个
MultiDiGraph,就像在将其添加为节点之前一样。
脚本的输出是:
subgraph:
<class '__main__.XGraph'>
1
2
3
self:
<class '__main__.XGraph'>
4
5
{}
为什么我的子图在被添加为节点时会成为字典?它的所有数据都会在哪里?
我错误地访问了节点。这样做是有效的:
for node in self.nodes_iter(data=True):
if isinstance(node[0], nx.MultiDiGraph):
print "this is the subgraph-node:"
print node
print "these are its internal nodes:"
for x in node[0].nodes_iter():
print x
else:
print "this is an atomic node:"
print node
输出:
this is the subgraph-node:
(<__main__.XGraph object at 0xb5ec21ac>, {})
these are its internal nodes:
1
2
3
this is an atomic node:
(4, {})
this is an atomic node:
(5, {})
答案 0 :(得分:1)
我无法理解为什么您的代码无效。这是一个可能有帮助的小例子
import networkx as nx
G = nx.Graph()
G.add_path([1,2,3,4])
S = G.subgraph([2,3]) # S is the graph 2-3
# add the subgraph as a node in the original graph
G.add_node(S)
# connect S to the neighbors of 2 and 3 and remove 2,3
for n in S:
nbrs = set(G.neighbors(n))
for nbr in nbrs - set([S]):
G.add_edge(S,nbr)
G.remove_node(n)
print(G.nodes()) # 1,4, <graph id>
print(G.edges()) # [(1, <graph id>), (<graph id>,4)]
答案 1 :(得分:0)
我错误地访问了节点。这样做是有效的:
n = 10;
ind = [2 5];
x=zeros(numel(ind),n);
x(sub2ind([numel(ind),n],1:numel(ind),ind))=1;
输出:
for node in self.nodes_iter(data=True):
if isinstance(node[0], nx.MultiDiGraph):
print "this is the subgraph-node:"
print node
print "these are its internal nodes:"
for x in node[0].nodes_iter():
print x
else:
print "this is an atomic node:"
print node
答案 2 :(得分:0)
我有一个图G,它首先划分为子图,然后创建一个新图A,并为其添加节点和边。所以在这里我有多个子图,我想用一个节点替换这些子图,并在它们之间添加边。
在下面,分区是一个字典,它将图G的节点映射到该节点所属的社区。
首先,我将位于同一社区中的节点放入列表中,并从该节点创建一个子图。之后,找到列表的邻居并将边添加到新图中。
此代码可用于有向图或无向图。
A = nx.Graph()
commlist = []
for com in set(partition.values()) :
list_nodes = [nodes for nodes in partition.keys()if partition[nodes] == com]
commlist.append(list_nodes)
subgraph = G.subgraph(list_nodes)
A.add_node(com)
for node in list_nodes:
nbrs = set(G.neighbors(node))
for i in nbrs - set(list_nodes):
A.add_edge(com, G.node[i]['community'])