好的,所以这是我在图表中找到切割的算法(我不是在谈论最小切割)
假设我们获得了非有向图的邻接列表。
我的问题是,这个算法是否正确?
答案 0 :(得分:1)
对于无向图的Krager Min-Cut算法,这是一个很好的解释。
我想你可能错过了一个细节。或许我只是误读了你的描述。
您想删除所有自循环。
例如,在移除顶点并运行算法后,顶点A现在可能具有从顶点A到顶点A的边。这称为自循环。并且它们在收缩两个顶点的过程中经常生成。作为第一步,您可以简单地检查整个图形以进行自循环,尽管有一些更复杂的方法。
这有意义吗?
答案 1 :(得分:1)
我只会改变你的随机化。
选择第一个顶点后,从邻接列表中选择另一个顶点。现在您确定两个顶点之间有边缘。下一步是从附属列表中找到顶点。
答案 2 :(得分:-1)
同意你绝对应该删除自我循环。 另外我要添加的另一点是,在你随机选择第一个顶点之后,你不必随意选择另一个节点,直到你有一个连接到第一个节点,你可以简单地选择连接到第一个节点的节点。第一个顶点,因为你知道有多少个节点是第一个连接的节点。所以在较小范围内进行第二次随机选择。这只是有效地随机选择边缘(由两个节点/顶点确定)。我有一些c#代码实现你可以玩的krager算法。它不是最有效的代码(特别是可以使用更高效的数据结构),因为我在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);
}
}
}