コード例 #1
0
def _community(G, u, community):
    """Get the community of the given node."""
    node_u = G.nodes[u]
    try:
        return node_u[community]
    except KeyError as e:
        raise nx.NetworkXAlgorithmError("No community information") from e
コード例 #2
0
ファイル: link_prediction.py プロジェクト: sr-murthy/networkx
        def predict(u, v):
            if u == v:
                raise nx.NetworkXAlgorithmError("Self links are not supported")
            path_len = spl[u].get(v, inf)

            return alpha * sum(1 for _ in nx.common_neighbors(G, u, v)) + (
                1 - alpha) * (G.number_of_nodes() / path_len)
コード例 #3
0
def bipartite_double_edge_swap(B, genes, samples, nswap=1, max_tries=1e75):
    """A modified version of bipartite_double_edge_swap function from multi Dendrix,
    which is a modified version of double_edge_swap in NetworkX to preserve the bipartite structure of the graph.

    :param B: nx.Graph B(G, S) a bipartite graph
    :param genes: list of genes G
    :param samples: list of samples S
    :param nswap: int, number of double edge swap to perform
    :param max_tries:int, maximum number of attests to swap edges
    :return: nx.Graph, permuted graph
    """
    if nswap > max_tries:
        raise nx.NetworkXError("Number of swaps > number of tries allowed.")
    if len(B) < 4:
        raise nx.NetworkXError("Graph has less than four nodes.")

    # Instead of choosing uniformly at random from a generated edge list,
    # this algorithm chooses nonuniformly from the set of nodes with
    # probability weighted by degree.

    n = 0
    swapcount = 0

    gkeys, gdegrees = zip(*B.degree(genes).items())  # keys, degree for genes
    gcdf = nx.utils.cumulative_distribution(
        gdegrees)  # cdf of degree for genes

    pkeys, pdegrees = zip(
        *B.degree(samples).items())  # keys, degree for samples
    pcdf = nx.utils.cumulative_distribution(
        pdegrees)  # cdf of degree for samples

    while swapcount < nswap:
        # pick two random edges without creating edge list
        # choose source node indices from discrete distribution
        gi = nx.utils.discrete_sequence(1, cdistribution=gcdf)
        pi = nx.utils.discrete_sequence(1, cdistribution=pcdf)

        gene1 = gkeys[gi[0]]  # convert index to label
        sample1 = pkeys[pi[0]]

        sample2 = random.choice(list(B[gene1]))
        gene2 = random.choice(list(B[sample1]))

        # don't create parallel edges
        if (gene1 not in B[sample1]) and (gene2 not in B[sample2]):
            B.add_edge(gene1, sample1)
            B.add_edge(gene2, sample2)

            B.remove_edge(gene1, sample2)
            B.remove_edge(gene2, sample1)
            swapcount += 1
        if n >= max_tries:
            e = ('Maximum number of swap attempts (%s) exceeded ' % n +
                 'before desired swaps achieved (%s).' % nswap)
            raise nx.NetworkXAlgorithmError(e)
        n += 1
        if n % 10000 == 0:
            logging.debug("%d swaps..\n" % n)
    return B
コード例 #4
0
    def directed_double_edge_swap(self, G, nswap=1, max_tries=100, seed=None):
        # u--v          u--y       instead of:      u--v            u   v
        #       becomes                                    becomes  |   |
        # x--y          x--v                        x--y            x   y

        np.random.seed(0)

        if nswap > max_tries:
            raise nx.NetworkXError(
                "Number of swaps > number of tries allowed.")
        if len(G) < 4:
            raise nx.NetworkXError("Graph has less than four nodes.")
        # Instead of choosing uniformly at random from a generated edge list,
        # this algorithm chooses nonuniformly from the set of nodes with
        # probability weighted by degree.
        n = 0
        swapcount = 0
        keys, degrees = zip(*G.out_degree())  # keys, degree
        cdf = nx.utils.cumulative_distribution(degrees)  # cdf of degree
        discrete_sequence = nx.utils.discrete_sequence
        while (swapcount < nswap):
            #        if random.random() < 0.5: continue # trick to avoid periodicities?
            # pick two random edges without creating edge list
            # choose source node indices from discrete distribution
            (ui, xi) = discrete_sequence(2, cdistribution=cdf)
            if (ui == xi):
                continue  # same source, skip
            u = keys[ui]  # convert index to label
            x = keys[xi]

            # ignore nodes with no downstream partners
            if ((len(G[u]) == 0) | (len(G[x]) == 0)):
                continue

            # choose target uniformly from neighbors
            v = np.random.choice(list(G[u]))
            y = np.random.choice(list(G[x]))
            if (v == y):
                continue  # same target, skip
            if (y not in G[u]) and (
                    v not in G[x]):  # don't create parallel edges
                G.add_edge(u,
                           y,
                           weight=G[u][v]['weight'],
                           edge_type=G[u][v]['edge_type'])
                G.add_edge(x,
                           v,
                           weight=G[x][y]['weight'],
                           edge_type=G[x][y]['edge_type'])
                G.remove_edge(u, v)
                G.remove_edge(x, y)
                swapcount += 1
            if (n >= max_tries):
                e = (f"Maximum number of swap attempts ({n}) exceeded "
                     f"before desired swaps achieved ({nswap}).")
                raise nx.NetworkXAlgorithmError(e)
            n += 1
        return G
def double_edge_swap_outedges(G, mod_nodes, indegree_list, outdegree_list,
                              nswap, max_tries):
    """Randomizes between-modul edges of the graph. This function is similiar 
    to the generic double-edge-swap technique with an additonal constraint: 
    Swaps that create within-module edges are not allowed."""

    if len(G) < 4: raise nx.NetworkXError("Graph has less than four nodes.")
    n = 0
    swapcount = 0

    # Modified by urkang, 191117
    temp_dict = dict(G.degree())  # for nodes, degree
    keys = list(temp_dict.keys())
    degrees = list(temp_dict.values())

    cdf = nx.utils.cumulative_distribution(degrees)  # cdf of degree
    while swapcount < nswap:
        (ui, xi) = nx.utils.discrete_sequence(2, cdistribution=cdf)
        if ui == xi:
            continue  # same source, skip
        u = keys[ui]  # convert index to label
        x = keys[xi]
        u_mod = [module for module in mod_nodes if u in mod_nodes[module]]
        u_mod = u_mod[0]

        if x in mod_nodes[u_mod]:
            continue  # same module, skip

        # choose target uniformly from neighbors
        v = rnd.choice(list(G[u]))
        y = rnd.choice(list(G[x]))

        v_mod = [module for module in mod_nodes if v in mod_nodes[module]]
        v_mod = v_mod[0]

        if v == y or y in mod_nodes[v_mod]:
            continue  # same target or same module, skip
        if (x not in G[u]) and (y not in G[v]):  # don't create parallel edges
            if (indegree_list[u] + indegree_list[x] !=
                    0) and (indegree_list[v] + indegree_list[y] != 0):

                G.add_edge(u, x)
                G.add_edge(v, y)
                G.remove_edge(u, v)
                G.remove_edge(x, y)
                swapcount += 1
        if n >= max_tries:
            e = ('Maximum number of swap attempts (%s) exceeded ' % n +
                 'before desired swaps achieved (%s).' % nswap)
            raise nx.NetworkXAlgorithmError(e)
        n += 1
    return G
コード例 #6
0
def bipartite_double_edge_swap(G, genes, patients, nswap=1, max_tries=1e75):
	"""A modified version of the double_edge_swap function in NetworkX to preserve the bipartite structure of the graph.

	For more details on this function, please see the `original NetworkX function <http://goo.gl/wWxBD>`_ that I shamelessly used to make this one.
	The only major change here is that I ensure that u,v and x,y are of the same type (i.e. genes or patients).
	"""
	if nswap>max_tries:
		raise nx.NetworkXError("Number of swaps > number of tries allowed.")
	if len(G) < 4:
		raise nx.NetworkXError("Graph has less than four nodes.")
	# Instead of choosing uniformly at random from a generated edge list,
	# this algorithm chooses nonuniformly from the set of nodes with
	# probability weighted by degree.
	n=0
	swapcount=0
	keys,degrees=zip(*G.degree().items()) # keys, degree
	cdf=nx.utils.cumulative_distribution(degrees)  # cdf of degree


	while swapcount < nswap:
		# pick two random edges without creating edge list
		# choose source node indices from discrete distribution
		(ui,xi)=nx.utils.discrete_sequence(2,cdistribution=cdf)
		if ui==xi:
			continue # same source, skip
		u=keys[ui] # convert index to label
		x=keys[xi]
		if (u in genes and x in genes) or (u in patients and x in patients):
			continue # both are genes, skip

		patient1 = u if u in patients else x
		gene1    = x if x in genes else u

		# choose target uniformly from neighbors
		patient2=random.choice( list(G[gene1]) )
		gene2=random.choice( list(G[patient1]) )

		# don't create parallel edges
		if (gene1 not in G[patient1]) and (gene2 not in G[patient2]):
			G.add_edge(gene1,patient1)
			G.add_edge(gene2,patient2)

			G.remove_edge(gene1,patient2)
			G.remove_edge(patient1, gene2)
			swapcount+=1

		if n >= max_tries:
			e=('Maximum number of swap attempts (%s) exceeded '%n +
			   'before desired swaps achieved (%s).'%nswap)
			raise nx.NetworkXAlgorithmError(e)
		n+=1
	return G
コード例 #7
0
def sign_network_positive_swap(G0, nswap=1, max_tries=100):
    # Instead of choosing uniformly at random from a generated edge list,
    # this algorithm chooses nonuniformly from the set of nodes with
    # probability weighted by degree.
    G = copy.deepcopy(G0)
    n = 0
    swapcount = 0
    keys, degrees = zip(*G.degree().items())  # keys, degree
    cdf = nx.utils.cumulative_distribution(degrees)  # cdf of degree

    while swapcount < nswap:
        #        if random.random() < 0.5: continue # trick to avoid periodicities?
        # pick two random edges without creating edge list
        # choose source node indices from discrete distribution
        (ui, xi) = nx.utils.discrete_sequence(2, cdistribution=cdf)
        if ui == xi:
            continue  # same source, skip
        u = keys[ui]  # convert index to label
        x = keys[xi]
        # choose target uniformly from neighbors
        if len(list(G[u])) > 0 and len(list(G[x])) > 0:
            v = random.choice(list(G[u]))
            y = random.choice(list(G[x]))
            if v == y:
                continue
        else:
            continue

        if (x not in G[u]) and (y not in G[v]) and G[u][v]['weight'] == 1 and G[x][y]['weight'] == 1:

            if ((u in G[x]) and (G[x][u]['weight'] == 2)) or ((v in G[y]) and (G[y][v]['weight'] == 2)):
                continue
            else:
                G.add_edge(u, x, weight=1)
                G.add_edge(v, y, weight=1)
                G.remove_edge(u, v)
                G.remove_edge(x, y)
                swapcount += 1
        if n >= max_tries:
            e = ('Maximum number of swap attempts (%s) exceeded ' %
                 n + 'before desired swaps achieved (%s).' % nswap)
            print nx.NetworkXAlgorithmError(e)
            break
        n += 1
        if n % 100000 == 0:
            print 'swap times=', swapcount, 'try times=', n
    return G
コード例 #8
0
def sign_network_positive_swap(G0, nswap=1, max_tries=100):

    G = copy.deepcopy(G0)
    n = 0
    swapcount = 0
    keys, degrees = zip(*G.degree().items())           # keys, degree
    cdf = nx.utils.cumulative_distribution(degrees)   # cdf of degree

    while swapcount < nswap:
        (ui, xi) = nx.utils.discrete_sequence(2, cdistribution=cdf)
        if ui == xi:
            continue  # same source, skip
        u = keys[ui]  # convert index to label
        x = keys[xi]
        # choose target uniformly from neighbors
        if len(list(G[u])) > 0 and len(list(G[x])) > 0:
            v = random.choice(list(G[u]))
            y = random.choice(list(G[x]))
            if v == y:
                continue
        else:
            continue

        if (x not in G[u]) and (y not in G[v]) and G[u][v]['weight'] == 1 and G[x][y]['weight'] == 1:
                        if connected == 1:  # 判断是否需要保持联通特性,为1的话则需要保持该特性
                    if not nx.is_connected(G):              #保证网络是全联通的:若网络不是全联通网络,则撤回交换边的操作
                    	G.add_edge(u,v)
                    	G.add_edge(x,y)
                    	G.remove_edge(u,y)
                    	G.remove_edge(x,v)
                    	continue 
                swapcount=swapcount+1    
            G.add_edge(u,x,weight=1)
            G.add_edge(v,y,weight=1)
            G.remove_edge(u,v)
            G.remove_edge(x,y)
            swapcount+=1
            
        if n >= max_tries:
            e=('Maximum number of swap attempts (%s) exceeded '%n + 'before desired swaps achieved (%s).'%nswap)
            print nx.NetworkXAlgorithmError(e)
            break
        n+=1
        if n%1000000==0:
            print 'swap times=',swapcount,'try times=',n
コード例 #9
0
def within_inter_cluster(G, ebunch=None, delta=0.001, community="community"):
    """Compute the ratio of within- and inter-cluster common neighbors
    of all node pairs in ebunch.

    For two nodes `u` and `v`, if a common neighbor `w` belongs to the
    same community as them, `w` is considered as within-cluster common
    neighbor of `u` and `v`. Otherwise, it is considered as
    inter-cluster common neighbor of `u` and `v`. The ratio between the
    size of the set of within- and inter-cluster common neighbors is
    defined as the WIC measure. [1]_

    Parameters
    ----------
    G : graph
        A NetworkX undirected graph.

    ebunch : iterable of node pairs, optional (default = None)
        The WIC measure will be computed for each pair of nodes given in
        the iterable. The pairs must be given as 2-tuples (u, v) where
        u and v are nodes in the graph. If ebunch is None then all
        non-existent edges in the graph will be used.
        Default value: None.

    delta : float, optional (default = 0.001)
        Value to prevent division by zero in case there is no
        inter-cluster common neighbor between two nodes. See [1]_ for
        details. Default value: 0.001.

    community : string, optional (default = 'community')
        Nodes attribute name containing the community information.
        G[u][community] identifies which community u belongs to. Each
        node belongs to at most one community. Default value: 'community'.

    Returns
    -------
    piter : iterator
        An iterator of 3-tuples in the form (u, v, p) where (u, v) is a
        pair of nodes and p is their WIC measure.

    Examples
    --------
    >>> G = nx.Graph()
    >>> G.add_edges_from([(0, 1), (0, 2), (0, 3), (1, 4), (2, 4), (3, 4)])
    >>> G.nodes[0]['community'] = 0
    >>> G.nodes[1]['community'] = 1
    >>> G.nodes[2]['community'] = 0
    >>> G.nodes[3]['community'] = 0
    >>> G.nodes[4]['community'] = 0
    >>> preds = nx.within_inter_cluster(G, [(0, 4)])
    >>> for u, v, p in preds:
    ...     print(f'({u}, {v}) -> {p:.8f}')
    (0, 4) -> 1.99800200
    >>> preds = nx.within_inter_cluster(G, [(0, 4)], delta=0.5)
    >>> for u, v, p in preds:
    ...     print(f'({u}, {v}) -> {p:.8f}')
    (0, 4) -> 1.33333333

    References
    ----------
    .. [1] Jorge Carlos Valverde-Rebaza and Alneu de Andrade Lopes.
       Link prediction in complex networks based on cluster information.
       In Proceedings of the 21st Brazilian conference on Advances in
       Artificial Intelligence (SBIA'12)
       https://doi.org/10.1007/978-3-642-34459-6_10
    """
    if delta <= 0:
        raise nx.NetworkXAlgorithmError("Delta must be greater than zero")

    def predict(u, v):
        Cu = _community(G, u, community)
        Cv = _community(G, v, community)
        if Cu != Cv:
            return 0
        cnbors = set(nx.common_neighbors(G, u, v))
        within = {w for w in cnbors if _community(G, w, community) == Cu}
        inter = cnbors - within
        return len(within) / (len(inter) + delta)

    return _apply_prediction(G, predict, ebunch)
コード例 #10
0
def double_edge_swap(G, nswap=1, max_tries=100):
    """Swap two edges in the graph while keeping the node degrees fixed.

    A double-edge swap removes two randomly chosen edges u-v and x-y
    and creates the new edges u-x and v-y::

     u--v            u  v
            becomes  |  |
     x--y            x  y

    If either the edge u-x or v-y already exist no swap is performed 
    and another attempt is made to find a suitable edge pair.
    
    Parameters
    ----------
    G : graph
       A NetworkX (undirected) Graph.

    nswap : integer (optional)
       Number of double-edge swaps to perform 

    max_tries : integer (optional)
       Maximum number of attempts to swap nswap edges.

    Returns
    -------
    G : graph
       The graph after nswap double edge swaps.

    Notes
    -----
    Does not enforce any connectivity constraints.

    The graph G is modified in place.
    """
    if G.is_directed():
        raise nx.NetworkXError(\
            "double_edge_swap() not defined for directed graphs.")
    # Instead of choosing uniformly at random from a generated edge list,
    # this algorithm chooses nonuniformly from the set of nodes with
    # probability weighted by degree.
    n = 0
    swapcount = 0
    keys, degrees = zip(*G.degree().items())  # keys, degree
    cdf = nx.utils.cumulative_distribution(degrees)  # cdf of degree
    if len(cdf) < 4:
        raise nx.NetworkXError("Graph has less than four nodes.")
    while swapcount < nswap:
        #        if random.random() < 0.5: continue # trick to avoid periodicities?
        # pick two randon edges without creating edge list
        # choose source node indices from discrete distribution
        (ui, xi) = nx.utils.discrete_sequence(2, cdistribution=cdf)
        if ui == xi:
            continue  # same source, skip
        u = keys[ui]  # convert index to label
        x = keys[xi]
        # choose target uniformly from neighbors
        v = random.choice(list(G[u]))
        y = random.choice(list(G[x]))
        if v == y:
            continue  # same target, skip
        if (x not in G[u]) and (y not in G[v]):  # don't create parallel edges
            G.add_edge(u, x)
            G.add_edge(v, y)
            G.remove_edge(u, v)
            G.remove_edge(x, y)
            swapcount += 1
        if n > max_tries:
            e = ('Maximum number of swap attempts (%s) exceeded ' % n +
                 'before desired swaps achieved (%s).' % nswap)
            raise nx.NetworkXAlgorithmError(e)
        n += 1
    return G
コード例 #11
0
def equitable_color(G, num_colors):
    """Provides equitable (r + 1)-coloring for nodes of G in O(r * n^2) time
     if deg(G) <= r. The algorithm is described in [1]_.

     Attempts to color a graph using r colors, where no neighbors of a node
     can have same color as the node itself and the number of nodes with each
     color differ by at most 1.

     Parameters
     ----------
     G : networkX graph
        The nodes of this graph will be colored.

     num_colors : number of colors to use
        This number must be at least one more than the maximum degree of nodes
        in the graph.

     Returns
     -------
     A dictionary with keys representing nodes and values representing
     corresponding coloring.

     Examples
     --------
     >>> G = nx.cycle_graph(4)
     >>> d = nx.coloring.equitable_color(G, num_colors=3)
     >>> nx.algorithms.coloring.equitable_coloring.is_equitable(G, d)
     True

     Raises
     ------
     NetworkXAlgorithmError
         If the maximum degree of the graph ``G`` is greater than
         ``num_colors``.

     References
     ----------
     .. [1] Kierstead, H. A., Kostochka, A. V., Mydlarz, M., & Szemerédi, E.
         (2010). A fast algorithm for equitable coloring. Combinatorica, 30(2),
         217-224.
    """

    # Map nodes to integers for simplicity later.
    nodes_to_int = {}
    int_to_nodes = {}

    for idx, node in enumerate(G.nodes):
        nodes_to_int[node] = idx
        int_to_nodes[idx] = node

    G = nx.relabel_nodes(G, nodes_to_int, copy=True)

    # Basic graph statistics and sanity check.
    if len(G.nodes) > 0:
        r_ = max([G.degree(node) for node in G.nodes])
    else:
        r_ = 0

    if r_ >= num_colors:
        raise nx.NetworkXAlgorithmError(
            f"Graph has maximum degree {r_}, needs "
            f"{r_ + 1} (> {num_colors}) colors for guaranteed coloring.")

    # Ensure that the number of nodes in G is a multiple of (r + 1)
    pad_graph(G, num_colors)

    # Starting the algorithm.
    # L = {node: list(G.neighbors(node)) for node in G.nodes}
    L_ = {node: [] for node in G.nodes}

    # Arbitrary equitable allocation of colors to nodes.
    F = {node: idx % num_colors for idx, node in enumerate(G.nodes)}

    C = make_C_from_F(F)

    # The neighborhood is empty initially.
    N = make_N_from_L_C(L_, C)

    # Currently all nodes witness all edges.
    H = make_H_from_C_N(C, N)

    # Start of algorithm.
    edges_seen = set()

    for u in sorted(G.nodes):
        for v in sorted(G.neighbors(u)):

            # Do not double count edges if (v, u) has already been seen.
            if (v, u) in edges_seen:
                continue

            edges_seen.add((u, v))

            L_[u].append(v)
            L_[v].append(u)

            N[(u, F[v])] += 1
            N[(v, F[u])] += 1

            if F[u] != F[v]:
                # Were 'u' and 'v' witnesses for F[u] -> F[v] or F[v] -> F[u]?
                if N[(u, F[v])] == 1:
                    H[F[u],
                      F[v]] -= 1  # u cannot witness an edge between F[u], F[v]

                if N[(v, F[u])] == 1:
                    H[F[v],
                      F[u]] -= 1  # v cannot witness an edge between F[v], F[u]

        if N[(u, F[u])] != 0:
            # Find the first color where 'u' does not have any neighbors.
            Y = [k for k in C.keys() if N[(u, k)] == 0][0]
            X = F[u]
            change_color(u, X, Y, N=N, H=H, F=F, C=C, L=L_)

            # Procedure P
            procedure_P(V_minus=X, V_plus=Y, N=N, H=H, F=F, C=C, L=L_)

    return {int_to_nodes[x]: F[x] for x in int_to_nodes}
コード例 #12
0
ファイル: triads.py プロジェクト: zahra-mor/networkx
def triad_type(G):
    """Returns the sociological triad type for a triad.

    Parameters
    ----------
    G : digraph
       A NetworkX DiGraph with 3 nodes

    Returns
    -------
    triad_type : str
       A string identifying the triad type

    Notes
    -----
    There can be 6 unique edges in a triad (order-3 DiGraph) (so 2^^6=64 unique
    triads given 3 nodes). These 64 triads each display exactly 1 of 16
    topologies of triads (topologies can be permuted). These topologies are
    identified by the following notation:

    {m}{a}{n}{type} (for example: 111D, 210, 102)

    Here:

    {m}     = number of mutual ties (takes 0, 1, 2, 3); a mutual tie is (0,1)
              AND (1,0)
    {a}     = number of assymmetric ties (takes 0, 1, 2, 3); an assymmetric tie
              is (0,1) BUT NOT (1,0) or vice versa
    {n}     = number of null ties (takes 0, 1, 2, 3); a null tie is NEITHER
              (0,1) NOR (1,0)
    {type}  = a letter (takes U, D, C, T) corresponding to up, down, cyclical
              and transitive. This is only used for topologies that can have
              more than one form (eg: 021D and 021U).

    References
    ----------
    .. [1] Snijders, T. (2012). "Transitivity and triads." University of
        Oxford.
        http://www.stats.ox.ac.uk/snijders/Trans_Triads_ha.pdf
    """
    if not is_triad(G):
        raise nx.NetworkXAlgorithmError("G is not a triad (order-3 DiGraph)")
    num_edges = len(G.edges())
    if num_edges == 0:
        return "003"
    elif num_edges == 1:
        return "012"
    elif num_edges == 2:
        e1, e2 = G.edges()
        if set(e1) == set(e2):
            return "102"
        elif e1[0] == e2[0]:
            return "021D"
        elif e1[1] == e2[1]:
            return "021U"
        elif e1[1] == e2[0] or e2[1] == e1[0]:
            return "021C"
    elif num_edges == 3:
        for (e1, e2, e3) in permutations(G.edges(), 3):
            if set(e1) == set(e2):
                if e3[0] in e1:
                    return "111U"
                # e3[1] in e1:
                return "111D"
            elif set(e1).symmetric_difference(set(e2)) == set(e3):
                if {e1[0], e2[0], e3[0]} == {e1[0], e2[0], e3[0]} == set(G.nodes()):
                    return "030C"
                # e3 == (e1[0], e2[1]) and e2 == (e1[1], e3[1]):
                return "030T"
    elif num_edges == 4:
        for (e1, e2, e3, e4) in permutations(G.edges(), 4):
            if set(e1) == set(e2):
                # identify pair of symmetric edges (which necessarily exists)
                if set(e3) == set(e4):
                    return "201"
                if {e3[0]} == {e4[0]} == set(e3).intersection(set(e4)):
                    return "120D"
                if {e3[1]} == {e4[1]} == set(e3).intersection(set(e4)):
                    return "120U"
                if e3[1] == e4[0]:
                    return "120C"
    elif num_edges == 5:
        return "210"
    elif num_edges == 6:
        return "300"
コード例 #13
0
def rewire_graph(graph, error):
    """
    Returns a rewired copy of the original graph.
    The rewiring procedure preserves degree of each node.
    The number of rewirings is the square of the node amount.
    This ensures the network is completely randomized.
    The weight of the edges also needs to be normalized.
    Therefore, after the network is randomized, weight is sampled
    from the original graph and added to the randomized graph.
    Because this does not take negative / positive hubs into account,
    the fraction of positive / negative weights per node
    is not preserved.

    Part of the rewire_graph function has been adapted from the original
    NetworkX double_edge_swap function. The adapted version also swaps edge weights.

    License
    =======
    NetworkX is distributed with the 3-clause BSD license.
    ::
       Copyright (C) 2004-2018, NetworkX Developers
       Aric Hagberg <*****@*****.**>
       Dan Schult <*****@*****.**>
       Pieter Swart <*****@*****.**>
       All rights reserved.
       Redistribution and use in source and binary forms, with or without
       modification, are permitted provided that the following conditions are
       met:
         * Redistributions of source code must retain the above copyright
           notice, this list of conditions and the following disclaimer.
         * Redistributions in binary form must reproduce the above
           copyright notice, this list of conditions and the following
           disclaimer in the documentation and/or other materials provided
           with the distribution.
         * Neither the name of the NetworkX Developers nor the names of its
           contributors may be used to endorse or promote products derived
           from this software without specific prior written permission.
       THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
       "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
       LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
       A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
       OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
       LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
       DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
       THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

    Parameters
    ----------
    :param graph: Original graph to rewire.
    :param error: Fraction of edges to rewire.
    :return: Rewired NetworkX graph
    """
    model = graph.copy(as_view=False).to_undirected(as_view=False)
    swaps = round(len(model.nodes) * error)
    swapfail = False
    max_tries = len(model.nodes) * 10
    try:
        n = 0
        swapcount = 0
        keys, degrees = zip(*model.degree())  # keys, degree
        cdf = nx.utils.cumulative_distribution(degrees)  # cdf of degree
        discrete_sequence = nx.utils.discrete_sequence
        while swapcount < swaps:
            #        if random.random() < 0.5: continue # trick to avoid periodicities?
            # pick two random edges without creating edge list
            # choose source node indices from discrete distribution
            (ui, xi) = discrete_sequence(2, cdistribution=cdf)
            if ui == xi:
                continue  # same source, skip
            u = keys[ui]  # convert index to label
            x = keys[xi]
            # choose target uniformly from neighbors
            v = choice(list(model[u]))
            y = choice(list(model[x]))
            if v == y:
                continue  # same target, skip
            if (x not in model[u]) and (y not in model[v]):  # don't create parallel edges
                weight_uv = model.edges[u, v]['weight']
                weight_xy = model.edges[x, y]['weight']
                model.add_edge(u, x)
                model.edges[u, x]['weight'] = weight_uv
                model.add_edge(v, y)
                model.edges[v, y]['weight'] = weight_xy
                model.remove_edge(u, v)
                model.remove_edge(x, y)
                swapcount += 1
            if n >= max_tries:
                e = ('Maximum number of swap attempts (%s) exceeded ' % n +
                     'before desired swaps achieved (%s).' % swaps)
                raise nx.NetworkXAlgorithmError(e)
            n += 1
    except nx.exception.NetworkXAlgorithmError:
        logger.error('Cannot permute this network fraction. ' + '\n' +
                     'Please choose a lower error parameter, or avoid calculating a centrality score. ', exc_info=True)
        swapfail = True
    # edge_weights = list()
    # for edge in graph.edges:
    #     edge_weights.append(graph[edge[0]][edge[1]]['weight'])
    # random_weights = dict()
    # for edge in model.edges:
    #     random_weights[edge] = choice(edge_weights)
    # nx.set_edge_attributes(model, random_weights, 'weight')
    return model, swapfail
コード例 #14
0
ファイル: link_prediction.py プロジェクト: sr-murthy/networkx
        def predict(u, v):
            if u == v:
                raise nx.NetworkXAlgorithmError("Self links are not supported")

            return sum(1 for _ in nx.common_neighbors(G, u, v))