返回包含networkx元素的列表的函数

0 投票
1 回答
1495 浏览
提问于 2025-04-18 03:26

抱歉,如果这看起来是个明显的错误——我还是个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())

撰写回答