Example #1
0
    def test_generate_sparse6(self):
        # Checked against sage encoder
        assert_equal(nx.generate_sparse6(nx.empty_graph(0)), '>>sparse6<<:?')
        assert_equal(nx.generate_sparse6(nx.empty_graph(1)), '>>sparse6<<:@')
        assert_equal(nx.generate_sparse6(nx.empty_graph(5)), '>>sparse6<<:D')
        assert_equal(nx.generate_sparse6(nx.empty_graph(68)),
                     '>>sparse6<<:~?@C')
        assert_equal(nx.generate_sparse6(nx.empty_graph(258049)),
                     '>>sparse6<<:~~???~?@')

        G1 = nx.complete_graph(4)
        assert_equal(nx.generate_sparse6(G1, header=True),
                     '>>sparse6<<:CcKI')
        assert_equal(nx.generate_sparse6(G1, header=False), ':CcKI')

        # Padding testing
        assert_equal(nx.generate_sparse6(nx.path_graph(4), header=False),
                     ':Cdv')
        assert_equal(nx.generate_sparse6(nx.path_graph(5), header=False),
                     ':DaYn')
        assert_equal(nx.generate_sparse6(nx.path_graph(6), header=False),
                     ':EaYnN')
        assert_equal(nx.generate_sparse6(nx.path_graph(7), header=False),
                     ':FaYnL')
        assert_equal(nx.generate_sparse6(nx.path_graph(8), header=False),
                     ':GaYnLz')
Example #2
0
def SBM(nvec,block_probs, directed=True, seed=None):
    """Return a graph sampled from a stochastic block model
    
    Parameters
    ----------
    nvec : array [k,1]
        The number of vertices per block; there are k blocks.
    B : array [k,k] in (0,1)^{k x k}
        Probability for edge creation for each block.
    seed : int, optional
        Seed for random number generator (default=None). 
    
      math
    Notes
    -----    
    loopy : bool, optional (default=True)
        If True return a loopy graph
    
    This algorithm iterates over pairs of blocks and then assigns edges uniformly at random
    between nodes in each block
    """
    
    if (block_probs<0).any():
        raise ValueError('some probability is <0')
    if (block_probs>1).any():
        raise ValueError('some probability is >1')
    if np.shape(block_probs)[0] != len(nvec):
        raise ValueError('nvec must be of length equal to the number of columns/rows of block_probs')
    
    if seed:
        np.random.seed(seed)
    
    Nvertices=nvec.sum()        # total number of vertices
    Nblocks=len(nvec)             # number of groups
    if directed:
        G=nx.empty_graph(Nvertices,create_using=nx.DiGraph())
    else:
        G=nx.empty_graph(Nvertices,create_using=nx.Graph())
    block_idx = np.append(0, nvec).cumsum()
    block = np.zeros(Nvertices, dtype=np.int)
    
    for ii in xrange(Nblocks):
        nodes1 = np.arange(block_idx[ii],block_idx[ii+1])
        block[block_idx[ii]:block_idx[ii+1]] = ii
        if directed:
            add_random_edges_between(G, nodes1, block_probs[ii,ii],nodes1)
        else:
            add_random_edges_between(G, nodes1, block_probs[ii,ii])
            
        for jj in xrange(ii+1,Nblocks):
            nodes2 = np.arange(block_idx[jj],block_idx[jj+1])
            if directed:
                add_random_edges_between(G, nodes1, block_probs[ii,jj],nodes2)
                add_random_edges_between(G, nodes2, block_probs[jj,ii],nodes1)
            else:
                add_random_edges_between(G, nodes1, block_probs[ii,jj],nodes2)

    nx.set_node_attributes(G, 'block', dict(zip(np.arange(Nvertices), block)))
    return G
Example #3
0
 def test_empty_subgraph(self):
     # Subgraph of an empty graph is an empty graph. test 1
     nullgraph = nx.null_graph()
     E5 = nx.empty_graph(5)
     E10 = nx.empty_graph(10)
     H = E10.subgraph([])
     assert_true(nx.is_isomorphic(H, nullgraph))
     H = E10.subgraph([1, 2, 3, 4, 5])
     assert_true(nx.is_isomorphic(H, E5))
Example #4
0
def test_strong_product():
    null=nx.null_graph()
    empty1=nx.empty_graph(1)
    empty10=nx.empty_graph(10)
    K2=nx.complete_graph(2)
    K3=nx.complete_graph(3)
    K5=nx.complete_graph(5)
    K10=nx.complete_graph(10)
    P2=nx.path_graph(2)
    P3=nx.path_graph(3)
    P5=nx.path_graph(5)
    P10=nx.path_graph(10)
    # null graph
    G=strong_product(null,null)
    assert_true(nx.is_isomorphic(G,null))
    # null_graph X anything = null_graph and v.v.
    G=strong_product(null,empty10)
    assert_true(nx.is_isomorphic(G,null))
    G=strong_product(null,K3)
    assert_true(nx.is_isomorphic(G,null))
    G=strong_product(null,K10)
    assert_true(nx.is_isomorphic(G,null))
    G=strong_product(null,P3)
    assert_true(nx.is_isomorphic(G,null))
    G=strong_product(null,P10)
    assert_true(nx.is_isomorphic(G,null))
    G=strong_product(empty10,null)
    assert_true(nx.is_isomorphic(G,null))
    G=strong_product(K3,null)
    assert_true(nx.is_isomorphic(G,null))
    G=strong_product(K10,null)
    assert_true(nx.is_isomorphic(G,null))
    G=strong_product(P3,null)
    assert_true(nx.is_isomorphic(G,null))
    G=strong_product(P10,null)
    assert_true(nx.is_isomorphic(G,null))

    G=strong_product(P5,K3)
    assert_equal(nx.number_of_nodes(G),5*3)
    G=strong_product(K3,K5)
    assert_equal(nx.number_of_nodes(G),3*5)

    #No classic easily found classic results for strong product

    G = nx.erdos_renyi_graph(10,2/10.)
    H = nx.erdos_renyi_graph(10,2/10.)
    GH = strong_product(G,H)

    for (u_G,u_H) in GH.nodes_iter():
        for (v_G,v_H) in GH.nodes_iter():
            if (u_G==v_G and H.has_edge(u_H,v_H)) or \
               (u_H==v_H and G.has_edge(u_G,v_G)) or \
               (G.has_edge(u_G,v_G) and H.has_edge(u_H,v_H)):
                assert_true(GH.has_edge((u_G,u_H),(v_G,v_H)))
            else:
                assert_true(not GH.has_edge((u_G,u_H),(v_G,v_H)))
Example #5
0
    def extract_graph(self):

        graph = nx.Graph()
        nx.empty_graph(self.n, graph)

	for i in range(self.n):
            graph.node[i] = self.agent[i].opinion
            for j in range(self.agent[i].degree):
                graph.add_edge(i, self.agent[i].neighbors[j])

        return graph
Example #6
0
    def __init__(self, n, f, q, id_topology = 'Nan', nmm = 1, noise = 0.00):

        nx.Graph.__init__(self)
        nx.empty_graph(n, self)

        self.init_agents(n, f, q)

        self.init_mass_media(nmm, f, q)

        if id_topology != 'Nan':
            self.set_topology(id_topology)

        self.noise = noise
Example #7
0
    def test_generate_graph6(self):
        assert_equal(nx.generate_graph6(nx.empty_graph(0)), '>>graph6<<?')
        assert_equal(nx.generate_graph6(nx.empty_graph(1)), '>>graph6<<@')

        G1 = nx.complete_graph(4)
        assert_equal(nx.generate_graph6(G1, header=True), '>>graph6<<C~')
        assert_equal(nx.generate_graph6(G1, header=False), 'C~')

        G2 = nx.complete_bipartite_graph(6,9)
        assert_equal(nx.generate_graph6(G2, header=False),
                     'N??F~z{~Fw^_~?~?^_?') # verified by Sage

        G3 = nx.complete_graph(67)
        assert_equal(nx.generate_graph6(G3, header=False),
                     '~?@B' + '~' * 368 + 'w')
Example #8
0
def random_social_graph(g, l, S, k, a):
    N = g*2**l
    G = nx.empty_graph(N)
    # create the social coordinates vs
    vs = np.zeros((S,N,l), dtype=int)
    # for every characteristic
    for s in range(S):
        # want to choose g elements at random for every coordinate
        random_nodes = list(range(N))
        random.shuffle(random_nodes)
        for ch in all_coordinates(l):
            for node in random_nodes[0:g]:
                vs[s, node, :] = ch
            del random_nodes[0:g]

    # collect all distances in a matrix
    social_matrix = social_distance_matrix(vs)
    # now add edges until the average degree is greater or equal to k
    while nx.number_of_edges(G) < N*k/2:
        # choose random node
        node1 = np.random.randint(N)
        # and random characteristic
        s = np.random.randint(S)
        # create probabilities
        probs = [ np.exp( -a * social_matrix[s, node1, node2] ) for node2 in range(N) ]
        # finally pick a node to connect to
        node2 = node1
        while node2 == node1 or G.has_edge(node1, node2): node2 = random_pick( list(range(N)), probs )
        #while node2 == node1: node2 = random_pick( list(range(N)), probs )
        G.add_edge(node1, node2)
    # done constructing the graph
    return G, social_matrix, vs
def random_tree(n, create_using=None,seed=None):
    """ Returns a random tree of size n

    Proceeds by creating nodes and selecting uniformly at random
    an existing node to connect to.

    Parameters:
    -----------
    n : int
        Number of nodes
    create_using: networkx graph
                  graph to determine type
    seed: int
          Random seed value

    Returns:
    --------
    G: networkx Graph
       A random tree
    """

    if seed is not None:
        random.seed(seed)

    G = nx.empty_graph(0,create_using)

    G.add_node(0)
    for i in range(1,n):
        u = random.choice(G.nodes())
        G.add_node(i)
        G.add_edge(i,u)
    return G
Example #10
0
    def get_graph_of_cluster(self, grids):
        # print '%%%%%%%%%%%%%%%%%%%%%is valid: ', self.is_valid_cluster(grids), ' %%%'
        # print 'graph of cluster grids keys: ', grids.keys()
        indices_list = grids.keys()
        g = nx.empty_graph()
        for i in range(len(indices_list)):
            indices = indices_list[i]
            # print 'indices: ', indices
            for j in range(len(indices_list)):
                other_indices = indices_list[j]
                # print 'other_indices: ', other_indices
                # print 'i, oi: ', indices, other_indices
                if self.are_neighbors(indices, other_indices):
                    # print '***** ', indices, other_indices, ' ARE neighbors'
                    if g.has_edge(indices, other_indices) == False:
                        g.add_edge(indices, other_indices)
                        continue
                g.add_node(other_indices)
            if g.has_node(indices) == False:
                g.add_node(indices)

        # print 'g size {}'.format(g.size())


        return g
Example #11
0
def Gen2DLattice(size):
    side = sqrt(size)
    if not side.is_integer():
        print("Error: the size of lattice is not perfect square!")
        sys.exit()

    G = nx.empty_graph(size)

    for i in range(size):
        r = i // side
        c = i % side
        # Now we have to add 4 edges to the neighbours of i_th node
        # Adding edge to the neighbour: (r+1,c)
        l = ((r+1) % side) * side + c
        G.add_edge(i,l)
        # Adding edge to the neighbour: (r-1,c)
        l = ((r-1) % side) * side + c
        G.add_edge(i,l)
        # Adding edge to the neighbour: (r,c+1)
        l = r * side + ((c+1) % side)
        G.add_edge(i,l)
        # Adding edge to the neighbour: (r,c-1)
        l = r * side + ((c-1) % side)
        G.add_edge(i,l)

    return G
def generate_graph(n, beta, mean_degree):
    """
    Test Graph generation
    """
    G = nx.empty_graph(n)
    
    degreeArray = utils.degreeDistribution(beta, n, mean_degree)
    
    utils.randPairings(G, degreeArray)
    
    # output of the RGG
    if not os.path.exists('generated'):
        os.mkdir('generated')
    
    txtName = "generated/adj-%s-%s-%s-.txt" % (str(n), str(beta), str(mean_degree))
    nx.write_adjlist(G, txtName)
    
    # plotting
    utils.drawDegreeHistogram(G)
    if n < 1000:
        utils.drawGraph(G)
    pngname = "generated/graph-%s-%s-%s-.png" % (str(n), str(beta), str(mean_degree))
    plt.savefig(pngname)
    
    if not os.path.exists('feed'):
        os.mkdir('feed')
    
    utils.generateFeed(n)
Example #13
0
def test_cartesian_product_null():
    null=nx.null_graph()
    empty10=nx.empty_graph(10)
    K3=nx.complete_graph(3)
    K10=nx.complete_graph(10)
    P3=nx.path_graph(3)
    P10=nx.path_graph(10)
    # null graph
    G=cartesian_product(null,null)
    assert_true(nx.is_isomorphic(G,null))
    # null_graph X anything = null_graph and v.v.
    G=cartesian_product(null,empty10)
    assert_true(nx.is_isomorphic(G,null))
    G=cartesian_product(null,K3)
    assert_true(nx.is_isomorphic(G,null))
    G=cartesian_product(null,K10)
    assert_true(nx.is_isomorphic(G,null))
    G=cartesian_product(null,P3)
    assert_true(nx.is_isomorphic(G,null))
    G=cartesian_product(null,P10)
    assert_true(nx.is_isomorphic(G,null))
    G=cartesian_product(empty10,null)
    assert_true(nx.is_isomorphic(G,null))
    G=cartesian_product(K3,null)
    assert_true(nx.is_isomorphic(G,null))
    G=cartesian_product(K10,null)
    assert_true(nx.is_isomorphic(G,null))
    G=cartesian_product(P3,null)
    assert_true(nx.is_isomorphic(G,null))
    G=cartesian_product(P10,null)
    assert_true(nx.is_isomorphic(G,null))
Example #14
0
def wheel_graph(n, create_using=None):
    """ Return the wheel graph
    
    The wheel graph consists of a hub node connected to a cycle of (n-1) nodes.

    Parameters
    ==========
    n : int or iterable
        If an integer, node labels are 0 to n with center 0.
        If an iterable of nodes, the center is the first.
    create_using : Graph, optional (default Graph())
        If provided this graph is cleared of nodes and edges and filled
        with the new graph. Usually used to set the type of the graph.
    Node labels are the integers 0 to n - 1.

    """
    n_name, nodes = n
    if n_name == 0:
        G = nx.empty_graph(0, create_using=create_using)
        G.name = "wheel_graph(0)"
        return G
    G = star_graph(nodes, create_using)
    G.name = "wheel_graph(%s)" % (n_name,)
    if len(G) > 2:
        G.add_edges_from(pairwise(nodes[1:]))
        G.add_edge(nodes[-1], nodes[1])
    return G
Example #15
0
def create_c11_graph(N, g, l, S, k, alpha):
	G = nx.empty_graph(N)
	vs = np.zeros((S,N,l)) -1
	for s in range(S):
		distinct = int(N/g + 0.5)
		vs_distinct = np.zeros((distinct, l))
		
		for i in range(distinct):
			for j in range(l):
				vs_distinct[i,j] = i/(2**(l-j-1))%2
		
		for i in range(distinct):
			for gg in range(int(g)):
				node = -1
				while node == -1:
					node = np.random.randint(N)
					if vs[s, node,0] != -1:
						node = -1
				vs[s, node,:] = vs_distinct[i,:]
	
	x = social_distance_matrix(vs)
	while nx.number_of_edges(G) < N*k:
		i = np.random.randint(N)
		s = np.random.randint(S)
		j = i
		probabilities = np.zeros(N)
		for q in range(N):
			probabilities[q] = np.exp(-alpha*x[s, i, q])
		while j == i:
			j = random_pick(range(N), probabilities)
		G.add_edge(i,j)
	return G, x, vs
Example #16
0
def generic_graph_view(G, create_using=None):
    if create_using is None:
        newG = G.__class__()
    else:
        newG = nx.empty_graph(0, create_using)
    if G.is_multigraph() != newG.is_multigraph():
        raise NetworkXError("Multigraph for G must agree with create_using")
    newG = nx.freeze(newG)

    # create view by assigning attributes from G
    newG._graph = G
    newG.graph = G.graph

    newG._node = G._node
    if newG.is_directed():
        if G.is_directed():
            newG._succ = G._succ
            newG._pred = G._pred
            newG._adj = G._succ
        else:
            newG._succ = G._adj
            newG._pred = G._adj
            newG._adj = G._adj
    elif G.is_directed():
        if G.is_multigraph():
            newG._adj = UnionMultiAdjacency(G._succ, G._pred)
        else:
            newG._adj = UnionAdjacency(G._succ, G._pred)
    else:
        newG._adj = G._adj
    return newG
 def test_eccentricity(self):
     assert_equal(networkx.eccentricity(self.G, 1), 6)
     e = networkx.eccentricity(self.G)
     assert_equal(e[1], 6)
     sp = dict(networkx.shortest_path_length(self.G))
     e = networkx.eccentricity(self.G, sp=sp)
     assert_equal(e[1], 6)
     e = networkx.eccentricity(self.G, v=1)
     assert_equal(e, 6)
     # This behavior changed in version 1.8 (ticket #739)
     e = networkx.eccentricity(self.G, v=[1, 1])
     assert_equal(e[1], 6)
     e = networkx.eccentricity(self.G, v=[1, 2])
     assert_equal(e[1], 6)
     # test against graph with one node
     G = networkx.path_graph(1)
     e = networkx.eccentricity(G)
     assert_equal(e[0], 0)
     e = networkx.eccentricity(G, v=0)
     assert_equal(e, 0)
     assert_raises(networkx.NetworkXError, networkx.eccentricity, G, 1)
     # test against empty graph
     G = networkx.empty_graph()
     e = networkx.eccentricity(G)
     assert_equal(e, {})
Example #18
0
def draw_graph(username, password, filename='graph.txt', label_flag=True, remove_isolated=True, different_size=True, iso_level=10, node_size=40):
    """Reading data from file and draw the graph.If not exists, create the file and re-scratch data from net"""
    print "Generating graph..."
    try:
        with open(filename, 'r') as f:
            G = p.load(f)
    except:
        G = getgraph(username, password)
        with open(filename, 'w') as f:
            p.dump(G, f)
    #nx.draw(G)
    # Judge whether remove the isolated point from graph
    if remove_isolated is True:
        H = nx.empty_graph()
        for SG in nx.connected_component_subgraphs(G):
            if SG.number_of_nodes() > iso_level:
                H = nx.union(SG, H)
        G = H
    # Ajust graph for better presentation
    if different_size is True:
        L = nx.degree(G)
        G.dot_size = {}
        for k, v in L.items():
            G.dot_size[k] = v
        node_size = [G.dot_size[v] * 10 for v in G]
    pos = nx.spring_layout(G, iterations=50)
    nx.draw_networkx_edges(G, pos, alpha=0.2)
    nx.draw_networkx_nodes(G, pos, node_size=node_size, node_color='r', alpha=0.3)
    # Judge whether shows label
    if label_flag is True:
        nx.draw_networkx_labels(G, pos, alpha=0.5)
    #nx.draw_graphviz(G)
    plt.show()

    return G
Example #19
0
def _lg_directed(G, create_using=None):
    """Return the line graph L of the (multi)digraph G.

    Edges in G appear as nodes in L, represented as tuples of the form (u,v)
    or (u,v,key) if G is a multidigraph. A node in L corresponding to the edge
    (u,v) is connected to every node corresponding to an edge (v,w).

    Parameters
    ----------
    G : digraph
        A directed graph or directed multigraph.
    create_using : NetworkX graph constructor, optional
       Graph type to create. If graph instance, then cleared before populated.
       Default is to use the same graph class as `G`.

    """
    L = nx.empty_graph(0, create_using, default=G.__class__)

    # Create a graph specific edge function.
    get_edges = _edge_func(G)

    for from_node in get_edges():
        # from_node is: (u,v) or (u,v,key)
        L.add_node(from_node)
        for to_node in get_edges(from_node[1]):
            L.add_edge(from_node, to_node)

    return L
Example #20
0
def k_random_intersection_graph(n,m,k):
    """Return a intersection graph with randomly chosen attribute sets for
    each node that are of equal size (k). 

    Parameters
    ----------
    n : int
        The number of nodes in the first bipartite set (nodes)
    m : int
        The number of nodes in the second bipartite set (attributes)
    k : float
        Size of attribute set to assign to each node.
    seed : int, optional
        Seed for random number generator (default=None). 

    See Also
    --------
    gnp_random_graph, uniform_random_intersection_graph

    References
    ----------
    .. [1] Godehardt, E., and Jaworski, J.
       Two models of random intersection graphs and their applications.
       Electronic Notes in Discrete Mathematics 10 (2001), 129--132.
    """
    G = nx.empty_graph(n + m)
    mset = range(n,n+m)
    for v in range(n):
        targets = random.sample(mset, k)
        G.add_edges_from(zip([v]*len(targets), targets))
    return nx.projected_graph(G, range(n))
Example #21
0
def full_rary_tree(r, n, create_using=None):
    """Creates a full r-ary tree of n vertices.

    Sometimes called a k-ary, n-ary, or m-ary tree.
    "... all non-leaf vertices have exactly r children and all levels
    are full except for some rightmost position of the bottom level
    (if a leaf at the bottom level is missing, then so are all of the
    leaves to its right." [1]_

    Parameters
    ----------
    r : int
        branching factor of the tree
    n : int
        Number of nodes in the tree
    create_using : Graph, optional (default None)
        If provided this graph is cleared of nodes and edges and filled
        with the new graph. Usually used to set the type of the graph.

    Returns
    -------
    G : networkx Graph
        An r-ary tree with n nodes

    References
    ----------
    .. [1] An introduction to data structures and algorithms,
           James Andrew Storer,  Birkhauser Boston 2001, (page 225).
    """
    G = nx.empty_graph(n, create_using)
    G.add_edges_from(_tree_edges(n, r))
    return G
Example #22
0
def binomial_tree(n):
    """Returns the Binomial Tree of order n.
    
    The binomial tree of order 0 consists of a single vertex. A binomial tree of order k 
    is defined recursively by linking two binomial trees of order k-1: the root of one is 
    the leftmost child of the root of the other.

    Parameters
    ----------
    n : int
        Order of the binomial tree.

    Returns
    -------
    G : NetworkX graph
        A binomial tree of $2^n$ vertices and $2^n - 1$ edges.

    """
    G = nx.empty_graph(1)
    N = 1
    for i in range(n):
        edges = [(u + N, v + N)  for (u, v) in G.edges]
        G.add_edges_from(edges)
        G.add_edge(0,N)
        N *= 2
    return G
Example #23
0
 def test_non_symmetric_min_unsat(self):
     G = nx.complete_graph(4)
     T = nx.empty_graph(4)
     edges = list(combinations(G.nodes(), 2))
     T.add_edges_from(edges[1:])
     F = SubgraphFormula(G, [T])
     self.assertUNSAT(F)
def RGG(n, beta, mean_degree):
    G = nx.empty_graph(n)
    powerLawArray = utils.powerLawArray(n, beta, mean_degree)
    powerLawDegreeArray = np.array(powerLawArray, dtype = np.longlong)
    sumOfDegrees = powerLawDegreeArray.sum()
    delimiterArray = np.cumsum(powerLawDegreeArray)
    delimiterArray = np.insert(delimiterArray, 0, 0)
    delimiterArray = np.delete(delimiterArray, n)
    someCounter = 0
    while someCounter < sumOfDegrees/2:
        G.add_edge(np.searchsorted(delimiterArray, rnd.randrange(sumOfDegrees)),
               np.searchsorted(delimiterArray, rnd.randrange(sumOfDegrees)))
        someCounter += 1
    txtname = "generated/adj-%s-%s-%s-.txt" % (str(n), str(beta), str(mean_degree))
    nx.write_adjlist(G, txtname)
    degreeSequence=sorted(nx.degree(G).values(),reverse=True)
    dmax=max(degreeSequence)
    plt.clf()
    plt.cla()
    plt.loglog(degreeSequence,'b-',marker='o')
    plt.title("Degree rank plot")
    plt.ylabel("degree")
    plt.xlabel("rank")
    if n < 1000:
        plt.axes([0.45,0.45,0.45,0.45])
        plt.cla()
        Gcc=nx.connected_component_subgraphs(G)[0]
        pos=nx.spring_layout(Gcc)
        plt.axis('off')
        nx.draw_networkx_nodes(Gcc,pos,node_size=20)
        nx.draw_networkx_edges(Gcc,pos,alpha=0.4)
    pngname = "generated/graph-%s-%s-%s-.png" % (str(n), str(beta), str(mean_degree))
    plt.savefig(pngname)
Example #25
0
def draw_graph(label_flag=True, remove_isolated=True, different_size=True, iso_level=10, node_size=40):
    G=build_graph(fb.get_friends_network())
    betweenness=nx.betweenness_centrality(G)
    degree=nx.degree_centrality(G)
    degree_num=[ degree[v] for v in G]
    maxdegree=max(degree_num);mindegree=min(degree_num);
    print maxdegree,mindegree
    clustering=nx.clustering(G)
    print nx.transitivity(G)
    # Judge whether remove the isolated point from graph
    if remove_isolated is True:
        H = nx.empty_graph()
        for SG in nx.connected_component_subgraphs(G):
            if SG.number_of_nodes() > iso_level:
                H = nx.union(SG, H)
        G = H
    # Ajust graph for better presentation
    if different_size is True:
        L = nx.degree(G)
        G.dot_size = {}
        for k, v in L.items():
            G.dot_size[k] = v
        #node_size = [betweenness[v] *1000 for v in G]
        node_size = [G.dot_size[v] * 10 for v in G]
        node_color= [((degree[v]-mindegree))/(maxdegree-mindegree) for v in G]
        #edge_width = [getcommonfriends(u,v) for u,v in G.edges()]
    pos = nx.spring_layout(G, iterations=15)
    nx.draw_networkx_edges(G, pos, alpha=0.05)
    nx.draw_networkx_nodes(G, pos, node_size=node_size, node_color=node_color, vmin=0.0,vmax=1.0, alpha=0.3)
    # Judge whether shows label
    if label_flag is True:
        nx.draw_networkx_labels(G, pos, font_size=6,alpha=0.1)
    #nx.draw_graphviz(G)
    plt.show()
    return G
Example #26
0
def setup_graph(ingredients, cuisine_name):
   # dict with random values for the position of the nodes
   p = dict((i,(random.gauss(0,2),random.gauss(0,2))) for i in range(len(ingredients)))

   # creating the graph
   G = nx.empty_graph()
   G.add_nodes_from(p) 
   
   # Setting an attribute with the position of each node in the graph
   pos = nx.set_node_attributes(G,'pos', p)

   # Creating the nodes
   node_trace = Scatter(
       x = [], 
       y = [], 
       text = [],
       name = cuisine_name,
       mode = 'markers', 
       hoverinfo = 'text')

   # adding positions for the nodes
   for node in G.nodes():
       x, y = G.node[node]['pos']
       node_trace['x'].append(x)
       node_trace['y'].append(y)

   # naming the nodes
   node_trace['text'].extend(ingredients)
    
   return node_trace
Example #27
0
def bipartite_alternating_havel_hakimi_graph(aseq, bseq,
                                            create_using=None,
                                            ):
    """
    Return a bipartite graph from two given degree sequences
    using a alternating Havel-Hakimi style construction.

    :Parameters:
       - `aseq`: degree sequence for node set A
       - `bseq`: degree sequence for node set B

    Nodes from the set A are connected to nodes in the set B by
    connecting the highest degree nodes in set A to
    alternatively the highest and the lowest degree nodes in set
    B until all stubs are connected.

    The sum of the two sequences must be equal: sum(aseq)=sum(bseq)
    """
    if create_using==None:
        create_using=NX.MultiGraph()

    G=NX.empty_graph(0,create_using)

    # length of the each sequence
    naseq=len(aseq)
    nbseq=len(bseq)
    suma=sum(aseq)
    sumb=sum(bseq)

    if not suma==sumb:
        raise NX.NetworkXError, \
              'invalid degree sequences, sum(aseq)!=sum(bseq),%s,%s'\
              %(suma,sumb)

    G.add_nodes_from(range(0,naseq)) # one vertex type (a)
    G.add_nodes_from(range(naseq,naseq+nbseq)) # the other type (b)

    if max(aseq)==0: return G  # done if no edges
    # build list of degree-repeated vertex numbers
    astubs=[[aseq[v],v] for v in range(0,naseq)]  
    bstubs=[[bseq[v-naseq],v] for v in range(naseq,naseq+nbseq)]  
    while astubs:
        astubs.sort()
        (degree,u)=astubs.pop() # take of largest degree node in the a set
        if degree==0: break # done, all are zero
        bstubs.sort()
        small=bstubs[0:degree/2]  # add these low degree targets     
        large=bstubs[(-degree+degree/2):] # and these high degree targets
        stubs=[x for z in zip(large,small) for x in z] # combine, sorry
        if len(stubs)<len(small)+len(large): # check for zip truncation
            stubs.append(large.pop())
        for target in stubs:
            v=target[1]
            G.add_edge(u,v)
            target[0] -= 1  # note this updates bstubs too.
            if target[0]==0:
                bstubs.remove(target)

    G.name="bipartite_alternating_havel_hakimi_graph"
    return G
Example #28
0
    def __init__(self, blockHeights):
        """
        Creates an occurence graph based on navigatable nodes (nodes at height 0)
        """
        self.width = len(blockHeights)
        self.height = len(blockHeights[0])
        self.g = nx.empty_graph(self.width * self.height)
        self.blockHeights = blockHeights
        self.prob = np.zeros(len(self.g.nodes())) #[0.0] * len(self.g.nodes())

        def isNavigabaleNode(nodeId):
            """ Returns false if a block is present else returns true """
            x, y = self.getCood(nodeId)
            return False if self.blockHeights[x][y] > 0 else True

        def getNeighbouringNodes(nodeId):
            """ Returns a list of nodes in all 8 directions from the given node """
            x, y = self.getCood(nodeId)
            neighbouringNodes = []
            for xoffset in range(-1, 2):
                for yoffset in range(-1, 2):
                    if xoffset == 0 and yoffset == 0:
                        continue
                    xn = x + xoffset
                    yn = y + yoffset
                    if xn < 0 or xn >= self.width or yn < 0 or yn >= self.height:
                        continue
                    neighbouringNodes.append(self.getNodeId(xn, yn))
            return neighbouringNodes

        for nodeId in self.g.nodes():
            neighbouringNodes = getNeighbouringNodes(nodeId)
            navigatableNodes = filter(isNavigabaleNode, neighbouringNodes)
            #print nodeId, len(navigatableNodes)
            self.g.add_edges_from([(nodeId, navigatableNode) for navigatableNode in navigatableNodes])
    def firstFitTopo(self, jobs, reservations):
        if len(jobs) != len(reservations):
            raise IndexError("Length of jobs and reservations input lists do no match")

        import networkx as nx
        skeleton = nx.barabasi_albert_graph(780)
        G = nx.empty_graph()
Example #30
0
def bipartite_preferential_attachment_graph(aseq,p,create_using=None):
    """Create a bipartite graph with a preferential attachment model
    from a given single degree sequence.

    Parameters
    ----------
    aseq : list or iterator
       Degree sequence for node set A.
    p :  float
       Probability that a new bottom node is added.
    create_using : NetworkX graph instance, optional
       Return graph of this type.

    Notes
    -----

     @article{guillaume-2004-bipartite,
       author = {Jean-Loup Guillaume and Matthieu Latapy},
       title = {Bipartite structure of all complex networks},
       journal = {Inf. Process. Lett.},
       volume = {90},
       number = {5},
       year = {2004},
       issn = {0020-0190},
       pages = {215--221},
       doi = {http://dx.doi.org/10.1016/j.ipl.2004.03.007},
       publisher = {Elsevier North-Holland, Inc.},
       address = {Amsterdam, The Netherlands, The Netherlands},
       }

    """
    if create_using==None:
        create_using=networkx.MultiGraph()

    G=networkx.empty_graph(0,create_using)

    if p > 1: 
        raise networkx.NetworkXError, "probability %s > 1"%(p)

    naseq=len(aseq)
    G.add_nodes_from(range(0,naseq))
    vv=[ [v]*aseq[v] for v in range(0,naseq)]
    while vv:
        while vv[0]:
            source=vv[0][0]
            vv[0].remove(source)
            if random.random() < p or G.number_of_nodes() == naseq:
                target=G.number_of_nodes()
                G.add_edge(source,target)
            else:
                bb=[ [b]*G.degree(b) for b in range(naseq,G.number_of_nodes())]
                # flatten the list of lists into a list.
                bbstubs=reduce(lambda x,y: x+y, bb) 
                # choose preferentially a bottom node.
                target=random.choice(bbstubs) 
                G.add_edge(source,target)
        vv.remove(vv[0])
    G.name="bipartite_preferential_attachment_model"
    return G
def configuration_model(aseq, bseq, create_using=None, seed=None):
    """Returns a random bipartite graph from two given degree sequences.

    Parameters
    ----------
    aseq : list
       Degree sequence for node set A.
    bseq : list
       Degree sequence for node set B.
    create_using : NetworkX graph instance, optional
       Return graph of this type.
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.

    Nodes from the set A are connected to nodes in the set B by
    choosing randomly from the possible free stubs, one in A and
    one in B.

    Notes
    -----
    The sum of the two sequences must be equal: sum(aseq)=sum(bseq)
    If no graph type is specified use MultiGraph with parallel edges.
    If you want a graph with no parallel edges use create_using=Graph()
    but then the resulting degree sequences might not be exact.

    The nodes are assigned the attribute 'bipartite' with the value 0 or 1
    to indicate which bipartite set the node belongs to.

    This function is not imported in the main namespace.
    To use it you have to explicitly import the bipartite package.
    """
    G = nx.empty_graph(0, create_using, default=nx.MultiGraph)
    if G.is_directed():
        raise nx.NetworkXError("Directed Graph not supported")

    # length and sum of each sequence
    lena = len(aseq)
    lenb = len(bseq)
    suma = sum(aseq)
    sumb = sum(bseq)

    if not suma == sumb:
        raise nx.NetworkXError(
            'invalid degree sequences, sum(aseq)!=sum(bseq),%s,%s'
            % (suma, sumb))

    G = _add_nodes_with_bipartite_label(G, lena, lenb)

    if len(aseq) == 0 or max(aseq) == 0:
        return G  # done if no edges

    # build lists of degree-repeated vertex numbers
    stubs = []
    stubs.extend([[v] * aseq[v] for v in range(0, lena)])
    astubs = []
    astubs = [x for subseq in stubs for x in subseq]

    stubs = []
    stubs.extend([[v] * bseq[v - lena] for v in range(lena, lena + lenb)])
    bstubs = []
    bstubs = [x for subseq in stubs for x in subseq]

    # shuffle lists
    seed.shuffle(astubs)
    seed.shuffle(bstubs)

    G.add_edges_from([[astubs[i], bstubs[i]] for i in range(suma)])

    G.name = "bipartite_configuration_model"
    return G
Example #32
0
def from_pydot(P):
    """Return a NetworkX graph from a Pydot graph.

    Parameters
    ----------
    P : Pydot graph
      A graph created with Pydot

    Returns
    -------
    G : NetworkX multigraph
        A MultiGraph or MultiDiGraph.

    Examples
    --------
    >>> K5=nx.complete_graph(5)
    >>> A=nx.to_pydot(K5)
    >>> G=nx.from_pydot(A) # return MultiGraph
    >>> G=nx.Graph(nx.from_pydot(A)) # make a Graph instead of MultiGraph

    """
    if P.get_strict(None): # pydot bug: get_strict() shouldn't take argument
        multiedges=False
    else:
        multiedges=True

    if P.get_type()=='graph': # undirected
        if multiedges:
            create_using=nx.MultiGraph()
        else:
            create_using=nx.Graph()
    else:
        if multiedges:
            create_using=nx.MultiDiGraph()
        else:
            create_using=nx.DiGraph()

    # assign defaults
    N=nx.empty_graph(0,create_using)
    N.name=P.get_name()

    # add nodes, attributes to N.node_attr
    for p in P.get_node_list():
        n=p.get_name().strip('"')
        if n in ('node','graph','edge'):
            continue
        N.add_node(n,**p.get_attributes())

    # add edges
    for e in P.get_edge_list():
        u=e.get_source()
        v=e.get_destination()
        attr=e.get_attributes()
        s=[]
        d=[]

        if isinstance(u, basestring):
            s.append(u.strip('"'))
        else:
            for unodes in u['nodes'].iterkeys():
                s.append(unodes.strip('"'))

        if isinstance(v, basestring):
            d.append(v.strip('"'))
        else:
            for vnodes in v['nodes'].iterkeys():
                d.append(vnodes.strip('"'))

        for source_node in s:
            for destination_node in d:
                N.add_edge(source_node,destination_node,**attr)

    # add default attributes for graph, nodes, edges
    N.graph['graph']=P.get_attributes()
    try:
        N.graph['node']=P.get_node_defaults()[0]
    except:# IndexError,TypeError:
        N.graph['node']={}
    try:
        N.graph['edge']=P.get_edge_defaults()[0]
    except:# IndexError,TypeError:
        N.graph['edge']={}
    return N
Example #33
0
 def test_empty(self):
     with pytest.raises(nx.NetworkXException):
         G = nx.empty_graph()
         nx.second_order_centrality(G)
Example #34
0
def expected_degree_graph(w, seed=None, selfloops=True):
    r"""Returns a random graph with given expected degrees.

    Given a sequence of expected degrees $W=(w_0,w_1,\ldots,w_{n-1})$
    of length $n$ this algorithm assigns an edge between node $u$ and
    node $v$ with probability

    .. math::

       p_{uv} = \frac{w_u w_v}{\sum_k w_k} .

    Parameters
    ----------
    w : list
        The list of expected degrees.
    selfloops: bool (default=True)
        Set to False to remove the possibility of self-loop edges.
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.

    Returns
    -------
    Graph

    Examples
    --------
    >>> z = [10 for i in range(100)]
    >>> G = nx.expected_degree_graph(z)

    Notes
    -----
    The nodes have integer labels corresponding to index of expected degrees
    input sequence.

    The complexity of this algorithm is $\mathcal{O}(n+m)$ where $n$ is the
    number of nodes and $m$ is the expected number of edges.

    The model in [1]_ includes the possibility of self-loop edges.
    Set selfloops=False to produce a graph without self loops.

    For finite graphs this model doesn't produce exactly the given
    expected degree sequence.  Instead the expected degrees are as
    follows.

    For the case without self loops (selfloops=False),

    .. math::

       E[deg(u)] = \sum_{v \ne u} p_{uv}
                = w_u \left( 1 - \frac{w_u}{\sum_k w_k} \right) .


    NetworkX uses the standard convention that a self-loop edge counts 2
    in the degree of a node, so with self loops (selfloops=True),

    .. math::

       E[deg(u)] =  \sum_{v \ne u} p_{uv}  + 2 p_{uu}
                = w_u \left( 1 + \frac{w_u}{\sum_k w_k} \right) .

    References
    ----------
    .. [1] Fan Chung and L. Lu, Connected components in random graphs with
       given expected degree sequences, Ann. Combinatorics, 6,
       pp. 125-145, 2002.
    .. [2] Joel Miller and Aric Hagberg,
       Efficient generation of networks with given expected degrees,
       in Algorithms and Models for the Web-Graph (WAW 2011),
       Alan Frieze, Paul Horn, and Paweł Prałat (Eds), LNCS 6732,
       pp. 115-126, 2011.
    """
    n = len(w)
    G = nx.empty_graph(n)

    # If there are no nodes are no edges in the graph, return the empty graph.
    if n == 0 or max(w) == 0:
        return G

    rho = 1 / sum(w)
    # Sort the weights in decreasing order. The original order of the
    # weights dictates the order of the (integer) node labels, so we
    # need to remember the permutation applied in the sorting.
    order = sorted(enumerate(w), key=itemgetter(1), reverse=True)
    mapping = {c: u for c, (u, v) in enumerate(order)}
    seq = [v for u, v in order]
    last = n
    if not selfloops:
        last -= 1
    for u in range(last):
        v = u
        if not selfloops:
            v += 1
        factor = seq[u] * rho
        p = min(seq[v] * factor, 1)
        while v < n and p > 0:
            if p != 1:
                r = seed.random()
                v += int(math.floor(math.log(r, 1 - p)))
            if v < n:
                q = min(seq[v] * factor, 1)
                if seed.random() < q / p:
                    G.add_edge(mapping[u], mapping[v])
                v += 1
                p = q
    return G
Example #35
0
def encoding(configs):
    ''' encode the subgraph to flat vector which is input of classifier '''
    ''' Bulid the Graph '''

    f = open(configs["basedir"] + "pa_edges_set.p", "rb")
    pa_edges_set = pickle.load(f)
    f.close()

    n_nodes = max(list(map(lambda x: max(x), pa_edges_set)))
    n_links = len(pa_edges_set)
    print("Encoding - # of total nodes in graph : ", n_nodes)
    print("Encoding - # of total links in graph : ", n_links)

    graph_edges = treat_Warning1(pa_edges_set)

    network = nx.empty_graph()
    network.add_edges_from(graph_edges)

    for node_idx in range(n_nodes):
        if node_idx not in list(network.nodes):
            network.add_node(node_idx)
    ''' Load Train data '''

    f = open(configs["basedir"] + configs["target"] + "/pos_communities.p",
             "rb")
    _pos_communities = pickle.load(f)
    f.close()
    pos_communities = _pos_communities["data"]
    pos_communities = treat_Warning1(pos_communities)

    f = open(configs["basedir"] + configs["target"] + "/neg_communities.p",
             "rb")
    _neg_communities = pickle.load(f)
    f.close()
    neg_communities = _neg_communities["data"]

    query_Train_edges = pos_communities + neg_communities
    query_Train_labels = [1] * len(pos_communities) + [0
                                                       ] * len(neg_communities)
    query_Train_edges, query_Train_labels = shuffle(query_Train_edges,
                                                    query_Train_labels)

    print("Encoding - # of Train edges : ", len(query_Train_edges))
    ''' Load Test data '''

    f = open(configs["basedir"] + "qpu_edges_raw_duplicate.p", 'rb')
    _query_Test_edges = pickle.load(f)
    f.close()
    _query_Test_edges = treat_Warning1(_query_Test_edges)

    f = open(configs["basedir"] + "apu_labels_raw_duplicate.p", 'rb')
    _query_Test_labels = pickle.load(f)
    f.close()

    if configs["target"] == "edges":
        query_Test_edges = []
        query_Test_labels = []
        for idx in range(len(_query_Test_edges)):
            if len(_query_Test_edges[idx]) == 2:
                query_Test_edges.append(_query_Test_edges[idx])
                query_Test_labels.append(_query_Test_labels[idx])
    elif configs["target"] == "raw":
        query_Test_edges = _query_Test_edges
        query_Test_labels = _query_Test_labels
    else:
        print("!!!Please check configs!!!")
        return
    print("Encoding - # of Test edges : ", len(query_Test_edges))
    ''' Encoding '''

    if configs["exist_node2vec"]:
        type_n2v = "n2v"
    else:
        type_n2v = "nn2v"

    dirname = configs["basedir"] + "encoded_vector/" + type_n2v + "/" + str(
        configs["h_size"]) + "/pickle/"
    if not os.path.isdir(dirname):
        os.mkdir(dirname)

    f = open(dirname + "configs.txt", "w")
    for k in configs.keys():
        f.write(str(k) + " : " + str(configs[k]))
        f.write("\n")
    f.close()

    gwl = GWL(graph=network, configs=configs)

    start = time.time()

    num_train_batch = int(len(query_Train_edges) / configs["batch_size"])

    for idx1 in range(num_train_batch):
        batch_dict = dict()
        cnt = 0
        for idx2 in range(configs["batch_size"]):
            if idx2 % 100 == 0:
                print("Encoding Train data - ", idx1, idx2)
            try:
                query = tuple(query_Train_edges[idx1 * configs["batch_size"] +
                                                idx2])
            except:
                break
            adj_vector = gwl.convert_into_adj_vector(query_data=query)
            if query in batch_dict.keys():
                print(query)
                break
            else:
                batch_dict[cnt] = [
                    query, adj_vector,
                    query_Train_labels[idx1 * configs["batch_size"] + idx2]
                ]
                cnt += 1

        f = open(dirname + "train_adj_vectors_" + str(idx1) + ".p", "wb")
        pickle.dump(batch_dict, f)
        f.close()

    num_test_batch = int(len(query_Test_edges) / configs["batch_size"])

    for idx1 in range(num_test_batch):
        batch_dict = dict()
        cnt = 0
        for idx2 in range(configs["batch_size"]):
            if idx2 % 100 == 0:
                print("Encoding Test data - ", idx1, idx2)
            try:
                query = tuple(query_Test_edges[idx1 * configs["batch_size"] +
                                               idx2])
            except:
                break
            adj_vector = gwl.convert_into_adj_vector(query_data=query)
            if query in batch_dict.keys():
                print(query)
                break
            else:
                batch_dict[cnt] = [
                    cnt, adj_vector,
                    query_Test_labels[idx1 * configs["batch_size"] + idx2]
                ]
                cnt += 1

        f = open(dirname + "test_adj_vectors_" + str(idx1) + ".p", "wb")
        pickle.dump(batch_dict, f)
        f.close()

    print("Encoding - Elapsed time : ", time.time() - start)
 def test_empty(self):
     expected = True
     actual = is_planar(nx.empty_graph())
     self.assertEqual(expected, actual)
     actual = is_planar(nx.empty_graph(15))
     self.assertEqual(expected, actual)
        if visited[u]:
            continue
        # neighbors = sortlistwithmap(sigmamapping, list(G.neighbors(u)))
        neighbors = adjacencylist[u]
        for node in neighbors:
            if (sigmamapping[node] < sigmamapping[u] and not visited[node]):
                v = node
                M.append((v, u))
                Nkv = BreadthFirstKLevels(G, v, k)
                Nku = BreadthFirstKLevels(G, u, k)
                for node in Nkv:
                    visited[node] = True
                for node in Nku:
                    visited[node] = True
                visited[u] = True
                visited[v] = True
                G.remove_nodes_from(Nkv)
                G.remove_nodes_from(Nku)
    return M


#generate the tree graph
n = 200
G = nx.empty_graph(n)
G.add_edges_from(list(_tree_edges(n, 4)))
H = G.copy()
nx.write_adjlist(G, "test.adjlist")
IM = induced_matching(H)
k = 3
DkM = distancekmatching(H, k)
Example #38
0
def join(rooted_trees, label_attribute=None):
    """Returns a new rooted tree with a root node joined with the roots
    of each of the given rooted trees.

    Parameters
    ----------
    rooted_trees : list
        A list of pairs in which each left element is a NetworkX graph
        object representing a tree and each right element is the root
        node of that tree. The nodes of these trees will be relabeled to
        integers.

    label_attribute : str
        If provided, the old node labels will be stored in the new tree
        under this node attribute. If not provided, the node attribute
        ``'_old'`` will store the original label of the node in the
        rooted trees given in the input.

    Returns
    -------
    NetworkX graph
        The rooted tree whose subtrees are the given rooted trees. The
        new root node is labeled 0. Each non-root node has an attribute,
        as described under the keyword argument ``label_attribute``,
        that indicates the label of the original node in the input tree.

    Notes
    -----
    Graph, edge, and node attributes are propagated from the given
    rooted trees to the created tree. If there are any overlapping graph
    attributes, those from later trees will overwrite those from earlier
    trees in the tuple of positional arguments.

    Examples
    --------
    Join two full balanced binary trees of height *h* to get a full
    balanced binary tree of depth *h* + 1::

        >>> h = 4
        >>> left = nx.balanced_tree(2, h)
        >>> right = nx.balanced_tree(2, h)
        >>> joined_tree = nx.join([(left, 0), (right, 0)])
        >>> nx.is_isomorphic(joined_tree, nx.balanced_tree(2, h + 1))
        True

    """
    if len(rooted_trees) == 0:
        return nx.empty_graph(1)

    # Unzip the zipped list of (tree, root) pairs.
    trees, roots = zip(*rooted_trees)

    # The join of the trees has the same type as the type of the first
    # tree.
    R = type(trees[0])()

    # Relabel the nodes so that their union is the integers starting at 1.
    if label_attribute is None:
        label_attribute = "_old"
    relabel = partial(
        nx.convert_node_labels_to_integers, label_attribute=label_attribute
    )
    lengths = (len(tree) for tree in trees[:-1])
    first_labels = chain([0], accumulate(lengths))
    trees = [
        relabel(tree, first_label=first_label + 1)
        for tree, first_label in zip(trees, first_labels)
    ]

    # Get the relabeled roots.
    roots = [
        next(v for v, d in tree.nodes(data=True) if d.get("_old") == root)
        for tree, root in zip(trees, roots)
    ]

    # Remove the old node labels.
    for tree in trees:
        for v in tree:
            tree.nodes[v].pop("_old")

    # Add all sets of nodes and edges, with data.
    nodes = (tree.nodes(data=True) for tree in trees)
    edges = (tree.edges(data=True) for tree in trees)
    R.add_nodes_from(chain.from_iterable(nodes))
    R.add_edges_from(chain.from_iterable(edges))

    # Add graph attributes; later attributes take precedent over earlier
    # attributes.
    for tree in trees:
        R.graph.update(tree.graph)

    # Finally, join the subtrees at the root. We know 0 is unused by the
    # way we relabeled the subtrees.
    R.add_node(0)
    R.add_edges_from((0, root) for root in roots)

    return R
Example #39
0
def from_dict_of_dicts(d, create_using=None, multigraph_input=False):
    """Returns a graph from a dictionary of dictionaries.

    Parameters
    ----------
    d : dictionary of dictionaries
      A dictionary of dictionaries adjacency representation.

    create_using : NetworkX graph constructor, optional (default=nx.Graph)
        Graph type to create. If graph instance, then cleared before populated.

    multigraph_input : bool (default False)
       When True, the values of the inner dict are assumed
       to be containers of edge data for multiple edges.
       Otherwise this routine assumes the edge data are singletons.

    Examples
    --------
    >>> dod = {0: {1: {"weight": 1}}}  # single edge (0,1)
    >>> G = nx.from_dict_of_dicts(dod)

    or

    >>> G = nx.Graph(dod)  # use Graph constructor

    """
    G = nx.empty_graph(0, create_using)
    G.add_nodes_from(d)
    # is dict a MultiGraph or MultiDiGraph?
    if multigraph_input:
        # make a copy of the list of edge data (but not the edge data)
        if G.is_directed():
            if G.is_multigraph():
                G.add_edges_from((u, v, key, data) for u, nbrs in d.items()
                                 for v, datadict in nbrs.items()
                                 for key, data in datadict.items())
            else:
                G.add_edges_from((u, v, data) for u, nbrs in d.items()
                                 for v, datadict in nbrs.items()
                                 for key, data in datadict.items())
        else:  # Undirected
            if G.is_multigraph():
                seen = set()  # don't add both directions of undirected graph
                for u, nbrs in d.items():
                    for v, datadict in nbrs.items():
                        if (u, v) not in seen:
                            G.add_edges_from((u, v, key, data)
                                             for key, data in datadict.items())
                            seen.add((v, u))
            else:
                seen = set()  # don't add both directions of undirected graph
                for u, nbrs in d.items():
                    for v, datadict in nbrs.items():
                        if (u, v) not in seen:
                            G.add_edges_from(
                                (u, v, data) for key, data in datadict.items())
                            seen.add((v, u))

    else:  # not a multigraph to multigraph transfer
        if G.is_multigraph() and not G.is_directed():
            # d can have both representations u-v, v-u in dict.  Only add one.
            # We don't need this check for digraphs since we add both directions,
            # or for Graph() since it is done implicitly (parallel edges not allowed)
            seen = set()
            for u, nbrs in d.items():
                for v, data in nbrs.items():
                    if (u, v) not in seen:
                        G.add_edge(u, v, key=0)
                        G[u][v][0].update(data)
                    seen.add((v, u))
        else:
            G.add_edges_from(((u, v, data) for u, nbrs in d.items()
                              for v, data in nbrs.items()))
    return G
Example #40
0
def parse_edgelist(lines,
                   comments='#',
                   delimiter=None,
                   create_using=None,
                   nodetype=None,
                   data=True):
    """Parse lines of an edge list representation of a graph.

    Parameters
    ----------
    lines : list or iterator of strings
        Input data in edgelist format
    comments : string, optional
       Marker for comment lines
    delimiter : string, optional
       Separator for node labels
    create_using : NetworkX graph constructor, optional (default=nx.Graph)
       Graph type to create. If graph instance, then cleared before populated.
    nodetype : Python type, optional
       Convert nodes to this type.
    data : bool or list of (label,type) tuples
       If False generate no edge data or if True use a dictionary
       representation of edge data or a list tuples specifying dictionary
       key names and types for edge data.

    Returns
    -------
    G: NetworkX Graph
        The graph corresponding to lines

    Examples
    --------
    Edgelist with no data:

    >>> lines = ["1 2",
    ...          "2 3",
    ...          "3 4"]
    >>> G = nx.parse_edgelist(lines, nodetype = int)
    >>> list(G)
    [1, 2, 3, 4]
    >>> list(G.edges())
    [(1, 2), (2, 3), (3, 4)]

    Edgelist with data in Python dictionary representation:

    >>> lines = ["1 2 {'weight':3}",
    ...          "2 3 {'weight':27}",
    ...          "3 4 {'weight':3.0}"]
    >>> G = nx.parse_edgelist(lines, nodetype = int)
    >>> list(G)
    [1, 2, 3, 4]
    >>> list(G.edges(data=True))
    [(1, 2, {'weight': 3}), (2, 3, {'weight': 27}), (3, 4, {'weight': 3.0})]

    Edgelist with data in a list:

    >>> lines = ["1 2 3",
    ...          "2 3 27",
    ...          "3 4 3.0"]
    >>> G = nx.parse_edgelist(lines, nodetype = int, data=(('weight',float),))
    >>> list(G)
    [1, 2, 3, 4]
    >>> list(G.edges(data=True))
    [(1, 2, {'weight': 3.0}), (2, 3, {'weight': 27.0}), (3, 4, {'weight': 3.0})]

    See Also
    --------
    read_weighted_edgelist
    """
    from ast import literal_eval
    G = nx.empty_graph(0, create_using)
    for line in lines:
        p = line.find(comments)
        if p >= 0:
            line = line[:p]
        if not len(line):
            continue
        # split line, should have 2 or more
        s = line.strip().split(delimiter)
        if len(s) < 2:
            continue
        u = s.pop(0)
        v = s.pop(0)
        d = s
        if nodetype is not None:
            try:
                u = nodetype(u)
                v = nodetype(v)
            except:
                raise TypeError("Failed to convert nodes %s,%s to type %s." %
                                (u, v, nodetype))

        if len(d) == 0 or data is False:
            # no data or data type specified
            edgedata = {}
        elif data is True:
            # no edge types specified
            try:  # try to evaluate as dictionary
                edgedata = dict(literal_eval(' '.join(d)))
            except:
                raise TypeError(
                    "Failed to convert edge data (%s) to dictionary." % (d))
        else:
            # convert edge data to dictionary with specified keys and type
            if len(d) != len(data):
                raise IndexError(
                    "Edge data %s and data_keys %s are not the same length" %
                    (d, data))
            edgedata = {}
            for (edge_key, edge_type), edge_value in zip(data, d):
                try:
                    edge_value = edge_type(edge_value)
                except:
                    raise TypeError(
                        "Failed to convert %s data %s to type %s." %
                        (edge_key, edge_value, edge_type))
                edgedata.update({edge_key: edge_value})
        G.add_edge(u, v, **edgedata)
    return G
Example #41
0
def directed_havel_hakimi_graph(in_deg_sequence,
                                out_deg_sequence,
                                create_using=None):
    """Returns a directed graph with the given degree sequences.

    Parameters
    ----------
    in_deg_sequence :  list of integers
        Each list entry corresponds to the in-degree of a node.
    out_deg_sequence : list of integers
        Each list entry corresponds to the out-degree of a node.
    create_using : NetworkX graph constructor, optional (default DiGraph)
        Graph type to create. If graph instance, then cleared before populated.

    Returns
    -------
    G : DiGraph
        A graph with the specified degree sequences.
        Nodes are labeled starting at 0 with an index
        corresponding to the position in deg_sequence

    Raises
    ------
    NetworkXError
        If the degree sequences are not digraphical.

    See Also
    --------
    configuration_model

    Notes
    -----
    Algorithm as described by Kleitman and Wang [1]_.

    References
    ----------
    .. [1] D.J. Kleitman and D.L. Wang
       Algorithms for Constructing Graphs and Digraphs with Given Valences
       and Factors Discrete Mathematics, 6(1), pp. 79-88 (1973)
    """
    in_deg_sequence = nx.utils.make_list_of_ints(in_deg_sequence)
    out_deg_sequence = nx.utils.make_list_of_ints(out_deg_sequence)

    # Process the sequences and form two heaps to store degree pairs with
    # either zero or nonzero out degrees
    sumin, sumout = 0, 0
    nin, nout = len(in_deg_sequence), len(out_deg_sequence)
    maxn = max(nin, nout)
    G = nx.empty_graph(maxn, create_using, default=nx.DiGraph)
    if maxn == 0:
        return G
    maxin = 0
    stubheap, zeroheap = [], []
    for n in range(maxn):
        in_deg, out_deg = 0, 0
        if n < nout:
            out_deg = out_deg_sequence[n]
        if n < nin:
            in_deg = in_deg_sequence[n]
        if in_deg < 0 or out_deg < 0:
            raise nx.NetworkXError(
                "Invalid degree sequences. Sequence values must be positive.")
        sumin, sumout, maxin = sumin + in_deg, sumout + out_deg, max(
            maxin, in_deg)
        if in_deg > 0:
            stubheap.append((-1 * out_deg, -1 * in_deg, n))
        elif out_deg > 0:
            zeroheap.append((-1 * out_deg, n))
    if sumin != sumout:
        raise nx.NetworkXError(
            "Invalid degree sequences. Sequences must have equal sums.")
    heapq.heapify(stubheap)
    heapq.heapify(zeroheap)

    modstubs = [(0, 0, 0)] * (maxin + 1)
    # Successively reduce degree sequence by removing the maximum
    while stubheap:
        # Remove first value in the sequence with a non-zero in degree
        (freeout, freein, target) = heapq.heappop(stubheap)
        freein *= -1
        if freein > len(stubheap) + len(zeroheap):
            raise nx.NetworkXError("Non-digraphical integer sequence")

        # Attach arcs from the nodes with the most stubs
        mslen = 0
        for i in range(freein):
            if zeroheap and (not stubheap or stubheap[0][0] > zeroheap[0][0]):
                (stubout, stubsource) = heapq.heappop(zeroheap)
                stubin = 0
            else:
                (stubout, stubin, stubsource) = heapq.heappop(stubheap)
            if stubout == 0:
                raise nx.NetworkXError("Non-digraphical integer sequence")
            G.add_edge(stubsource, target)
            # Check if source is now totally connected
            if stubout + 1 < 0 or stubin < 0:
                modstubs[mslen] = (stubout + 1, stubin, stubsource)
                mslen += 1

        # Add the nodes back to the heaps that still have available stubs
        for i in range(mslen):
            stub = modstubs[i]
            if stub[1] < 0:
                heapq.heappush(stubheap, stub)
            else:
                heapq.heappush(zeroheap, (stub[0], stub[2]))
        if freeout < 0:
            heapq.heappush(zeroheap, (freeout, target))

    return G
Example #42
0
def _configuration_model(deg_sequence,
                         create_using,
                         directed=False,
                         in_deg_sequence=None,
                         seed=None):
    """Helper function for generating either undirected or directed
    configuration model graphs.

    ``deg_sequence`` is a list of nonnegative integers representing the
    degree of the node whose label is the index of the list element.

    ``create_using`` see :func:`~networkx.empty_graph`.

    ``directed`` and ``in_deg_sequence`` are required if you want the
    returned graph to be generated using the directed configuration
    model algorithm. If ``directed`` is ``False``, then ``deg_sequence``
    is interpreted as the degree sequence of an undirected graph and
    ``in_deg_sequence`` is ignored. Otherwise, if ``directed`` is
    ``True``, then ``deg_sequence`` is interpreted as the out-degree
    sequence and ``in_deg_sequence`` as the in-degree sequence of a
    directed graph.

    .. note::

       ``deg_sequence`` and ``in_deg_sequence`` need not be the same
       length.

    ``seed`` is a random.Random or numpy.random.RandomState instance

    This function returns a graph, directed if and only if ``directed``
    is ``True``, generated according to the configuration model
    algorithm. For more information on the algorithm, see the
    :func:`configuration_model` or :func:`directed_configuration_model`
    functions.

    """
    n = len(deg_sequence)
    G = nx.empty_graph(n, create_using)
    # If empty, return the null graph immediately.
    if n == 0:
        return G
    # Build a list of available degree-repeated nodes.  For example,
    # for degree sequence [3, 2, 1, 1, 1], the "stub list" is
    # initially [0, 0, 0, 1, 1, 2, 3, 4], that is, node 0 has degree
    # 3 and thus is repeated 3 times, etc.
    #
    # Also, shuffle the stub list in order to get a random sequence of
    # node pairs.
    if directed:
        pairs = zip_longest(deg_sequence, in_deg_sequence, fillvalue=0)
        # Unzip the list of pairs into a pair of lists.
        out_deg, in_deg = zip(*pairs)

        out_stublist = _to_stublist(out_deg)
        in_stublist = _to_stublist(in_deg)

        seed.shuffle(out_stublist)
        seed.shuffle(in_stublist)
    else:
        stublist = _to_stublist(deg_sequence)
        # Choose a random balanced bipartition of the stublist, which
        # gives a random pairing of nodes. In this implementation, we
        # shuffle the list and then split it in half.
        n = len(stublist)
        half = n // 2
        seed.shuffle(stublist)
        out_stublist, in_stublist = stublist[:half], stublist[half:]
    G.add_edges_from(zip(out_stublist, in_stublist))
    return G
 def test_single_node(self):
     G = nx.empty_graph(1)
     ground_truth = {frozenset([0])}
     self._check_communities(G, ground_truth)
Example #44
0
def havel_hakimi_graph(deg_sequence, create_using=None):
    """Returns 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 : NetworkX graph constructor, optional (default=nx.Graph)
        Graph type to create. If graph instance, then cleared before populated.
        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_graphical(deg_sequence):
        raise nx.NetworkXError("Invalid degree sequence")

    p = len(deg_sequence)
    G = nx.empty_graph(p, create_using)
    if G.is_directed():
        raise nx.NetworkXError("Directed graphs are not supported")
    num_degs = [[] for i in range(p)]
    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

    return G
 def test_large_empty_graph(self):
     G = nx.empty_graph(68)
     result = BytesIO()
     nx.write_sparse6(G, result)
     self.assertEqual(result.getvalue(), '>>sparse6<<:~?@C\n')
def reverse_havel_hakimi_graph(aseq, bseq, create_using=None):
    """Returns a bipartite graph from two given degree sequences using a
    Havel-Hakimi style construction.

    Nodes from set A are connected to nodes in the set B by connecting
    the highest degree nodes in set A to the lowest degree nodes in
    set B until all stubs are connected.

    Parameters
    ----------
    aseq : list
       Degree sequence for node set A.
    bseq : list
       Degree sequence for node set B.
    create_using : NetworkX graph instance, optional
       Return graph of this type.

    Notes
    -----
    This function is not imported in the main namespace.
    To use it you have to explicitly import the bipartite package.

    The sum of the two sequences must be equal: sum(aseq)=sum(bseq)
    If no graph type is specified use MultiGraph with parallel edges.
    If you want a graph with no parallel edges use create_using=Graph()
    but then the resulting degree sequences might not be exact.

    The nodes are assigned the attribute 'bipartite' with the value 0 or 1
    to indicate which bipartite set the node belongs to.
    """
    G = nx.empty_graph(0, create_using, default=nx.MultiGraph)
    if G.is_directed():
        raise nx.NetworkXError("Directed Graph not supported")

    # length of the each sequence
    lena = len(aseq)
    lenb = len(bseq)
    suma = sum(aseq)
    sumb = sum(bseq)

    if not suma == sumb:
        raise nx.NetworkXError(
            'invalid degree sequences, sum(aseq)!=sum(bseq),%s,%s'
            % (suma, sumb))

    G = _add_nodes_with_bipartite_label(G, lena, lenb)

    if len(aseq) == 0 or max(aseq) == 0:
        return G  # done if no edges

    # build list of degree-repeated vertex numbers
    astubs = [[aseq[v], v] for v in range(0, lena)]
    bstubs = [[bseq[v - lena], v] for v in range(lena, lena + lenb)]
    astubs.sort()
    bstubs.sort()
    while astubs:
        (degree, u) = astubs.pop()  # take of largest degree node in the a set
        if degree == 0:
            break  # done, all are zero
        # connect the source to the smallest degree nodes in the b set
        for target in bstubs[0:degree]:
            v = target[1]
            G.add_edge(u, v)
            target[0] -= 1  # note this updates bstubs too.
            if target[0] == 0:
                bstubs.remove(target)

    G.name = "bipartite_reverse_havel_hakimi_graph"
    return G
def preferential_attachment_graph(aseq, p, create_using=None, seed=None):
    """Create a bipartite graph with a preferential attachment model from
    a given single degree sequence.

    Parameters
    ----------
    aseq : list
       Degree sequence for node set A.
    p :  float
       Probability that a new bottom node is added.
    create_using : NetworkX graph instance, optional
       Return graph of this type.
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.

    References
    ----------
    .. [1] Guillaume, J.L. and Latapy, M., 
       Bipartite graphs as models of complex networks.
       Physica A: Statistical Mechanics and its Applications,
       2006, 371(2), pp.795-813.
    .. [2] Jean-Loup Guillaume and Matthieu Latapy,
       Bipartite structure of all complex networks,
       Inf. Process. Lett. 90, 2004, pg. 215-221
       https://doi.org/10.1016/j.ipl.2004.03.007

    Notes
    -----

    This function is not imported in the main namespace.
    To use it you have to explicitly import the bipartite package.
    """
    G = nx.empty_graph(0, create_using, default=nx.MultiGraph)
    if G.is_directed():
        raise nx.NetworkXError("Directed Graph not supported")

    if p > 1:
        raise nx.NetworkXError("probability %s > 1" % (p))

    naseq = len(aseq)
    G = _add_nodes_with_bipartite_label(G, naseq, 0)
    vv = [[v] * aseq[v] for v in range(0, naseq)]
    while vv:
        while vv[0]:
            source = vv[0][0]
            vv[0].remove(source)
            if seed.random() < p or G.number_of_nodes() == naseq:
                target = G.number_of_nodes()
                G.add_node(target, bipartite=1)
                G.add_edge(source, target)
            else:
                bb = [[b] * G.degree(b) for b in range(naseq, G.number_of_nodes())]
                # flatten the list of lists into a list.
                bbstubs = reduce(lambda x, y: x + y, bb)
                # choose preferentially a bottom node.
                target = seed.choice(bbstubs)
                G.add_node(target, bipartite=1)
                G.add_edge(source, target)
        vv.remove(vv[0])
    G.name = "bipartite_preferential_attachment_model"
    return G
Example #48
0
    def test_disconnected_graph(self):
        """TestData that the Wiener index of a disconnected graph is
        positive infinity.

        """
        assert wiener_index(empty_graph(2)) == float("inf")
def alternating_havel_hakimi_graph(aseq, bseq, create_using=None):
    """Returns a bipartite graph from two given degree sequences using
    an alternating Havel-Hakimi style construction.

    Nodes from the set A are connected to nodes in the set B by
    connecting the highest degree nodes in set A to alternatively the
    highest and the lowest degree nodes in set B until all stubs are
    connected.

    Parameters
    ----------
    aseq : list
       Degree sequence for node set A.
    bseq : list
       Degree sequence for node set B.
    create_using : NetworkX graph instance, optional
       Return graph of this type.

    Notes
    -----
    This function is not imported in the main namespace.
    To use it you have to explicitly import the bipartite package.

    The sum of the two sequences must be equal: sum(aseq)=sum(bseq)
    If no graph type is specified use MultiGraph with parallel edges.
    If you want a graph with no parallel edges use create_using=Graph()
    but then the resulting degree sequences might not be exact.

    The nodes are assigned the attribute 'bipartite' with the value 0 or 1
    to indicate which bipartite set the node belongs to.
    """
    G = nx.empty_graph(0, create_using, default=nx.MultiGraph)
    if G.is_directed():
        raise nx.NetworkXError("Directed Graph not supported")

    # length of the each sequence
    naseq = len(aseq)
    nbseq = len(bseq)
    suma = sum(aseq)
    sumb = sum(bseq)

    if not suma == sumb:
        raise nx.NetworkXError(
            'invalid degree sequences, sum(aseq)!=sum(bseq),%s,%s'
            % (suma, sumb))

    G = _add_nodes_with_bipartite_label(G, naseq, nbseq)

    if len(aseq) == 0 or max(aseq) == 0:
        return G  # done if no edges
    # build list of degree-repeated vertex numbers
    astubs = [[aseq[v], v] for v in range(0, naseq)]
    bstubs = [[bseq[v - naseq], v] for v in range(naseq, naseq + nbseq)]
    while astubs:
        astubs.sort()
        (degree, u) = astubs.pop()  # take of largest degree node in the a set
        if degree == 0:
            break  # done, all are zero
        bstubs.sort()
        small = bstubs[0:degree // 2]  # add these low degree targets
        large = bstubs[(-degree + degree // 2):]  # and these high degree targets
        stubs = [x for z in zip(large, small) for x in z]  # combine, sorry
        if len(stubs) < len(small) + len(large):  # check for zip truncation
            stubs.append(large.pop())
        for target in stubs:
            v = target[1]
            G.add_edge(u, v)
            target[0] -= 1  # note this updates bstubs too.
            if target[0] == 0:
                bstubs.remove(target)

    G.name = "bipartite_alternating_havel_hakimi_graph"
    return G
Example #50
0
def configuration_model(deg_sequence, create_using=None, seed=None):
    """Returns a random graph with the given degree sequence.

    The configuration model generates a random pseudograph (graph with
    parallel edges and self loops) by randomly assigning edges to
    match the given degree sequence.

    Parameters
    ----------
    deg_sequence :  list of nonnegative integers
        Each list entry corresponds to the degree of a node.
    create_using : NetworkX graph constructor, optional (default MultiGraph)
        Graph type to create. If graph instance, then cleared before populated.
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.

    Returns
    -------
    G : MultiGraph
        A graph with the specified degree sequence.
        Nodes are labeled starting at 0 with an index
        corresponding to the position in deg_sequence.

    Raises
    ------
    NetworkXError
        If the degree sequence does not have an even sum.

    See Also
    --------
    is_graphical

    Notes
    -----
    As described by Newman [1]_.

    A non-graphical degree sequence (not realizable by some simple
    graph) is allowed since this function returns graphs with self
    loops and parallel edges.  An exception is raised if the degree
    sequence does not have an even sum.

    This configuration model construction process can lead to
    duplicate edges and loops.  You can remove the self-loops and
    parallel edges (see below) which will likely result in a graph
    that doesn't have the exact degree sequence specified.

    The density of self-loops and parallel edges tends to decrease as
    the number of nodes increases. However, typically the number of
    self-loops will approach a Poisson distribution with a nonzero mean,
    and similarly for the number of parallel edges.  Consider a node
    with *k* stubs. The probability of being joined to another stub of
    the same node is basically (*k* - *1*) / *N*, where *k* is the
    degree and *N* is the number of nodes. So the probability of a
    self-loop scales like *c* / *N* for some constant *c*. As *N* grows,
    this means we expect *c* self-loops. Similarly for parallel edges.

    References
    ----------
    .. [1] M.E.J. Newman, "The structure and function of complex networks",
       SIAM REVIEW 45-2, pp 167-256, 2003.

    Examples
    --------
    You can create a degree sequence following a particular distribution
    by using the one of the distribution functions in
    :mod:`~networkx.utils.random_sequence` (or one of your own). For
    example, to create an undirected multigraph on one hundred nodes
    with degree sequence chosen from the power law distribution:

    >>> sequence = nx.random_powerlaw_tree_sequence(100, tries=5000)
    >>> G = nx.configuration_model(sequence)
    >>> len(G)
    100
    >>> actual_degrees = [d for v, d in G.degree()]
    >>> actual_degrees == sequence
    True

    The returned graph is a multigraph, which may have parallel
    edges. To remove any parallel edges from the returned graph:

    >>> G = nx.Graph(G)

    Similarly, to remove self-loops:

    >>> G.remove_edges_from(nx.selfloop_edges(G))

    """
    if sum(deg_sequence) % 2 != 0:
        msg = "Invalid degree sequence: sum of degrees must be even, not odd"
        raise nx.NetworkXError(msg)

    G = nx.empty_graph(0, create_using, default=nx.MultiGraph)
    if G.is_directed():
        raise nx.NetworkXNotImplemented("not implemented for directed graphs")

    G = _configuration_model(deg_sequence, G, seed=seed)

    return G
Example #51
0
def from_agraph(A, create_using=None):
    """Return a NetworkX Graph or DiGraph from a PyGraphviz graph.

    Parameters
    ----------
    A : PyGraphviz AGraph
      A graph created with PyGraphviz

    create_using : NetworkX graph class instance
      The output is created using the given graph class instance

    Examples
    --------
    >>> K5 = nx.complete_graph(5)
    >>> A = nx.nx_agraph.to_agraph(K5)
    >>> G = nx.nx_agraph.from_agraph(A)
    >>> G = nx.nx_agraph.from_agraph(A)


    Notes
    -----
    The Graph G will have a dictionary G.graph_attr containing
    the default graphviz attributes for graphs, nodes and edges.

    Default node attributes will be in the dictionary G.node_attr
    which is keyed by node.

    Edge attributes will be returned as edge data in G.  With
    edge_attr=False the edge data will be the Graphviz edge weight
    attribute or the value 1 if no edge weight attribute is found.

    """
    if create_using is None:
        if A.is_directed():
            if A.is_strict():
                create_using = nx.DiGraph()
            else:
                create_using = nx.MultiDiGraph()
        else:
            if A.is_strict():
                create_using = nx.Graph()
            else:
                create_using = nx.MultiGraph()

    # assign defaults
    N = nx.empty_graph(0, create_using)
    N.name = ''
    if A.name is not None:
        N.name = A.name

    # add graph attributes
    N.graph.update(A.graph_attr)

    # add nodes, attributes to N.node_attr
    for n in A.nodes():
        str_attr = {str(k): v for k, v in n.attr.items()}
        N.add_node(str(n), **str_attr)

    # add edges, assign edge data as dictionary of attributes
    for e in A.edges():
        u, v = str(e[0]), str(e[1])
        attr = dict(e.attr)
        str_attr = {str(k): v for k, v in attr.items()}
        if not N.is_multigraph():
            if e.name is not None:
                str_attr['key'] = e.name
            N.add_edge(u, v, **str_attr)
        else:
            N.add_edge(u, v, key=e.name, **str_attr)

    # add default attributes for graph, nodes, and edges
    # hang them on N.graph_attr
    N.graph['graph'] = dict(A.graph_attr)
    N.graph['node'] = dict(A.node_attr)
    N.graph['edge'] = dict(A.edge_attr)
    return N
Example #52
0
def draw_graph(network,
               ax=None,
               figsize=(10, 10),
               edge_mode='current',
               colorbar=False,
               TE_mode='local',
               **kwargs):
    if edge_mode == 'TE':
        if hasattr(network, 'TE'):
            TimeVector = network.TimeVector[network.sampling]
        else:
            print('No TE attached to network yet. Please calcualte TE first.')
            from sys import exit
            exit()
    else:
        TimeVector = network.TimeVector

    if 'TimeStamp' in kwargs:
        this_TimeStamp = kwargs['TimeStamp']
    elif 'time' in kwargs:
        if kwargs['time'] in TimeVector:
            this_TimeStamp = np.where(TimeVector == kwargs['time'])[0][0]
            real_TimeStamp = np.where(
                network.TimeVector == kwargs['time'])[0][0]
        elif (kwargs['time'] < min(TimeVector)) or (kwargs['time'] >
                                                    max(TimeVector)):
            print('Input time exceeds simulation period.')
            this_TimeStamp = np.argmin(abs(TimeVector - kwargs['time']))
            real_TimeStamp = np.argmin(abs(network.TimeVector -
                                           kwargs['time']))
        else:
            this_TimeStamp = np.argmin(abs(TimeVector - kwargs['time']))
            real_TimeStamp = np.argmin(abs(network.TimeVector -
                                           kwargs['time']))
    else:
        this_TimeStamp = 0
        real_TimeStamp = 0

    G = nx.from_numpy_array(network.connectivity.adj_matrix)
    pos = nx.layout.kamada_kawai_layout(G)
    edgeList = network.connectivity.edge_list
    sources = network.sources
    drains = network.drains

    this_switch = network.junctionSwitch[real_TimeStamp, :]

    if edge_mode == 'current':
        graphView = nx.DiGraph()
        graphView.add_nodes_from(range(network.numOfWires))
        this_current = network.junctionVoltage[
            real_TimeStamp, :] / network.junctionResistance[real_TimeStamp, :]
        for i in range(network.numOfJunctions):
            if this_switch[i]:
                if this_current[i] > 0:
                    graphView.add_edge(edgeList[i, 0],
                                       edgeList[i, 1],
                                       weight=abs(this_current[i]),
                                       width=2,
                                       style='solid')
                else:
                    graphView.add_edge(edgeList[i, 1],
                                       edgeList[i, 0],
                                       weight=abs(this_current[i]),
                                       width=2,
                                       style='solid')

    elif edge_mode == 'voltage':
        graphView = nx.empty_graph(network.numOfWires)
        this_voltage = network.junctionVoltage[this_TimeStamp, :]
        for i in range(network.numOfJunctions):
            if this_switch[i]:
                graphView.add_edge(edgeList[i, 0],
                                   edgeList[i, 1],
                                   weight=abs(this_voltage[i]),
                                   width=2,
                                   style='solid')
            else:
                graphView.add_edge(edgeList[i, 0],
                                   edgeList[i, 1],
                                   weight=abs(this_voltage[i]),
                                   width=1,
                                   style='dashed')

    elif edge_mode == 'filament':
        graphView = nx.empty_graph(network.numOfWires)
        this_filament = network.filamentState[this_TimeStamp, :]
        for i in range(network.numOfJunctions):
            if this_switch[i]:
                graphView.add_edge(edgeList[i, 0],
                                   edgeList[i, 1],
                                   weight=abs(this_filament[i]),
                                   width=2,
                                   style='solid')
            else:
                graphView.add_edge(edgeList[i, 0],
                                   edgeList[i, 1],
                                   weight=abs(this_filament[i]),
                                   width=1,
                                   style='dashed')

    elif edge_mode == 'Lyapunov':
        graphView = nx.empty_graph(network.numOfWires)
        if not hasattr(network, 'Lyapunov'):
            print('Lyapunov not calculated')
            network.Lyapunov = np.zeros(network.numOfJunctions)
        for i in range(network.numOfJunctions):
            if this_switch[i]:
                graphView.add_edge(edgeList[i, 0],
                                   edgeList[i, 1],
                                   weight=network.Lyapunov[i],
                                   width=2,
                                   style='solid')
            else:
                graphView.add_edge(edgeList[i, 0],
                                   edgeList[i, 1],
                                   weight=network.Lyapunov[i],
                                   width=1,
                                   style='dashed')

    elif edge_mode == 'TE':
        graphView = nx.empty_graph(network.numOfWires)
        if TE_mode == 'local':
            this_TE = network.TE[this_TimeStamp, :]
        elif TE_mode == 'average':
            this_TE = np.mean(network.TE[:this_TimeStamp, :], axis=0)

        for i in range(network.numOfJunctions):
            if this_switch[i]:
                graphView.add_edge(edgeList[i, 0],
                                   edgeList[i, 1],
                                   weight=this_TE[i],
                                   width=2,
                                   style='solid')
            else:
                graphView.add_edge(edgeList[i, 0],
                                   edgeList[i, 1],
                                   weight=this_TE[i],
                                   width=1,
                                   style='dashed')

    from analysis.GraphTheory import getOnGraph
    tempGraph = getOnGraph(network, this_TimeStamp=real_TimeStamp)
    pathFormed = nx.has_path(tempGraph, sources[0], drains[0])

    edge_colors = [graphView[u][v]['weight'] for u, v in graphView.edges]
    widths = [graphView[u][v]['width'] for u, v in graphView.edges]
    styles = [graphView[u][v]['style'] for u, v in graphView.edges]

    node_colors = ['#1f78b4'] * len(graphView)
    for i in sources:
        node_colors[i] = 'g'
    for i in drains:
        node_colors[i] = 'r'
    plt.style.use('classic')

    if ax == None:
        fig, ax = plt.subplots(figsize=figsize)
        ax.axis('off')

    if pathFormed:
        cmap = plt.cm.Reds
    else:
        cmap = plt.cm.Blues

    cmap_min = 0
    if len(edge_colors) == 0:
        cmap_max = 1
    elif edge_mode == 'current':
        cmap_max = max(edge_colors)
    elif edge_mode == 'voltage':
        cmap_max = np.max(abs(network.junctionVoltage))
    elif edge_mode == 'filament':
        cmap_max = np.max(network.filamentState)
    elif edge_mode == 'Lyapunov':
        cmap_min = np.min(network.Lyapunov)
        cmap_max = np.max(network.Lyapunov)
    elif edge_mode == 'TE':
        cmap_min = np.min(this_TE)
        cmap_max = np.max(this_TE)

    nx.draw_networkx(graphView,
                     pos,
                     node_size=350,
                     node_color=node_colors,
                     edge_color=edge_colors,
                     edge_cmap=cmap,
                     edge_vmin=cmap_min,
                     edge_vmax=cmap_max,
                     font_color='w',
                     width=widths,
                     style=styles,
                     ax=ax)

    if edge_mode == 'current':
        nx.draw_networkx_edges(G, pos, width=1, alpha=0.15, ax=ax)

    ax.set_facecolor((0.8, 0.8, 0.8))
    if (edge_mode == 'TE') & (TE_mode == 'average'):
        ax.set_title(
            f'Network average TE from t = 0 to {np.round(TimeVector[this_TimeStamp],3)}'
        )
    else:
        ax.set_title('Network ' + edge_mode +
                     f' at t = {np.round(TimeVector[this_TimeStamp],3)}')
    ax.get_xaxis().set_ticks([])
    ax.get_yaxis().set_ticks([])

    if colorbar:
        sm = plt.cm.ScalarMappable(cmap=cmap,
                                   norm=plt.Normalize(vmin=cmap_min,
                                                      vmax=cmap_max))
        sm.set_array([])
        cbar = plt.colorbar(sm, ax=ax, fraction=0.05, label=edge_mode)

    return ax
Example #53
0
 def test_must_be_connected(self):
     pytest.raises(nx.NetworkXNoPath, nx.barycenter, nx.empty_graph(5))
Example #54
0
def joint_degree_graph(joint_degrees, seed=None):
    """ Generates a random simple graph with the given joint degree dictionary.

    Parameters
    ----------
    joint_degrees :  dictionary of dictionary of integers
        A joint degree dictionary in which entry ``joint_degrees[k][l]`` is the
        number of edges joining nodes of degree *k* with nodes of degree *l*.
    seed : integer, random_state, or None (default)
        Indicator of random number generation state.
        See :ref:`Randomness<randomness>`.

    Returns
    -------
    G : Graph
        A graph with the specified joint degree dictionary.

    Raises
    ------
    NetworkXError
        If *joint_degrees* dictionary is not realizable.

    Notes
    -----
    In each iteration of the "while loop" the algorithm picks two disconnected
    nodes *v* and *w*, of degree *k* and *l* correspondingly,  for which
    ``joint_degrees[k][l]`` has not reached its target yet. It then adds
    edge (*v*, *w*) and increases the number of edges in graph G by one.

    The intelligence of the algorithm lies in the fact that  it is always
    possible to add an edge between such disconnected nodes *v* and *w*,
    even if one or both nodes do not have free stubs. That is made possible by
    executing a "neighbor switch", an edge rewiring move that releases
    a free stub while keeping the joint degree of G the same.

    The algorithm continues for E (number of edges) iterations of
    the "while loop", at the which point all entries of the given
    ``joint_degrees[k][l]`` have reached their target values and the
    construction is complete.

    References
    ----------
    ..  [1] M. Gjoka, B. Tillman, A. Markopoulou, "Construction of Simple
        Graphs with a Target Joint Degree Matrix and Beyond", IEEE Infocom, '15.

    Examples
    --------
    >>> import networkx as nx
    >>> joint_degrees = {1: {4: 1},
    ...                      2: {2: 2, 3: 2, 4: 2},
    ...                      3: {2: 2, 4: 1},
    ...                      4: {1: 1, 2: 2, 3: 1}}
    >>> G=nx.joint_degree_graph(joint_degrees)
    >>>
    """

    if not is_valid_joint_degree(joint_degrees):
        msg = 'Input joint degree dict not realizable as a simple graph'
        raise nx.NetworkXError(msg)

    # compute degree count from joint_degrees
    degree_count = {
        k: sum(l.values()) // k
        for k, l in joint_degrees.items() if k > 0
    }

    # start with empty N-node graph
    N = sum(degree_count.values())
    G = nx.empty_graph(N)

    # for a given degree group, keep the list of all node ids
    h_degree_nodelist = {}

    # for a given node, keep track of the remaining stubs
    h_node_residual = {}

    # populate h_degree_nodelist and h_node_residual
    nodeid = 0
    for degree, num_nodes in degree_count.items():
        h_degree_nodelist[degree] = range(nodeid, nodeid + num_nodes)
        for v in h_degree_nodelist[degree]:
            h_node_residual[v] = degree
        nodeid += int(num_nodes)

    # iterate over every degree pair (k,l) and add the number of edges given
    # for each pair
    for k in joint_degrees:
        for l in joint_degrees[k]:

            # n_edges_add is the number of edges to add for the
            # degree pair (k,l)
            n_edges_add = joint_degrees[k][l]

            if (n_edges_add > 0) and (k >= l):

                # number of nodes with degree k and l
                k_size = degree_count[k]
                l_size = degree_count[l]

                # k_nodes and l_nodes consist of all nodes of degree k and l
                k_nodes = h_degree_nodelist[k]
                l_nodes = h_degree_nodelist[l]

                # k_unsat and l_unsat consist of nodes of degree k and l that
                # are unsaturated i.e. nodes that have at least 1 available stub
                k_unsat = set(v for v in k_nodes if h_node_residual[v] > 0)

                if k != l:
                    l_unsat = set(w for w in l_nodes if h_node_residual[w] > 0)
                else:
                    l_unsat = k_unsat
                    n_edges_add = joint_degrees[k][l] // 2

                while n_edges_add > 0:

                    # randomly pick nodes v and w that have degrees k and l
                    v = k_nodes[seed.randrange(k_size)]
                    w = l_nodes[seed.randrange(l_size)]

                    # if nodes v and w are disconnected then attempt to connect
                    if not G.has_edge(v, w) and (v != w):

                        # if node v has no free stubs then do neighbor switch
                        if h_node_residual[v] == 0:
                            _neighbor_switch(G, v, k_unsat, h_node_residual)

                        # if node w has no free stubs then do neighbor switch
                        if h_node_residual[w] == 0:
                            if k != l:
                                _neighbor_switch(G, w, l_unsat,
                                                 h_node_residual)
                            else:
                                _neighbor_switch(G,
                                                 w,
                                                 l_unsat,
                                                 h_node_residual,
                                                 avoid_node_id=v)

                        # add edge (v, w) and update data structures
                        G.add_edge(v, w)
                        h_node_residual[v] -= 1
                        h_node_residual[w] -= 1
                        n_edges_add -= 1

                        if h_node_residual[v] == 0:
                            k_unsat.discard(v)
                        if h_node_residual[w] == 0:
                            l_unsat.discard(w)
    return G
 def test_very_large_empty_graph(self):
     G = nx.empty_graph(258049)
     result = BytesIO()
     nx.write_sparse6(G, result)
     self.assertEqual(result.getvalue(), '>>sparse6<<:~~???~?@\n')
Example #56
0
    def obtain_graph(args,suffix=""):
        """Build a Graph according to command line arguments

        Arguments:
        - `args`: command line options
        """
        if getattr(args,'gnd'+suffix) is not None:

            n,d = getattr(args,'gnd'+suffix)
            if (n*d)%2 == 1:
                raise ValueError("n * d must be even")
            G=networkx.random_regular_graph(d,n)

        elif getattr(args,'gnp'+suffix) is not None:

            n,p = getattr(args,'gnp'+suffix)
            G=networkx.gnp_random_graph(n,p)

        elif getattr(args,'gnm'+suffix) is not None:

            n,m = getattr(args,'gnm'+suffix)
            G=networkx.gnm_random_graph(n,m)

        elif getattr(args,'grid'+suffix) is not None:

            G=networkx.grid_graph(getattr(args,'grid'+suffix))

        elif getattr(args,'torus'+suffix) is not None:
            
            G=networkx.grid_graph(getattr(args,'torus'+suffix),periodic=True)

        elif getattr(args,'complete'+suffix) is not None:

            G=networkx.complete_graph(getattr(args,'complete'+suffix))

        elif getattr(args,'empty'+suffix) is not None:

            G=networkx.empty_graph(getattr(args,'empty'+suffix))

        elif getattr(args,'graphformat'+suffix) is not None:

            try:
                print("INFO: reading simple graph {} from '{}'".format(suffix,getattr(args,"input"+suffix).name),
                      file=sys.stderr)
                G=readGraph(getattr(args,'input'+suffix),
                            "simple",
                            getattr(args,'graphformat'+suffix))
            except ValueError as e:
                print("ERROR ON '{}'. {}".format(
                    getattr(args,'input'+suffix).name,e),
                      file=sys.stderr)
                exit(-1)
        else:
            raise RuntimeError("Command line does not specify a graph")

        # Graph modifications
        if getattr(args,'plantclique'+suffix)>1:
            cliquesize = getattr(args,'plantclique'+suffix)
            if cliquesize > G.order() :
                raise ValueError("Clique cannot be larger than graph")

            clique=random.sample(G.nodes(),cliquesize)

            for v,w in combinations(clique,2):
                G.add_edge(v,w)

        if getattr(args,'addedges'+suffix)>0:
            k = getattr(args,'addedges'+suffix)
            G.add_edges_from(sample_missing_edges(G,k))
            if hasattr(G, 'name'):
                G.name = "{} with {} new random edges".format(G.name,k)

        # Output the graph is requested
        if getattr(args,'savegraph'+suffix) is not None:
            writeGraph(G,
                       getattr(args,'savegraph'+suffix),
                       'simple',
                       getattr(args,'graphformat'+suffix))

        return G
Example #57
0
 def test_complete_1_partite_graph(self):
     """Tests that the complete 1-partite graph is the empty graph."""
     G = nx.complete_multipartite_graph(3)
     H = nx.empty_graph(3)
     assert_nodes_equal(G, H)
     assert_edges_equal(sorted(G.edges()), sorted(H.edges()))
Example #58
0
# # number of graph nodes
numOfNodes = 9877

# list the files in the simulated graphs directory
files  = os.listdir('simNets/')
adjLists = []

# read the grpahs adjacency lists
for file in files:
    adjLists = adjLists + [np.genfromtxt('simNets/'+file, delimiter=",")]



# build the graph
diffGraph = nx.empty_graph(numOfNodes)
counter = 1
numOfFiles = 1/100
diffGraph = nx.empty_graph(numOfNodes)
for adjList in adjLists:
    numOfele = np.shape(adjList)[0]
    for i in range(0, numOfele):
        rowIndex = int(adjList[i,0]) - 1
        colIndex = int(adjList[i,1]) - 1
        if diffGraph.has_edge(rowIndex,colIndex):
            diffGraph[rowIndex][colIndex]['weight'] = diffGraph[rowIndex][colIndex]['weight'] + numOfFiles
        else:
            diffGraph.add_edge(rowIndex,colIndex,weight=numOfFiles)
    print("file "+str(counter)+" completed")
    counter = counter + 1
Example #59
0
import networkx as nx
import matplotlib.pyplot as plt

G = nx.complete_graph(10)
e = np.array(G.edges)
print(G.edges, len(e))
X, y = [], []
count = 0
for i in range(10000):
    sample = np.random.normal(22, 10)
    if sample < 0: sample = 2
    elif sample > 45: sample = 42
    idx = np.random.permutation(len(e))[:int(sample)]
    #print(idx)
    edg = e[idx]
    G = nx.empty_graph(10)
    G.add_edges_from(edg)
    mat = np.zeros((10, 10), dtype=int)
    for i in edg:
        mat[tuple(i)] = True
        mat[tuple(i[::-1])] = True
    X.append(mat.reshape(1, -1)[0])

    label = len(nx.maximal_independent_set(G))
    y.append(int(label))
    count += label
    print(i, label)

y = np.asarray(y)
X = np.asarray(X)
import pickle
Example #60
0
 def test_symmetric_min_unsat(self):
     G = nx.empty_graph(4)
     G.add_edge(0, 1)
     T = nx.empty_graph(4)
     F = SubgraphFormula(G, [T])
     self.assertUNSAT(F)