Frage

Apologies if this is an obvious error--I'm a Python newbie. Anyways, I'm working with the NetworkX package in Python to generate a sequence of graphs. Essentially what I'm doing is growing a graph up to "n" vertices by preferential attachment, but saving each "slice" as it goes along. My code looks like this:

# 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

The weird problem I'm running up to is that the final Gseq list seems to consist of just n copies of the final graph. For example, the output in the small debugging loop (# Next loop for...) looks like:

[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]

Whereas really the first element should have length 0, the second element has length 1, etc... (since we add one node each time, according to preferential attachment). Is it obviously to anyone what error I am making here? I have confirmed that if I just add a print nx.nodes(G) inside the main for loop, then the output looks how I want it to...

Thanks for all your help and patience!

War es hilfreich?

Lösung

The code only appends a reference of G to GSeq and not actually append a new graph object. To get the behavior you want put if G==None: G = nx.MultiGraph() in the main loop.

For a better understanding of how python handles data read up on mutable vs immutable.

@markusian has the right idea I think. MultiGraph has a copy method that should get you the behavior you are looking for. Try something like

if seq==True: Gseq.append(G.copy())
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top