【问题标题】:Random contraction algorithm for finding Min Cuts in a graph用于在图中查找 Min Cuts 的随机收缩算法
【发布时间】:2012-04-20 18:20:30
【问题描述】:

好的,这是我在图表中寻找切口的算法(我不是在说最小切口)

假设我们得到一个无向图的邻接表。

  1. 选择图形上的任意顶点(用枢轴表示)
  2. 选择图形上的任何其他顶点(随机)。 (用 x 表示)
  3. 如果两个顶点之间有一条边,则从图中删除该边。并将 x 连接到的所有顶点转储到枢轴上。 (如果没有,则返回第 2 步。
  4. 如果任何其他顶点连接到 x,则更改邻接列表,以便现在 x 被枢轴替换。即它们已连接到 Pivot。
  5. 如果顶点数大于 2(返回步骤 2)
  6. 如果等于 2。只需计算 2 个点的邻接列表中存在的顶点数。这将给削减

我的问题是,这个算法正确吗?

【问题讨论】:

  • 它是否适用于几个演示示例?如果是这样,那么很可能是的。
  • 对不起,转储所有顶点是什么意思?
  • 这不是mathematics StackExchange 网站的问题吗?

标签: algorithm random graph


【解决方案1】:

这是对 Krager 的无向图最小割算法的一个很好的解释。

我认为您可能遗漏了一个细节。或者我只是看错了你的描述。

您想删除所有自循环。

例如,在您删除一个顶点并运行您的算法之后,顶点 A 现在可能有一条从顶点 A 到顶点 A 的边。这称为自循环。并且它们在收缩两个顶点的过程中经常产生。第一步,您可以简单地检查整个图表是否存在自环,尽管还有一些更复杂的方法。

这有意义吗?

【讨论】:

  • 是的,它是 Krager 的 Min-Cut 算法。我认为不会产生任何自循环。但除此之外,一切看起来都不错,对吧?
  • 是的,完全可以,除此之外它看起来很棒。但检查自循环。例如,考虑当您的第 3 步时,当您将所有一个顶点边缘转储到另一个顶点时。它们之前是连接的,因此在该点上应该至少产生一个(如果不是多个)“自循环”。这通常是发生的事情。无论如何,你可能已经涵盖了这个,我只是想我会提到它。干得好!
  • 无论如何,第一次或两次运行代码时检查它们并没有什么坏处。以防万一。
【解决方案2】:

我只会更改您的随机化。

选择第一个顶点后,从他的邻接列表中选择另一个。现在您确定两个顶点之间有边。下一步是从邻接列表中找到顶点。

【讨论】:

    【解决方案3】:

    同意您绝对应该删除自循环。 还有一点我要补充的是,在你随机选择第一个顶点之后,你不必随机选择另一个节点,直到你有一个连接到第一个节点的节点,你可以简单地从连接到的节点中选择第一个顶点,因为您知道第一个选择的节点连接到多少个节点。所以在较小的范围内进行第二次随机选择。这只是有效地随机选择一条边(由两个节点/顶点确定)。我有一些实现 krager 算法的 c# 代码,你可以玩转。它不是最高效的代码(尤其是可以使用更高效的数据结构),因为我在 200 个节点的图表上对其进行了测试,10000 次迭代大约需要 30 秒才能运行。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace MinCut
    {
        internal struct Graph
        {
            public int N { get; private set; }
            public readonly List<int> Connections;
            public Graph(int n) : this()
            {
                N = n;
                Connections = new List<int>();
            }
    
        public override bool Equals(object obj)
        {
            return Equals((Graph)obj);
        }
    
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    
        private bool Equals(Graph g)
        {
            return N == g.N;
        }
    }
    
    internal sealed class GraphContraction
    {
        public static void Run(IList<Graph> graphs, int i)
        {
            var liveGraphs = graphs.Count;
            if (i >= liveGraphs)
            {
                throw new Exception("Wrong random index generation; index cannot be larger than the number of nodes");
            }
            var leftV = graphs[i];
    
            var r = new Random();
            var index = r.Next(0, leftV.Connections.Count);
            var rightV = graphs.Where(x=>x.N == leftV.Connections[index]).Single();
    
            foreach (var v in graphs.Where(x => !x.Equals(leftV) && x.Connections.Contains(leftV.N))) 
            {
                v.Connections.RemoveAll(x => x == leftV.N);
            }
            foreach (var c in leftV.Connections)
            {
                if (c != rightV.N)
                {
                    rightV.Connections.Add(c);
                    int c1 = c;
                    graphs.Where(x=> x.N == c1).First().Connections.Add(rightV.N);
                }
            }
            graphs.Remove(leftV);
        }
    }
    

    }

    【讨论】:

    • 您(或其他读者)能否展示或链接到为什么这种随机化方法“有效”?在没有支持的情况下,这是一个强有力的声明——请分享您为什么对所有图的 Pr(整个图上的任何边)=1/m 有信心,永远。
    • @newcoder,理论上要获得 1/m 的概率,您需要运行 m^2*log(m) 次迭代。它涉及到相当多的数学来证明这一点,您可以参考许多在线资源以获得详细的证明,例如en.wikipedia.org/wiki/Karger's_algorithm
    • 也许我不清楚;我之前的评论提到选择任何给定边进行收缩的概率为 1/m,其中 m 是剩余边数。该算法依赖于这个概率对于所有边缘都是一致的。以您和@stupi 建议的方式选择边缘实际上并不符合此要求。
    • 为了说明,考虑下图:[(0):1,2,2,3] [(1):0] [(2):0,0] [(3): 0] 对于该图, m=4 ,因此任何声称选择均匀随机边的方法都应计算为 Pr(0,1)=1/4 、 Pr(0,2)=1/4 和 Pr(0, 3)=1/4 首先均匀地随机选择一个顶点,然后从它的邻接列表中均匀地随机地选择一个顶点,我们有 Pr(0,1)=5/16 , Pr(0,2)=6/16 , 和 Pr(0,3)=5/16 。
    • 我不确定您是如何计算出 P(0,1) = 5/16、P(0,2) = 6/16 和 P(0,3) = 5/16 的。这是我的计算: P(0,1) 实际上是在已经选择顶点 0 的情况下随机选择顶点 1 的条件概率,即 P(1|0) = P(0 和 1) / P(0) ;因为每个选择都是独立的,因此 P(0 和 1) = P(0) * P(1),所以 P(1|0) = P(1) = 1/4,类似地 P(2|0) = P( 2) = 2/4 = 1/2; P(3|0) = 1/4。
    猜你喜欢
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 2022-01-19
    • 2011-04-11
    • 2021-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多