Algorithm 给定稀疏性的随机单连通图生成

Algorithm 给定稀疏性的随机单连通图生成,algorithm,random,graph,Algorithm,Random,Graph,我试图找到一个有效的算法来生成一个具有给定稀疏性的简单连通图。比如: Input: N - size of generated graph S - sparseness (numer of edges actually; from N-1 to N(N-1)/2) Output: simple connected graph G(v,e) with N vertices and S edges 对于每个节点,至少需要一条边 从一个节点开始。 在每次迭代中,创建一个新节点

我试图找到一个有效的算法来生成一个具有给定稀疏性的简单连通图。比如:

Input:
    N - size of generated graph
    S - sparseness (numer of edges actually; from N-1 to N(N-1)/2)
Output:
    simple connected graph G(v,e) with N vertices and S edges

对于每个节点,至少需要一条边

从一个节点开始。 在每次迭代中,创建一个新节点和一条新边。边用于将新节点与上一个节点集中的随机节点连接

创建所有节点后,创建随机边,直到满足S。确保不要创建双边(为此,可以使用邻接矩阵)

随机图是在O(S)中完成的。

高级概念
  • 生成具有N节点和N-1边的(均匀选择的)随机生成树
  • 在达到请求的边数之前,在任意两个随机节点之间添加一条边
  • 创建生成树 by是一个很好的开始,但由于总是为新边的一端选择一个访问的节点,因此会引入偏差。通过在每次迭代中随机选择访问的节点,在开始时访问的节点有更多的迭代,它们有机会被选择。因此,与稍后拾取的节点相比,较早的节点更可能具有较高的阶数(边数)

    偏见的例子 例如,对于一个4节点连通图,而不是生成一个线性图(75%的可能生成树都是线性的),这种偏差将导致生成的概率大于它应该是的25%

    偏见并不总是坏事。事实证明,这种偏差有利于生成类似于真实世界计算机网络的生成树。然而,为了创建一个真正的随机连通图,初始生成树必须从可能的生成树集中统一选取(参见Wikipedia的文章)

    随机游走法 生成统一生成树的一种方法是通过随机游走。下面是威尔逊描述简单算法的一篇文章的引文

    从任意顶点开始,在图上进行简单的随机游走。每次第一次遇到顶点时,标记发现顶点的边。当发现所有顶点时,标记的边形成一个随机生成树。该算法易于编码,运行时间常数小,并且很好地证明了它生成的树具有正确的概率

    这适用于简单的连通图,但是如果您需要有向图的算法,那么请进一步阅读它描述的Wilson算法。这是另一个关于和Wilson算法的资源

    实施 因为我也对这个问题感兴趣,所以我编写了各种方法的Python实现,包括随机行走方法。请随意查看GitHub上的

    以下是随机游走法代码的摘录:

    #创建两个分区S和T。最初将所有节点存储在S中。
    S、 T=集合(节点),集合()
    #选择一个随机节点,并将其标记为已访问和当前节点。
    当前_节点=random.sample(S,1).pop()
    S.remove(当前_节点)
    T.add(当前_节点)
    图形=图形(节点)
    #创建一个随机连接图。
    而S:
    #从当前节点的邻居中随机选取下一个节点。
    #当我们生成一个连通图时,我们假设一个完整的图。
    邻居节点=random.sample(节点,1).pop()
    #如果尚未访问新节点,请将边从当前添加到新。
    如果邻居节点不在T中:
    边=(当前_节点,邻居_节点)
    图.添加_边(边)
    S.remove(邻居节点)
    T.add(邻居节点)
    #将新节点设置为当前节点。
    当前节点=邻居节点
    #添加随机边,直到达到所需的边数。
    图.添加随机边(数量边)
    
    使用类似的方法生成,然后根据所需的稀疏性从中随机生成指向的附加链接

    根据客户的回答,我提出了以下javascript实现来处理图形:

    函数生成器领域图(cy、numNode、avgdgree、weightMin、weightMax){
    //创建节点
    对于(变量i=0;i0){
    var nexturenodeidx=randomIntBetween(0,S.length);
    var nexturenode=S[nexturenodeidx];
    赛义德({
    组:“边”,
    数据:{
    权重:确定(权重最小值、权重最大值)之间的随机数,
    来源:currNode.id(),
    目标:nextureNode.id()
    }
    });
    S.拼接(相邻节点,1);
    T.push(相邻节点);
    currNode=相邻节点;
    }
    //添加随机边,直到满足avgDegree
    while(nodes.totalDegree()/nodes.length

    要获得完整的示例源代码,请访问:)

    刚刚在Java中制作了类似的代码。此外,最好在创建最小连通图的同时添加随机节点。否则,您将始终获得覆盖最后一个节点的唯一垂直面,覆盖前一个节点的垂直面不超过两个,以此类推。或者,你可以通过邻接操作矩阵得到一个图的同构图。这很好也很简单,但是如果图是稠密的,这不是O(S),因为有双边检查。我的意思是,最坏的情况是(几乎)新能源汽车