def test_valid_degree_sequence2():
    n = 100
    for i in range(10):
        G = nx.barabasi_albert_graph(n,1)
        deg = list(G.degree().values())
        assert_true( nx.is_valid_degree_sequence(deg, method='eg') )
        assert_true( nx.is_valid_degree_sequence(deg, method='hh') )        
Beispiel #2
0
def test_valid_degree_sequence2():
    n = 100
    for i in range(10):
        G = nx.barabasi_albert_graph(n, 1)
        deg = (d for n, d in G.degree())
        assert_true(nx.is_valid_degree_sequence(deg, method="eg"))
        assert_true(nx.is_valid_degree_sequence(deg, method="hh"))
Beispiel #3
0
def test_valid_degree_sequence2():
    n = 100
    for i in range(10):
        G = nx.barabasi_albert_graph(n,1)
        deg = list(G.degree().values())
        assert_true( nx.is_valid_degree_sequence(deg, method='eg') )
        assert_true( nx.is_valid_degree_sequence(deg, method='hh') )        
Beispiel #4
0
def test_valid_degree_sequence1():
    n = 100
    p = 0.3
    for i in range(10):
        G = nx.erdos_renyi_graph(n, p)
        deg = (d for n, d in G.degree())
        assert_true(nx.is_valid_degree_sequence(deg, method="eg"))
        assert_true(nx.is_valid_degree_sequence(deg, method="hh"))
def test_valid_degree_sequence1():
    n = 100
    p = .3
    for i in range(10):
        G = nx.erdos_renyi_graph(n,p)
        deg = list(G.degree().values())
        assert_true( nx.is_valid_degree_sequence(deg, method='eg') )
        assert_true( nx.is_valid_degree_sequence(deg, method='hh') )        
Beispiel #6
0
def test_valid_degree_sequence1():
    n = 100
    p = .3
    for i in range(10):
        G = nx.erdos_renyi_graph(n,p)
        deg = list(G.degree().values())
        assert_true( nx.is_valid_degree_sequence(deg, method='eg') )
        assert_true( nx.is_valid_degree_sequence(deg, method='hh') )        
Beispiel #7
0
def gen_delta_graph(n, ks, ps, simple=False, model='conf'):
    '''
    Generate a graph whose degree distribution is of finite support.
    
    Parameters
    ----------
    n : number of nodes
    ks : list
        Degrees the nodes can have
    ps : list
        Probability for each edge, must have same length as ks and sum to 1
    '''
    # the following function generates a degree sequence of length n
    pkmap = choicemap(ks,ps)
    dseqfun = lambda n: [ nx.utils.weighted_choice(pkmap) for i in range(n) ]
    success = False
    while not success:
        dseq = dseqfun(n)
        if nx.is_valid_degree_sequence(dseq): 
            success = True
    if model == 'conf':
        G = nx.configuration_model(dseq)
    elif model == 'chung-lu':
        G = nx.expected_degree_graph(dseq)
    else:
        raise Exception('wrong graph model requested')
    if simple:
        G = nx.Graph(G) # removes multi-edges
        G.remove_edges_from( G.selfloop_edges() ) # remove self loop
    return G
def generate_graph(type = 'PL', n = 100, seed = 1.0, parameter = 2.1):
    if type == 'ER':
        G = nx.erdos_renyi_graph(n, p=parameter, seed=seed, directed=True)
        G = nx.DiGraph(G)
        G.remove_edges_from(G.selfloop_edges())
    elif type == 'PL':
        z = nx.utils.create_degree_sequence(n, nx.utils.powerlaw_sequence, exponent = parameter)
        while not nx.is_valid_degree_sequence(z):
            z = nx.utils.create_degree_sequence(n, nx.utils.powerlaw_sequence, exponent = parameter)
        G = nx.configuration_model(z)
        G = nx.DiGraph(G)
        G.remove_edges_from(G.selfloop_edges())
    elif type == 'BA':
        G = nx.barabasi_albert_graph(n, 3, seed=None)
        G = nx.DiGraph(G)
    elif type == 'grid':
        G = nx.grid_2d_graph(int(np.ceil(np.sqrt(n))), int(np.ceil(np.sqrt(n))))
        G = nx.DiGraph(G)
    elif type in ['facebook', 'enron', 'twitter', 'students', 'tumblr', 'facebookBig']:
        #print 'start reading'
        #_, G, _, _ = readRealGraph(os.path.join("..","..","Data", type+".txt"))
        _, G, _, _ = readRealGraph(os.path.join("..","Data", type+".txt"))
        print 'size of graph', G.number_of_nodes()
        #Gcc = sorted(nx.connected_component_subgraphs(G.to_undirected()), key = len, reverse=True)
        #print Gcc[0].number_of_nodes()
        #print 'num of connected components', len(sorted(nx.connected_component_subgraphs(G.to_undirected()), key = len, reverse=True))
        #exit()
        if G.number_of_nodes() > n:
            G = getSubgraph(G, n)
        #G = getSubgraphSimulation(G, n, infP = 0.3)
    #nx.draw(G)
    #plt.show()
    return G
Beispiel #9
0
def seqGen(n):
    seq = [1, 2] #start with invalid deg seq
    while not nx.is_valid_degree_sequence(seq):
        seq = []
        for x in range(0, n):
            seq.append(random.randint(1, 4))
    return seq
def generate_simple_graph(sfunction, N, avg_degree):
    """generate a simple random graph with sfunction degree sequence"""

    graphical_deg_seq = False
    is_connected_graph = False
    while is_connected_graph == False:
        while graphical_deg_seq == False:
            seq = sfunction(N, avg_degree, seqtype="simple_degree")
            graphical_deg_seq = nx.is_valid_degree_sequence(seq)
        G = nx.havel_hakimi_graph(seq)
        G.remove_edges_from(G.selfloop_edges())

        if not nx.is_connected(G):
            try:
                connect_simple_graph(G)
                is_connected_graph = True
                randomize_graph(G)
            except (IndexError):
                is_connected_graph = False

        if not nx.is_connected(G):
            try:
                connect_simple_graph(G)
                is_connected_graph = True

            except (IndexError):
                is_connected_graph = False
                graphical_deg_seq = False

    return G
def generate_simple_graph(sfunction, N, avg_degree):
    """generate a simple random graph with sfunction degree sequence"""

    graphical_deg_seq = False
    is_connected_graph = False
    while is_connected_graph == False:
        while graphical_deg_seq == False:
            seq = sfunction(N, avg_degree, seqtype="simple_degree")
            graphical_deg_seq = nx.is_valid_degree_sequence(seq)
        G = nx.havel_hakimi_graph(seq)
        G.remove_edges_from(G.selfloop_edges())

        if not nx.is_connected(G):
            try:
                connect_simple_graph(G)
                is_connected_graph = True
                randomize_graph(G)
            except (IndexError):
                is_connected_graph = False

        if not nx.is_connected(G):
            try:
                connect_simple_graph(G)
                is_connected_graph = True

            except (IndexError):
                is_connected_graph = False
                graphical_deg_seq = False

    return G
def create_total_degree_sequence (n, sfunction, avg_degree, mod_nodes, tolerance, max_tries=2000, **kwds):

        """
        Creates a total-degree sequence.Ensures that the minimum degree is 1 and
        the max degree is 1 less than the number of nodes and that the average
        degree of the sequence generated is within a tolerance of 0.05.

	`n`: number of nodes
	`sfunction`: a sequence generating function with signature (number of
			nodes, mean)
	`avg_degree`: mean degree
	`max_tries`: maximum number of tries before dying. 
	
	8Nov 2013: function now assigns total degree to the nodes module-wise, to
	ensure that mean(d(k))= mean(d). ie., mean degree of each module is equal 
	to the network mean degree
	
	"""

	
	seqlist=[]
	# this loop assumes modules are indexed sequentially from 0 to K-1
	for mod in xrange(len(mod_nodes.keys())):
		tries = 0
		max_deg = len(mod_nodes[mod]) -1
		is_valid_seq = False
        	tol = 5.0
		while tol > tolerance  or (not is_valid_seq) or (tries > max_tries):
			trialseq = sfunction(len(mod_nodes[mod]), avg_degree, seqtype="degree")
			seq = [min(max_deg, max( int(round(s)), 1 )) for s in trialseq]
			is_valid_seq = nx.is_valid_degree_sequence(seq)
			
			if not is_valid_seq and sum(seq)%2 !=0:
				x = rnd.choice(xrange(len(seq)))
				seq[x] += 1 
			is_valid_seq = nx.is_valid_degree_sequence(seq)
			# check if d_k (bar) = d(bar)
			tol = abs(avg_degree - np.mean(seq))
			tries += 1	
			if (tries > max_tries):
				raise nx.NetworkXError, \
			 	"Exceeded max (%d) attempts at a valid sequence."%max_tries
		seqlist.append(seq)
	deg_list = [val for sublist in seqlist for val in sublist]
	return deg_list
Beispiel #13
0
 def __init__(self, degree, seed=None):
     if not nx.is_valid_degree_sequence(degree):
         raise nx.NetworkXUnfeasible('degree sequence is not graphical')
     if seed is not None:
         random.seed(seed)
     self.degree = list(degree)
     # node labels are integers 0,...,n-1
     self.m = sum(self.degree)/2.0 # number of edges
     try:
         self.dmax = max(self.degree) # maximum degree
     except ValueError:
         self.dmax = 0
 def __init__(self, degree, seed=None):
     if not nx.is_valid_degree_sequence(degree):
         raise nx.NetworkXUnfeasible('degree sequence is not graphical')
     if seed is not None:
         random.seed(seed)
     self.degree = list(degree)
     # node labels are integers 0,...,n-1
     self.m = sum(self.degree)/2.0 # number of edges
     try:
         self.dmax = max(self.degree) # maximum degree
     except ValueError:
         self.dmax = 0
Beispiel #15
0
def test_small_graph_false():
    z=[1000,3,3,3,3,2,2,2,1,1,1]
    assert_false(nx.is_valid_degree_sequence(z, method='hh'))
    assert_false(nx.is_valid_degree_sequence(z, method='eg'))
    z=[6,5,4,4,2,1,1,1]
    assert_false(nx.is_valid_degree_sequence(z, method='hh'))
    assert_false(nx.is_valid_degree_sequence(z, method='eg'))
    z=[1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 4]
    assert_false(nx.is_valid_degree_sequence(z, method='hh'))
    assert_false(nx.is_valid_degree_sequence(z, method='eg'))        
Beispiel #16
0
def test_small_graph_true():
        z=[5,3,3,3,3,2,2,2,1,1,1]
        assert_true(nx.is_valid_degree_sequence(z, method='hh'))
        assert_true(nx.is_valid_degree_sequence(z, method='eg'))       
        z=[10,3,3,3,3,2,2,2,2,2,2]
        assert_true(nx.is_valid_degree_sequence(z, method='hh'))
        assert_true(nx.is_valid_degree_sequence(z, method='eg'))        
        z=[1, 1, 1, 1, 1, 2, 2, 2, 3, 4]
        assert_true(nx.is_valid_degree_sequence(z, method='hh'))
        assert_true(nx.is_valid_degree_sequence(z, method='eg'))        
Beispiel #17
0
def test_small_graph_false():
        z=[1000,3,3,3,3,2,2,2,1,1,1]
        assert_false(nx.is_valid_degree_sequence(z, method='hh'))
        assert_false(nx.is_valid_degree_sequence(z, method='eg'))
        z=[6,5,4,4,2,1,1,1]
        assert_false(nx.is_valid_degree_sequence(z, method='hh'))
        assert_false(nx.is_valid_degree_sequence(z, method='eg'))
        z=[1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 4]
        assert_false(nx.is_valid_degree_sequence(z, method='hh'))
        assert_false(nx.is_valid_degree_sequence(z, method='eg'))        
Beispiel #18
0
def test_small_graph_true():
        z=[5,3,3,3,3,2,2,2,1,1,1]
        assert_true(nx.is_valid_degree_sequence(z, method='hh'))
        assert_true(nx.is_valid_degree_sequence(z, method='eg'))       
        z=[10,3,3,3,3,2,2,2,2,2,2]
        assert_true(nx.is_valid_degree_sequence(z, method='hh'))
        assert_true(nx.is_valid_degree_sequence(z, method='eg'))        
        z=[1, 1, 1, 1, 1, 2, 2, 2, 3, 4]
        assert_true(nx.is_valid_degree_sequence(z, method='hh'))
        assert_true(nx.is_valid_degree_sequence(z, method='eg'))        
Beispiel #19
0
def undirected_degree_preserving_random_graph(degreeSequence):
    """Returns a random graph with n nodes, with the degree distribution same as that given by the argument ``degreeSequence``.

    """

    assert (nx.is_valid_degree_sequence(degreeSequence))

    num_nodes = len(degreeSequence)
    G = nx.empty_graph(num_nodes, create_using)
    num_degrees = []
    for i in range(num_nodes):
        num_degrees.append([])
    dmax, dsum, n = 0, 0, 0
    for d in degreeSequence:
        if d > 0:
            num_degrees[d].append(n)
            dmax, dsum, n = max(dmax, d), dsum + d, n + 1
    if n == 0:
        return G

    modstubs = [(0, 0)] * (dmax + 1)
    while n > 0:
        while len(num_degrees[dmax]) == 0:
            dmax -= 1
        if dmax > n - 1:
            raise nx.NetworkXError(
                'Sequence provided cannot be used on a graph.')

        source = num_degrees[dmax].pop()
        n -= 1
        mslen = 0
        k = dmax
        for i in range(dmax):
            while len(num_degrees[k]) == 0:
                k -= 1
            target = num_degrees[k].pop()
            G.add_edge(source, target)
            n -= 1
            if k > 1:
                modstubs[mslen] = (k - 1, target)
                mslen += 1
        for i in range(mslen):
            (stubval, stubtarget) = modstubs[i]
            num_degrees[stubval].append(stubtarget)
            n += 1

    return G
Beispiel #20
0
def scale_free_powerlaw(n=4000, lam=3, k_avg=4):
    """
    n : number of nodes
    lam : exponent
    """
    noftries = 2147483647
    standard = k_avg + 0.5

    while (1):
        s = generate(n, lam)
        ratio = standard / np.mean(s)
        for i in range(len(s)):
            s[i] = int(ratio * s[i])
        if (nx.is_valid_degree_sequence(s)):
            G = nx.random_degree_sequence_graph(s, tries=noftries)
            break
    return G
Beispiel #21
0
def GenGraph(Nodes_CC,Lambda):
    import numpy as np
    import networkx as nx

    Lmin=min(1,len(Nodes_CC))
    Lmax=len(Nodes_CC)-1
    flag=0
    if len(Nodes_CC)==1:
        D=[0]
    
    while len(Nodes_CC)!=1 and flag==0:
    
        D=[Distribution(Lmin,Lmax,Lambda) for i in range(0,len(Nodes_CC))]
        if nx.is_valid_degree_sequence(D, method='eg') ==True:
        # eg:Erdős-Gallai      hh:  Havel-Hakimi
            flag=1
    
    return D 
def create_degree_sequence(n, sfunction=None, max_tries=50, **kwds):
    _warnings.warn("create_degree_sequence() is deprecated",
                   DeprecationWarning)
    """ Attempt to create a valid degree sequence of length n using
    specified function sfunction(n,**kwds).

    Parameters
    ----------
    n : int
        Length of degree sequence = number of nodes
    sfunction: function
        Function which returns a list of n real or integer values.
        Called as "sfunction(n,**kwds)".
    max_tries: int
        Max number of attempts at creating valid degree sequence.

    Notes
    -----
    Repeatedly create a degree sequence by calling sfunction(n,**kwds)
    until achieving a valid degree sequence. If unsuccessful after
    max_tries attempts, raise an exception.
    
    For examples of sfunctions that return sequences of random numbers,
    see networkx.Utils.

    Examples
    --------
    >>> from networkx.utils import uniform_sequence, create_degree_sequence
    >>> seq=create_degree_sequence(10,uniform_sequence)
    """
    tries=0
    max_deg=n
    while tries < max_tries:
        trialseq=sfunction(n,**kwds)
        # round to integer values in the range [0,max_deg]
        seq=[min(max_deg, max( int(round(s)),0 )) for s in trialseq]
        # if graphical return, else throw away and try again
        if nx.is_valid_degree_sequence(seq):
            return seq
        tries+=1
    raise nx.NetworkXError(\
          "Exceeded max (%d) attempts at a valid sequence."%max_tries)
Beispiel #23
0
def generate_graph(type='PL', n=100, seed=1.0, parameter=2.1):
    if type == 'ER':
        G = nx.erdos_renyi_graph(n, p=parameter, seed=seed, directed=True)
        G = nx.DiGraph(G)
        G.remove_edges_from(G.selfloop_edges())
    elif type == 'PL':
        z = nx.utils.create_degree_sequence(n,
                                            nx.utils.powerlaw_sequence,
                                            exponent=parameter)
        while not nx.is_valid_degree_sequence(z):
            z = nx.utils.create_degree_sequence(n,
                                                nx.utils.powerlaw_sequence,
                                                exponent=parameter)
        G = nx.configuration_model(z)
        G = nx.DiGraph(G)
        G.remove_edges_from(G.selfloop_edges())
    elif type == 'BA':
        G = nx.barabasi_albert_graph(n, 3, seed=None)
        G = nx.DiGraph(G)
    elif type == 'grid':
        G = nx.grid_2d_graph(int(np.ceil(np.sqrt(n))),
                             int(np.ceil(np.sqrt(n))))
        G = nx.DiGraph(G)
    elif type in [
            'facebook', 'enron', 'twitter', 'students', 'tumblr', 'facebookBig'
    ]:
        #print 'start reading'
        #_, G, _, _ = readRealGraph(os.path.join("..","..","Data", type+".txt"))
        _, G, _, _ = readRealGraph(os.path.join("..", "Data", type + ".txt"))
        print 'size of graph', G.number_of_nodes()
        #Gcc = sorted(nx.connected_component_subgraphs(G.to_undirected()), key = len, reverse=True)
        #print Gcc[0].number_of_nodes()
        #print 'num of connected components', len(sorted(nx.connected_component_subgraphs(G.to_undirected()), key = len, reverse=True))
        #exit()
        if G.number_of_nodes() > n:
            G = getSubgraph(G, n)
        #G = getSubgraphSimulation(G, n, infP = 0.3)
    #nx.draw(G)
    #plt.show()
    return G
Beispiel #24
0
Random graph from given degree sequence.
Draw degree histogram with matplotlib.

"""
__author__ = """Aric Hagberg ([email protected])"""

try:
    import matplotlib.pyplot as plt
    import matplotlib
except:
    raise

import networkx as nx

z=nx.utils.create_degree_sequence(100,nx.utils.powerlaw_sequence,exponent=2.1)
nx.is_valid_degree_sequence(z)

print "Configuration model"
G=nx.configuration_model(z)  # configuration model

degree_sequence=sorted(nx.degree(G).values(),reverse=True) # degree sequence
#print "Degree sequence", degree_sequence
dmax=max(degree_sequence)

plt.loglog(degree_sequence,'b-',marker='o')
plt.title("Degree rank plot")
plt.ylabel("degree")
plt.xlabel("rank")

# draw graph in inset 
plt.axes([0.45,0.45,0.45,0.45])
def test_iterable():
    G = nx.path_graph(4)
    seq = iter(G.degree().values())
    assert_true(nx.is_valid_degree_sequence(seq, method='hh'))
    assert_true(nx.is_valid_degree_sequence(seq, method='eg'))
def test_negative_input():
    assert_false(nx.is_valid_degree_sequence([-1],'hh'))
    assert_false(nx.is_valid_degree_sequence([-1],'eg'))
    assert_false(nx.is_valid_degree_sequence([72.5],'eg'))
def test_string_input():
    a = nx.is_valid_degree_sequence([],'foo')
def test_iterable():
    G = nx.path_graph(4)
    seq = iter(G.degree().values())
    assert_true(nx.is_valid_degree_sequence(seq, method='hh'))
    assert_true(nx.is_valid_degree_sequence(seq, method='eg'))
Beispiel #29
0
def havel_hakimi_graph(deg_sequence,create_using=None):
    """Return a simple graph with given degree sequence constructed
    using the Havel-Hakimi algorithm.

    Parameters
    ----------
    deg_sequence: list of integers
        Each integer corresponds to the degree of a node (need not be sorted).
    create_using : graph, optional (default Graph)
        Return graph of this type. The instance will be cleared.
        Directed graphs are not allowed.

    Raises
    ------
    NetworkXException
        For a non-graphical degree sequence (i.e. one
        not realizable by some simple graph).

    Notes
    -----
    The Havel-Hakimi algorithm constructs a simple graph by
    successively connecting the node of highest degree to other nodes
    of highest degree, resorting remaining nodes by degree, and
    repeating the process. The resulting graph has a high
    degree-associativity.  Nodes are labeled 1,.., len(deg_sequence),
    corresponding to their position in deg_sequence.

    The basic algorithm is from Hakimi [1]_ and was generalized by
    Kleitman and Wang [2]_.

    References
    ----------
    .. [1] Hakimi S., On Realizability of a Set of Integers as 
       Degrees of the Vertices of a Linear Graph. I,
       Journal of SIAM, 10(3), pp. 496-506 (1962)
    .. [2] Kleitman D.J. and Wang D.L.
       Algorithms for Constructing Graphs and Digraphs with Given Valences
       and Factors  Discrete Mathematics, 6(1), pp. 79-88 (1973) 
    """
    if not nx.is_valid_degree_sequence(deg_sequence):
        raise nx.NetworkXError('Invalid degree sequence')
    if create_using is not None:
        if create_using.is_directed():
            raise nx.NetworkXError("Directed graphs are not supported")

    p = len(deg_sequence)
    G=nx.empty_graph(p,create_using)
    num_degs = []
    for i in range(p):
        num_degs.append([])
    dmax, dsum, n = 0, 0, 0
    for d in deg_sequence:
        # Process only the non-zero integers
        if d>0:
            num_degs[d].append(n)
            dmax, dsum, n = max(dmax,d), dsum+d, n+1
    # Return graph if no edges
    if n==0:
        return G

    modstubs = [(0,0)]*(dmax+1)
    # Successively reduce degree sequence by removing the maximum degree
    while n > 0:
        # Retrieve the maximum degree in the sequence
        while len(num_degs[dmax]) == 0:
            dmax -= 1
        # If there are not enough stubs to connect to, then the sequence is
        # not graphical
        if dmax > n-1:
            raise nx.NetworkXError('Non-graphical integer sequence')

        # Remove largest stub in list
        source = num_degs[dmax].pop()
        n -= 1
        # Reduce the next dmax largest stubs
        mslen = 0
        k = dmax
        for i in range(dmax):
            while len(num_degs[k]) == 0:
                k -= 1
            target = num_degs[k].pop()
            G.add_edge(source, target)
            n -= 1
            if k > 1:
                modstubs[mslen] = (k-1,target)
                mslen += 1
        # Add back to the list any nonzero stubs that were removed
        for i  in range(mslen):
            (stubval, stubtarget) = modstubs[i]
            num_degs[stubval].append(stubtarget)
            n += 1

    G.name="havel_hakimi_graph %d nodes %d edges"%(G.order(),G.size())
    return G
Beispiel #30
0
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
import random

DOPART1 = 1
DOPART2 = 1
#calculate mean fractional size per part 1, Q6
if (DOPART1):
    NUMBERITERATIONS = 2663  #confidence level-99, confidence interval-2.5
    resultsArray = np.zeros(NUMBERITERATIONS)
    for index in range(0, NUMBERITERATIONS):
        degreeSequence = [0] * 1000
        degreeSequence[0] = 1
        while (not nx.is_valid_degree_sequence(degreeSequence)):
            for index2 in range(0, 1000):  #generate degree sequence
                rollTheDice = random.random()
                if (rollTheDice <= .6):
                    degreeSequence[index2] = 1
                else:
                    degreeSequence[index2] = 3
        graph = nx.configuration_model(degreeSequence)
        resultsArray[index] = len(
            max(nx.connected_component_subgraphs(graph), key=len))
    print "mean of largest component after", NUMBERITERATIONS, "iterations =", np.mean(
        resultsArray)
    print "mean fractional size =", np.mean(resultsArray) / 1000

if (DOPART2):
    NUMBERITERATIONS = 666  #confidence level-99, confindence interval-5
        dataset_tag=sys.argv[3]
        num_iter=int(sys.argv[4]);
    else:
        print('Input is required as:\n 1) full edgelist filename 
        \n 2) name of output directory 
        \n 3) name tag for output files 
        \n 4) number of iterations');
        sys.exit();

if not os.path.exists(dir):
    os.makedirs(dir)


G=nx.read_weighted_edgelist(original_graph)

boo = nx.is_valid_degree_sequence(G.degree().values())

if boo == False:
    print 'la successione dei gradi non e valida'


GD = nx.configuration_model(G.degree().values())
GD.remove_edges_from(GD.selfloop_edges())
GD = nx.Graph(GD)
ww = nx.utils.powerlaw_sequence(GD.number_of_edges())

m = min(ww)
M = max(ww)

def new_weights(ww):
    return [(ww[i]-m)/(M-m) for i in range(len(ww))]
Beispiel #32
0
def test_string_input():
    a = nx.is_valid_degree_sequence([],'foo')
Beispiel #33
0
def li_smax_graph(degree_seq, create_using=None):
    """Generates a graph based with a given degree sequence and maximizing
    the s-metric.  Experimental implementation.

    Maximum s-metrix  means that high degree nodes are connected to high
    degree nodes. 
        
    - `degree_seq`: degree sequence, a list of integers with each entry
       corresponding to the degree of a node.
       A non-graphical degree sequence raises an Exception.    

    Reference::      
    
      @unpublished{li-2005,
       author = {Lun Li and David Alderson and Reiko Tanaka
                and John C. Doyle and Walter Willinger},
       title = {Towards a Theory of Scale-Free Graphs:
               Definition, Properties, and  Implications (Extended Version)},
       url = {http://arxiv.org/abs/cond-mat/0501169},
       year = {2005}
      }

    The algorithm::

     STEP 0 - Initialization
     A = {0}
     B = {1, 2, 3, ..., n}
     O = {(i; j), ..., (k, l),...} where i < j, i <= k < l and 
             d_i * d_j >= d_k *d_l 
     wA = d_1
     dB = sum(degrees)

     STEP 1 - Link selection
     (a) If |O| = 0 TERMINATE. Return graph A.
     (b) Select element(s) (i, j) in O having the largest d_i * d_j , if for 
             any i or j either w_i = 0 or w_j = 0 delete (i, j) from O
     (c) If there are no elements selected go to (a).
     (d) Select the link (i, j) having the largest value w_i (where for each 
             (i, j) w_i is the smaller of w_i and w_j ), and proceed to STEP 2.

     STEP 2 - Link addition
     Type 1: i in A and j in B. 
             Add j to the graph A and remove it from the set B add a link 
             (i, j) to the graph A. Update variables:
             wA = wA + d_j -2 and dB = dB - d_j
             Decrement w_i and w_j with one. Delete (i, j) from O
     Type 2: i and j in A.
         Check Tree Condition: If dB = 2 * |B| - wA. 
             Delete (i, j) from O, continue to STEP 3
         Check Disconnected Cluster Condition: If wA = 2. 
             Delete (i, j) from O, continue to STEP 3
         Add the link (i, j) to the graph A 
         Decrement w_i and w_j with one, and wA = wA -2
     STEP 3
         Go to STEP 1


    The article states that the algorithm will result in a maximal s-metric. 
    This implementation can not guarantee such maximality. I may have 
    misunderstood the algorithm, but I can not see how it can be anything 
    but a heuristic. Please contact me at [email protected] if you can 
    provide python code that can guarantee maximality.
    Several optimizations are included in this code and it may be hard to read.
    Commented code to come.

    A POSSIBLE ALTERNATIVE:

    For an 'unconstrained' graph, that is one they describe as having
    the sum of the degree sequence be even(ie all undirected graphs) they
    present a simpler algorithm. It is as follows

        "For each vertex i: if di is even then attach di/2 self-loops;
        if di is odd, then attach (di-1)/2 self-loops, leaving one
        available "stub". Second for all remaining vertices with "stubs"
        connect them in pairs according to decreasing values of di."[1]
    
    Since this only works for undirected graphs anyway, perhaps this is
    the better method? Note this also returns a graph with a larger
    s_metric than the other method, and it seems to have the same
    degree sequence, though I haven't tested it extensively.
    """
    if not nx.is_valid_degree_sequence(degree_seq):
        raise nx.NetworkXError('Invalid degree sequence')
    if create_using is not None and create_using.is_directed():
        raise nx.NetworkXError("Directed Graph not supported")

    degree_seq.sort(reverse=True) # make sure it's sorted
   
    if not (sum(degree_seq) %2): #check if the sum of the degree sequence is even, Should be if it is undirected
        dseven = [di for di in degree_seq if (not di % 2)]
        dsodd = [di for di in degree_seq if (di % 2)]
        Gmax = nx.MultiGraph()
        i = 0
        for di in dseven:
            Gmax.add_node(i)
            for k in range(di // 2):
                Gmax.add_edge(i,i)
            i=i+1
        for j in range(0,len(dsodd),2): #do this iteratively to connect
            Gmax.add_node(i)            #node stubs as we go
            Gmax.add_node(i+1)
            for k in range((dsodd[j]-1) // 2):
                Gmax.add_edge(i,i)
            for k in range((dsodd[j+1]-1) // 2):
                Gmax.add_edge(i+1,i+1)
            Gmax.add_edge(i,i+1)
            i=i+2
        return Gmax
    else:
        degrees_left = degree_seq[:]
        A_graph = empty_graph(0,create_using)
        A_graph.add_node(0)
        a_list = [False]*len(degree_seq)
        b_set = set(range(1,len(degree_seq)))
        a_open = set([0])
        O = []
        for j in b_set:
            heapq.heappush(O, (-degree_seq[0]*degree_seq[j], (0,j))),
        wa = degrees_left[0] #stubs in a_graph
        db = sum(degree_seq) - degree_seq[0] #stubs in b-graph
        a_list[0] = True #node 0 is now in a_Graph
        bsize = len(degree_seq) -1 #size of b_graph
        selected = []
        weight = 0
        while O or selected:
            if len(selected) <1 :
                firstrun = True
                while O:
                    (newweight, (i,j)) = heapq.heappop(O)
                    if degrees_left[i] < 1 or degrees_left[j] < 1 :
                        continue
                    if firstrun:
                        firstrun = False
                        weight = newweight
                    if not newweight == weight:
                        break
                    heapq.heappush(selected, [-degrees_left[i], \
                                        -degrees_left[j], (i,j)])
                if not weight == newweight:
                    heapq.heappush(O,(newweight, (i,j)))
                weight *= -1
            if len(selected) < 1:
                break

            [w1, w2, (i,j)] = heapq.heappop(selected)
            if degrees_left[i] < 1 or degrees_left[j] < 1 :
                continue
            if a_list[i] and j in b_set:
                #TYPE1
                a_list[j] = True
                b_set.remove(j)
                A_graph.add_node(j)
                A_graph.add_edge(i, j)
                degrees_left[i] -= 1
                degrees_left[j] -= 1
                wa += degree_seq[j] - 2
                db -= degree_seq[j]
                bsize -= 1
                newweight = weight
                if not degrees_left[j] == 0:
                    a_open.add(j)
                    for k in b_set:
                        if A_graph.has_edge(j, k): continue
                        w = degree_seq[j]*degree_seq[k]
                        if w > newweight:
                            newweight = w
                        if weight == w and not newweight > weight:
                            heapq.heappush(selected, [-degrees_left[j], \
                                                -degrees_left[k], (j,k)])
                        else:
                            heapq.heappush(O, (-w, (j,k)))
                    if not weight == newweight:
                        while selected:
                            [w1,w2,(i,j)] = heapq.heappop(selected)
                            if degrees_left[i]*degrees_left[j] > 0:
                                heapq.heappush(O, [-degree_seq[i]*degree_seq[j],(i,j)])
                if degrees_left[i] == 0:
                    a_open.discard(i)

            else:
                #TYPE2
                if db == (2*bsize - wa):
                    #tree condition
                    #print "removing because tree condition    "
                    continue
                elif db < 2*bsize -wa:
                    raise nx.NetworkXError(\
                            "THIS SHOULD NOT HAPPEN!-not graphable")
                    continue
                elif wa == 2 and bsize > 0:
                    #print "removing because disconnected  cluster"
                    #disconnected cluster condition
                    continue
                elif wa == db - (bsize)*(bsize-1):
                    #print "MYOWN removing because disconnected  cluster"
                    continue
                A_graph.add_edge(i, j)
                degrees_left[i] -= 1
                degrees_left[j] -= 1
                if degrees_left[i] < 1:
                    a_open.discard(i)
                if degrees_left[j] < 1:
                    a_open.discard(j)
                wa -=  2
                if not degrees_left[i] < 0 and not degrees_left[j] < 0:
                    selected2 = (selected)
                    selected = []
                    while selected2:
                        [w1,w1, (i,j)] = heapq.heappop(selected2)
                        if degrees_left[i]*degrees_left[j] > 0:
                            heapq.heappush(selected, [-degrees_left[i], \
                                            -degrees_left[j], (i,j)])
        return A_graph 
def create_indegree_sequence(n, m, sfunction, mod_nodes, wd, degree_list, tolerance, **kwds):

    """ 
	Creates indegree sequence.
	Ensures that (i)the within-module degree of node is less than or equal to
	its total degree; (ii) the within-module degree sequence is graphical
	nodes; and (iii) the average within module degree of the sequence
	generated is within a tolerance of 0.05 

	'n': number of nodes
	'sfunction': a sequence generating function with signature (number of
			nodes, mean)
	 'wd' = mean within-module degree, m= total modules in the network
	 'nc'=average community size
	 'mod_nodes'= dictionary of nodal membership to communities
	'avg_degree': mean degree
	'degree_list'= total degree sequence
	"""
    is_valid_seq = False
    is_valid_indegree = False
    is_valid_module_size = False
    is_valid_outdegree = True
    tol = 5.0
    connect_trial = 0
    # Return empty list if the main loop breaks
    indegree_list = []

    while (not is_valid_seq) or (not is_valid_indegree) or (not is_valid_module_size) or (not is_valid_outdegree):

        indegree_seq = sfunction(n, wd, seqtype="indegree")
        indegree_sort = list(np.sort(indegree_seq))
        degree_sort = list(np.sort(degree_list))
        is_valid_indegree = all([indegree_sort[i] <= degree_sort[i] for i in range(n)]) == True
        mod_sizes = [len(mod_nodes[x]) for x in mod_nodes.keys()]
        is_valid_module_size = min(mod_sizes) >= max(indegree_seq)
        is_valid_seq = True

        if not is_valid_module_size:
            connect_trial += 1
        if is_valid_indegree and is_valid_seq and is_valid_module_size:
            # assign within-degree to a node such that wd(i)<=d(i)
            indegree_list = sort_inedge(indegree_sort, degree_sort, degree_list, n)
            # if network has two modules then sum(outdegree) for module 1 has to be equal to sum(outdegree) of module 2
            if m == 2:
                mod1, mod2 = mod_nodes.keys()
                is_valid_outdegree = sum([(degree_list[i] - indegree_list[i]) for i in mod_nodes[mod1]]) == sum(
                    [(degree_list[i] - indegree_list[i]) for i in mod_nodes[mod2]]
                )

            for module in mod_nodes:
                seq = [indegree_list[i] for i in mod_nodes[module]]

                while (sum(seq) % 2) != 0:
                    # choose a random node in the module
                    node_add_degree = rnd.choice([i for i in mod_nodes[module]])
                    # ensure that wd<=d and wd< (module size -1)after adding a within-degree to the node
                    if indegree_list[node_add_degree] < degree_list[node_add_degree] and indegree_list[
                        node_add_degree
                    ] < len(mod_nodes[module]):
                        indegree_list[node_add_degree] += 1
                    seq = [indegree_list[i] for i in mod_nodes[module]]

                is_valid_seq = nx.is_valid_degree_sequence(seq)
                tol = abs(wd - (sum(seq) / (1.0 * len(seq))))  # ensure that wd_k(bar) = wd(bar)
                if (not is_valid_seq) and tol > tolerance:
                    break

        if connect_trial > 10:
            break

    return indegree_list
def havel_hakimi_graph(deg_sequence,create_using=None):
    """Return a simple graph with given degree sequence constructed
    using the Havel-Hakimi algorithm.

    Parameters
    ----------
    deg_sequence: list of integers
        Each integer corresponds to the degree of a node (need not be sorted).
    create_using : graph, optional (default Graph)
        Return graph of this type. The instance will be cleared.
        Multigraphs and directed graphs are not allowed.

    Raises
    ------
    NetworkXException
        For a non-graphical degree sequence (i.e. one
        not realizable by some simple graph).

    Notes
    -----
    The Havel-Hakimi algorithm constructs a simple graph by
    successively connecting the node of highest degree to other nodes
    of highest degree, resorting remaining nodes by degree, and
    repeating the process. The resulting graph has a high
    degree-associativity.  Nodes are labeled 1,.., len(deg_sequence),
    corresponding to their position in deg_sequence.

    See Theorem 1.4 in [1]_.
    This algorithm is also used in the function is_valid_degree_sequence.

    References
    ----------
    .. [1] G. Chartrand and L. Lesniak, "Graphs and Digraphs",
           Chapman and Hall/CRC, 1996.
    """
    if not nx.is_valid_degree_sequence(deg_sequence):
        raise nx.NetworkXError('Invalid degree sequence')
    if create_using is not None:
        if create_using.is_directed():
            raise nx.NetworkXError("Directed Graph not supported")
        if create_using.is_multigraph():
            raise nx.NetworkXError("Havel-Hakimi requires simple graph")

    N=len(deg_sequence)
    G=nx.empty_graph(N,create_using)

    if N==0 or max(deg_sequence)==0: # done if no edges
        return G

    # form list of [stubs,name] for each node.
    stublist=[ [deg_sequence[n],n] for n in G]
    #  Now connect the stubs
    while stublist:
        stublist.sort()
        if stublist[0][0]<0: # took too many off some vertex
            return False     # should not happen if deg_seq is valid

        (freestubs,source) = stublist.pop() # the node with the most stubs
        if freestubs==0: break          # the rest must also be 0 --Done!
        if freestubs > len(stublist):  # Trouble--can't make that many edges
            return False               # should not happen if deg_seq is valid

        # attach edges to biggest nodes
        for stubtarget in stublist[-freestubs:]:
            G.add_edge(source, stubtarget[1])
            stubtarget[0] -= 1  # updating stublist on the fly

    G.name="havel_hakimi_graph %d nodes %d edges"%(G.order(),G.size())
    return G
Beispiel #36
0
def havel_hakimi_graph(deg_sequence, create_using=None):
    """Return a simple graph with given degree sequence constructed
    using the Havel-Hakimi algorithm.

    Parameters
    ----------
    deg_sequence: list of integers
        Each integer corresponds to the degree of a node (need not be sorted).
    create_using : graph, optional (default Graph)
        Return graph of this type. The instance will be cleared.
        Multigraphs and directed graphs are not allowed.

    Raises
    ------
    NetworkXException
        For a non-graphical degree sequence (i.e. one
        not realizable by some simple graph).

    Notes
    -----
    The Havel-Hakimi algorithm constructs a simple graph by
    successively connecting the node of highest degree to other nodes
    of highest degree, resorting remaining nodes by degree, and
    repeating the process. The resulting graph has a high
    degree-associativity.  Nodes are labeled 1,.., len(deg_sequence),
    corresponding to their position in deg_sequence.

    See Theorem 1.4 in [1]_.
    This algorithm is also used in the function is_valid_degree_sequence.

    References
    ----------
    .. [1] G. Chartrand and L. Lesniak, "Graphs and Digraphs",
           Chapman and Hall/CRC, 1996.
    """
    if not nx.is_valid_degree_sequence(deg_sequence):
        raise nx.NetworkXError('Invalid degree sequence')
    if create_using is not None:
        if create_using.is_directed():
            raise nx.NetworkXError("Directed Graph not supported")
        if create_using.is_multigraph():
            raise nx.NetworkXError("Havel-Hakimi requires simple graph")

    N = len(deg_sequence)
    G = nx.empty_graph(N, create_using)

    if N == 0 or max(deg_sequence) == 0:  # done if no edges
        return G

    # form list of [stubs,name] for each node.
    stublist = [[deg_sequence[n], n] for n in G]
    #  Now connect the stubs
    while stublist:
        stublist.sort()
        if stublist[0][0] < 0:  # took too many off some vertex
            return False  # should not happen if deg_seq is valid

        (freestubs, source) = stublist.pop()  # the node with the most stubs
        if freestubs == 0: break  # the rest must also be 0 --Done!
        if freestubs > len(stublist):  # Trouble--can't make that many edges
            return False  # should not happen if deg_seq is valid

        # attach edges to biggest nodes
        for stubtarget in stublist[-freestubs:]:
            G.add_edge(source, stubtarget[1])
            stubtarget[0] -= 1  # updating stublist on the fly

    G.name = "havel_hakimi_graph %d nodes %d edges" % (G.order(), G.size())
    return G
Beispiel #37
0
def test_negative_input():
    assert_false(nx.is_valid_degree_sequence([-1],'hh'))
    assert_false(nx.is_valid_degree_sequence([-1],'eg'))
    assert_false(nx.is_valid_degree_sequence([72.5],'eg'))
Beispiel #38
0
def test_atlas():
    for graph in nx.graph_atlas_g():
        deg = list(graph.degree().values())
        assert_true( nx.is_valid_degree_sequence(deg, method='eg') )
        assert_true( nx.is_valid_degree_sequence(deg, method='hh') )        
Beispiel #39
0
def test_negative_input():
    assert_false(nx.is_valid_degree_sequence([-1], "hh"))
    assert_false(nx.is_valid_degree_sequence([-1], "eg"))
    assert_false(nx.is_valid_degree_sequence([72.5], "eg"))
Beispiel #40
0
 def test_atlas(self):
     for graph in self.GAG:
         deg = (d for n, d in graph.degree())
         assert_true(nx.is_valid_degree_sequence(deg, method="eg"))
         assert_true(nx.is_valid_degree_sequence(deg, method="hh"))
Beispiel #41
0
        dataset_tag=sys.argv[3]
        num_iter=int(sys.argv[4]);
    else:
        print('Input is required as:\n 1) full edgelist filename 
        \n 2) name of output directory 
        \n 3) name tag for output files 
        \n 4) number of iterations');
        sys.exit();

if not os.path.exists(dir):
    os.makedirs(dir)


G=nx.read_weighted_edgelist(original_graph)

boo = nx.is_valid_degree_sequence(G.degree().values())

if boo == False:
    print 'la successione dei gradi non e valida'

GD = nx.configuration_model(G.degree().values())
GD.remove_edges_from(GD.selfloop_edges())
GD = nx.Graph(GD)
ww = nx.utils.powerlaw_sequence(GD.number_of_edges(), 2.6)

m = min(ww)
M = max(ww)

def new_weights(ww):
    return [(ww[i]-m)/(M-m) for i in range(len(ww))]
Beispiel #42
0
 def test_atlas(self):
     for graph in self.GAG:
         deg = (d for n, d in graph.degree())
         assert_true( nx.is_valid_degree_sequence(deg, method='eg') )
         assert_true( nx.is_valid_degree_sequence(deg, method='hh') )        
def setup_network(num_of_banks, num_of_assets, round_rvs, kind='man_half_half', p=2.5, min_holdings=10,
                  single_net=False, project_network=False, av_deg=False, add_fedfunds=None):
    if not single_net:
        if kind == 'er':
            # np.random.seed(1)
            if av_deg:
                G = nx.bipartite.random_graph(num_of_banks, num_of_assets, av_deg/num_of_banks)  # ,seed=1
            else:
                G = nx.bipartite.random_graph(num_of_banks, num_of_assets, np.mean(round_rvs)/num_of_banks)  # ,seed=1
            if not nx.is_connected(G):
                G = max(nx.connected_component_subgraphs(G), key=len)
            bot, top = nx.bipartite.sets(G)
            assets = {t: 'a' + str(t-num_of_banks) for t in top}
            banks = {b: 'b' + str(b) for b in bot}
            z = assets.copy()
            z.update(banks)
            nx.relabel_nodes(G, z, copy=False)
            for node, data in G.nodes(data=True):
                if node.startswith('b'):
                    data['kind'] = 'bank'
                elif node.startswith('a'):
                    data['kind'] = 'asset'
#            print 'random: ', average_degree(G), len(G)
        elif kind == 'powpow':
            G = nx.bipartite.configuration_model(map(int, round_rvs), map(int, round_rvs), create_using=nx.Graph())
            bot, top = nx.bipartite.sets(G)
            assets = {t: 'a' + str(t-num_of_banks) for t in top}
            banks = {b: 'b' + str(b) for b in bot}
            z = assets.copy()
            z.update(banks)
            nx.relabel_nodes(G, z, copy=False)
            for node,data in G.nodes(data=True):
                if node.startswith('b'):
                    data['kind'] = 'bank'
                else:
                    data['kind'] = 'asset'
#            print 'powpow: ', average_degree(G)
        elif kind == 'man_half_half':
            banks = ['b'+str(i) for i in range(num_of_banks)]
            assets = ['a'+str(i) for i in range(num_of_assets)]
            G = nx.Graph()
            G.add_nodes_from(banks,kind='bank')
            G.add_nodes_from(assets,kind='asset')
#            np.random.seed(1)
            for i,j in enumerate(round_rvs):
                G.add_edges_from([('b'+str(i),'a'+str(k)) for k in np.random.choice(num_of_assets,int(j),replace=False)])
#            print 'power law: ', average_degree(G)
        elif kind == 'auto_half_and_half':
            temp_rvs = round_rvs[:-1]     
#            np.random.seed(1)
            while True:            
                pois = np.random.poisson(np.mean(round_rvs),num_of_assets)
                pd.Series(pois).hist()
                rem = sum(pois)-sum(temp_rvs)
                if rem < 0:
                    continue
                else:
                    if ((p-1)*(min_holdings**(p-1)))*(rem**(-p)) > 0.0001:
                        round_rvs[-1] = rem
                        break
                    else:
                        continue
            G = nx.bipartite.configuration_model(map(int, round_rvs), map(int, pois), create_using=nx.Graph())
            bot,top = nx.bipartite.sets(G)
            assets = {t: 'a' + str(t-num_of_banks) for t in top}
            banks = {b: 'b' + str(b) for b in bot}
            z = assets.copy()
            z.update(banks)
            nx.relabel_nodes(G,z,copy=False)
            for node,data in G.nodes(data=True):
                if node.startswith('b'):
                    data['kind'] = 'bank'
                else:
                    data['kind'] = 'asset'
#            print 'auto_h_h: ', average_degree(G)
        if project_network:
            G = nx.bipartite.project(G,[node for node,data in G.nodes(data=True) if data['kind']=='bank'])
            for node,data in G.nodes(data=True):
                data['init_deg'] = G.degree(node)
        else:
            if add_fedfunds:
                G.add_node('f01')
                new_edges = [('f01', 'b'+str(i)) for i in random.sample(range(num_of_banks), add_fedfunds)]
                G.add_edges_from(new_edges)
                G.node['f01']['kind'] = 'fed'

    else:
        if kind == 'er':
            # np.random.seed(1)
            G = nx.fast_gnp_random_graph(num_of_banks, np.mean(round_rvs)/num_of_banks)
        elif kind == 'man_half_half':
            if not nx.is_valid_degree_sequence(map(int,round_rvs)):
                round_rvs[0] += 1
            G = nx.configuration_model(map(int, round_rvs), create_using=nx.Graph())
        banks = {b: 'b' + str(b) for b in range(num_of_banks)}
        nx.relabel_nodes(G, banks, copy=False)
        for node, data in G.nodes(data=True):
            data['kind'] = 'bank'
    for node,data in G.nodes(data=True):
        data['init_deg'] = G.degree(node)
    return G
Beispiel #44
0
def test_atlas():
    for graph in nx.graph_atlas_g():
        deg = list(graph.degree().values())
        assert_true( nx.is_valid_degree_sequence(deg, method='eg') )
        assert_true( nx.is_valid_degree_sequence(deg, method='hh') )        
Random graph from given degree sequence.
Draw degree histogram with matplotlib.

"""
__author__ = """Aric Hagberg ([email protected])"""

try:
    import matplotlib.pyplot as plt
    import matplotlib
except:
    raise

import networkx as nx

z=nx.create_degree_sequence(100,nx.utils.powerlaw_sequence,exponent=2.1)
nx.is_valid_degree_sequence(z)

print "Configuration model"
G=nx.configuration_model(z)  # configuration model

degree_sequence=sorted(nx.degree(G).values(),reverse=True) # degree sequence
#print "Degree sequence", degree_sequence
dmax=max(degree_sequence)

plt.loglog(degree_sequence,'b-',marker='o')
plt.title("Degree rank plot")
plt.ylabel("degree")
plt.xlabel("rank")

# draw graph in inset 
plt.axes([0.45,0.45,0.45,0.45])
 def __init__(self, population,degree_seq=None,m=None):
     # Create a population of agents
     self.agents=list()
     if type(population)==int and population>0:
         for a in range(population):
             self.agents.append(Agent(agent_id=a))
     else:
         raise ValueError("Model must have positive number of agents")
     # Get total wealth in state
     self.state_wealth=sum(map(lambda a: a.get_wealth(),self.agents))
     if m is None:
         self.threshold=.25*self.state_wealth
     else:
         if m>=0 and m<=1:
             self.threshold=m*self.state_wealth
         else:
             raise ValueError("Value for m must be between 0 and 1")
     # Create network
     if degree_seq is None:
     # If no degree sequence is provided create wealth-based preferential attachment
     # This is the default setting for the model
         for i in xrange(population):
             for j in xrange(population):
                 if i!=j:
                     prob_tie=uniform(low=0,high=1)
                     # Tie probability function of agent's wealth relative to 
                     # total wealth in state
                     if prob_tie<=self.agents[j].get_wealth()/self.state_wealth:
                     # Create symmetric ties between neighbors
                         self.agents[i].make_tie(self.agents[j])
                         self.agents[j].make_tie(self.agents[i])
     else:
         if(nx.is_valid_degree_sequence(degree_seq) and len(degree_seq)==population):
             # Use NX configuration model to create network from degree sequence. By default,
             # the configuration model returns a MultiGraph type with edges assigned at random.
             # For consistency, the network type returned is Graph, and the random seed is
             # always set to the number of agents in the environment.
             G=nx.generators.configuration_model(degree_seq,create_using=nx.Graph(),seed=population)
             for e in G.edges():
                 self.agents[e[0]].make_tie(self.agents[e[1]])
                 self.agents[e[1]].make_tie(self.agents[e[0]])
         else:
             raise nx.NetworkXError('Invalid degree sequence')
     # Calculate all agent's m_net parameter
     for a in self.agents:  
         agent_neighbors=a.get_neighbors()
         # Get wealth of all neighbors
         y_net=sum(map(lambda n: self.agents[n].get_wealth(),agent_neighbors))
         # Calculate m_net
         m_net=0
         for n in agent_neighbors:
             n_wealth=self.agents[n].get_wealth()
             n_disposition=self.agents[n].get_disposition()
             m_net+=n_disposition*(n_wealth/y_net)
         a.set_mnet(m_net)
     # Set all agents contribution levels based on their network position
     for a in self.agents:
         # Get all relevant agent info
         agent_type=a.get_type()
         agent_mnet=a.get_mnet()
         agent_wealth=a.get_wealth()
         agent_neighbors=a.get_neighbors()
         if agent_type == 0:
         # Altruistic type
             a.set_contrib(0.5*a.get_disposition())
         else:
             if agent_type==1:
             # Community type
                 unmet=self.threshold-agent_mnet # Level of weath needed to meet threshold
                 if unmet>0:
                     if unmet<agent_wealth:
                         a.set_contrib((unmet/agent_wealth)*a.get_disposition())
                     else:
                     # Agent commits all wealth if threshold out of reach
                         a.set_contrib(1.0*a.get_disposition())
                 else:
                     a.set_contrib(0.0)
             else:
                 if agent_type==2:
                 # Min-match type
                     if agent_mnet>0:
                         min_neighbor=min(map(lambda n: self.agents[n].get_wealth(),agent_neighbors))
                         min_prop=min_neighbor/agent_mnet
                         if min_prop<1:
                             a.set_contrib(min_prop*a.get_disposition())
                         else:
                             a.set_contrib(1.0*a.get_disposition())
                     else:
                         a.set_contrib(random()*a.get_disposition())
                 else:
                     if agent_type==3:
                     # Max-match type
                         if agent_mnet>0:
                             max_neighbor=max(map(lambda n: self.agents[n].get_wealth(),agent_neighbors))
                             max_prop=max_neighbor/agent_mnet
                             if max_prop<1:
                                 a.set_contrib(max_prop*a.get_disposition())
                             else:
                                 a.set_contrib(1.0*a.get_disposition())
                         else:
                             a.set_contrib(random()*a.get_disposition())
                     else:
                     # Miserly type
                         a.set_contrib(uniform(0.0,0.05)*a.get_disposition())
     # Finally, check to see if threshold has been met
     self.total_contribs=sum(map(lambda a: a.get_contrib()*a.get_wealth(),self.agents))
     if(self.total_contribs>=self.threshold):
         self.threshold_met=True
     else:
         self.threshold_met=False