Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用用户指定的全局聚类系数高效地生成随机图_Python_Numpy_Random_Graph Theory_Igraph - Fatal编程技术网

Python 使用用户指定的全局聚类系数高效地生成随机图

Python 使用用户指定的全局聚类系数高效地生成随机图,python,numpy,random,graph-theory,igraph,Python,Numpy,Random,Graph Theory,Igraph,我正在研究大规模神经元网络的模拟,为此我需要生成代表网络拓扑的随机图 我希望能够指定这些图的以下属性: 节点数,N(~=1000-10000) 任意两个给定节点之间连接的平均概率,p(~0.01-0.2) 全局聚类系数,C(~0.1-0.5) 理想情况下,随机图应该从满足这些用户指定标准的所有可能图集中统一绘制 目前,我正在使用一种非常粗糙的随机扩散方法,从鄂尔多斯仁义随机网络开始,具有所需的大小和全局连接概率,然后在每一步上,我随机重新连接一些边。如果重新布线使我更接近所需的C,那么我将重

我正在研究大规模神经元网络的模拟,为此我需要生成代表网络拓扑的随机图

我希望能够指定这些图的以下属性:

  • 节点数,N(~=1000-10000)
  • 任意两个给定节点之间连接的平均概率,p(~0.01-0.2)
  • 全局聚类系数,C(~0.1-0.5)
理想情况下,随机图应该从满足这些用户指定标准的所有可能图集中统一绘制

目前,我正在使用一种非常粗糙的随机扩散方法,从鄂尔多斯仁义随机网络开始,具有所需的大小和全局连接概率,然后在每一步上,我随机重新连接一些边。如果重新布线使我更接近所需的C,那么我将重新布线的网络保留到下一个迭代中

下面是我当前的Python实现:

import igraph
import numpy as np

def generate_fixed_gcc(n, p, target_gcc, tol=1E-3):
    """
    Creates an Erdos-Renyi random graph of size n with a specified global
    connection probability p, which is then iteratively rewired in order to
    achieve a user- specified global clustering coefficient.
    """

    # initialize random graph
    G_best = igraph.Graph.Erdos_Renyi(n=n, p=p, directed=True, loops=False)

    loss_best = 1.
    n_edges = G_best.ecount()

    # start with a high rewiring rate
    rewiring_rate = n_edges
    n_iter = 0

    while loss_best > tol:

        # operate on a copy of the current best graph
        G = G_best.copy()

        # adjust the number of connections to rewire according to the current
        # best loss
        n_rewire = min(max(int(rewiring_rate * loss_best), 1), n_edges)
        G.rewire(n=n_rewire)

        # compute the global clustering coefficient
        gcc = G.transitivity_undirected()
        loss = abs(gcc - target_gcc)

        # did we improve?
        if loss < loss_best:

            # keep the new graph
            G_best = G
            loss_best = loss
            gcc_best = gcc

            # increase the rewiring rate
            rewiring_rate *= 1.1

        else:

            # reduce the rewiring rate
            rewiring_rate *= 0.9

        n_iter += 1

    # get adjacency matrix as a boolean numpy array
    M = np.array(G_best.get_adjacency().data, dtype=np.bool)

    return M, n_iter, gcc_best
导入igraph
将numpy作为np导入
def生成固定gcc(n,p,目标gcc,tol=1E-3):
"""
使用指定的全局变量创建大小为n的鄂尔多斯仁义随机图
连接概率p,然后迭代重新布线以
实现用户指定的全局聚类系数。
"""
#初始化随机图
G_best=igraph.Graph.Erdos_Renyi(n=n,p=p,directed=True,loops=False)
损失最好=1。
n_edges=G_best.ecoount()
#从高重新布线率开始
重新布线率=n条边
n_iter=0
当损失>tol时:
#操作当前最佳图形的副本
G=G_最佳。复制()
#根据电流调整要重新布线的连接数
#最佳损失
n_重新布线=最小值(最大值(int(重新布线率*损耗最佳值),1),n_边)
G.重新布线(n=n_重新布线)
#计算全局聚类系数
gcc=G.及物性_无向()
损失=绝对值(gcc-目标值)
#我们改进了吗?
如果损失
这对于小型网络(N<500)是可行的,但随着节点数量的增加,它很快变得难以处理。生成一个200节点的图大约需要20秒,生成一个1000节点的图需要几天


有人能提出一个有效的方法吗?

你说得对。这是一个非常昂贵的方法来实现你想要的。我只能推测,是否有一种数学上合理的方法来优化并确保其接近均匀分布。我甚至不确定你的方法是否会导致均匀分布,尽管看起来会。让我试试:

基于和,似乎可以在图中进行局部更改,同时了解对全局连接性和全局群集的确切影响

全局聚类系数基于三组节点。三元组由三个节点组成,这些节点通过两个(开放三元组)或三个(封闭三元组)无向连接线连接。三角形由三个闭合的三元组组成,其中一个以每个节点为中心。全局聚类系数是闭合三元组(或3个三角形)的数量超过三元组总数(开放和闭合)


(*编辑*)根据我对ali_m引用的论文的阅读,下面的方法可能会在低阶聚类上花费太多的边,导致图形无法达到所需的聚类系数,除非它非常低(这可能无论如何都不会有用)。因此,如果有人实际使用此功能,您可能希望识别更高级别的簇以添加边,以便在不需要添加大量边的情况下快速提高聚类系数

另一方面,以下方法确实与研究论文中的方法一致,因此或多或少是一种合理的方法


如果我理解正确,您可以执行以下操作:

  • 按照您所做的方式生成图形

  • 计算并跟踪:

    • p_剩余
      跟踪需要在其他位置添加或删除以保持连接的边数
    • cc_top
      cc_btm
      跟踪聚类系数
  • 迭代地(不是完全地)选择随机对,并单调地连接或断开它们 接近所需的聚类系数(cc),同时保持现有的连接性(p)

    伪代码:

    for random_pair in random_pairs:
    
        if (random_pair is connected) and (need to reduce cc or p):  # maybe put priority on the one that has a larger gap?
            delete the edge
            p_surplus -= 1
            cc_top -= broken_connected_triplets  # have to search locally
            cc_btm -= (broken_connected_triplets + broken_open_triplets)  # have to search locally
        elif (random_pair is not connected) add (need to increase c or p):
            add the edge
            p_surplus += 1
            cc_top += new_connected_triplets
            cc_btm += (new_connected_triplets + new_open_triplets)
    
        if cc and p are within desired ranges:
            done
    
        if some condition for detecting infinite loops:
            rethink this method
    
  • 这可能不完全正确,但我认为这种方法会奏效。效率 搜索本地三元组并始终将参数移动到正确的方向会更好
    比复制图表和多次全局测量cc要好得多。

    经过一点阅读,看起来最好的解决方案可能是中介绍的Gleeson算法的广义版本。然而,我仍然不知道如何实现它,所以目前我一直在努力

    与我的天真方法一样,这是一种基于马尔可夫链的方法,使用随机边交换,但与我的方法不同,它专门针对图中的“三重基序”进行重新布线:

    由于这将更倾向于引入三角形,因此它将对聚类系数产生更大的影响。至少在无向图的情况下,重新布线步骤也保证保持度序列。阿盖恩