返回包含networkx元素的列表的函数
抱歉,如果这看起来是个明显的错误——我还是个Python新手。总之,我正在使用Python中的NetworkX库来生成一系列图。基本上,我的做法是通过优先连接的方式逐步增加图的顶点,直到达到“n”个顶点,并在这个过程中保存每一个“切片”。我的代码大致是这样的:
# function to generate a sequence of barabasi-albert random graphs
import networkx as nx
def pa_graph_seq(n, m, c=0, G=None, seed=None, seq=True):
# Note: seq = True means function returns a list of
# networkx graph objects. Otherwise returns the
# graph from the final time slice
# Some preliminary checks
if m<1 or m>=n:
raise nx.NetworkXError(\
"BA network must have m>=1 and m<n, m=%d,n=%d"%(m,n))
if seed is not None:
random.seed(seed)
if G is not None and len(G) >= n:
raise nx.NetworkXError(\
"G must have strictly less than n nodes")
# If initial graph was not specified, initialize empty graph
if G==None: G = nx.MultiGraph()
# If seq==True, initialize the list with the initial graph
if seq==True: Gseq = [G]
# Grow the graph
step = len(G)+1
while step <= n:
# Add a single node
G.add_node(1)
# Add edges
for i in range(m):
# Get degree sequence of current graph
deg = nx.degree(G)
d = deg.values()
# Increment degree of new node by 1
d[len(d)-1] = d[len(d)-1]+1
# Sample node and attach edge
newnode = deg_sample(d,c)
G.add_edge(step,deg_sample(d,c))
# If seq==True, append onto Gseq
if seq==True: Gseq.append(G)
step += 1
# Next loop for debugging only
for i in range(len(Gseq)):
print nx.nodes(Gseq[i])
if seq == True:
return Gseq
else:
return G
我遇到的奇怪问题是,最后的 Gseq
列表似乎只包含了 n
个最终图的副本。例如,在小的调试循环中(# Next loop for...
),输出看起来是这样的:
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
实际上,第一个元素应该是长度为0,第二个元素长度为1,依此类推……(因为我们每次都根据优先连接添加一个节点)。有人能看出我这里犯了什么错误吗?我确认如果我在主循环中加上 print nx.nodes(G)
,那么输出就会是我想要的样子……
谢谢大家的帮助和耐心!
1 个回答
1
这段代码只是把一个叫 G
的引用添加到 GSeq
中,并没有真正添加一个新的图对象。如果你想要实现你想要的效果,可以在主循环中加上 if G==None: G = nx.MultiGraph()
这行代码。
想更好地理解 Python 是怎么处理数据的,可以去看看 可变类型和不可变类型 的相关内容。
@markusian 的想法是对的。我觉得 MultiGraph 有一个 复制方法,可以帮助你实现你想要的效果。你可以试试类似这样的代码:
if seq==True: Gseq.append(G.copy())