public LazyPrimMST(WeightSpareGraph <float> g) { this.g = g; this.n = g.V(); this.m = g.E(); minHeap = new MinHeap <Edge <float> > (m); minSpanTreeEdge = new List <Edge <float> > (); book = new bool[n]; for (int i = 0; i != n; i++) { book [i] = false; } book [0] = true; visit(0); while (minHeap.Size() != 0) { Edge <float> e = minHeap.ExtraMinItem(); int u = e.U(); int v = e.V(); if (book [u] == book [v]) { continue; } if (!book [u]) { book [u] = true; minSpanTreeEdge.Add(e); visit(u); } else { book [v] = true; visit(v); minSpanTreeEdge.Add(e); } // if (!book [e.V ()] && book [e.U ()]) {//这里出错了~~~= =other也出错了。。。 // book [e.V ()] = true; // visit (e.V ()); // minSpanTreeEdge.Add (e); // minSpanValue =minSpanValue+ e.weight; // } else if (book [e.V ()] && !book [e.U ()]) { // book [e.U ()] = true; // visit (e.U ()); // minSpanTreeEdge.Add (e); // minSpanValue += e.weight; // } else if (book [e.V ()] && book [e.U ()]) { // continue; // } else { // Debug.Assert (false); // } } foreach (Edge <float> e in minSpanTreeEdge) { minSpanValue += e.weight; } }
// Use this for initialization void Start() { //利用LazyPrim算法计算稀疏有权图的最短路径 print("求稀疏有权图的最小生成树"); string name = ""; string url = ""; name = "testWeightG1.txt"; url = FileHelper.FileNameHelper(name); WeightSpareGraph <float> wsGraph = null; ReadWeightGraph.ReadGraphFromFile(url, out wsGraph, false); wsGraph.print(); LazyPrimMST lazyPrim = new LazyPrimMST(wsGraph); lazyPrim.print(); print("最小生成树的长度为:" + lazyPrim.length()); print("使用深度优先搜索的方法得到一棵生成树"); lazyPrim = new LazyPrimMST(wsGraph, true); lazyPrim.printOneTree(); print("*********************"); //利用Prim算法计算稀疏有权图的最短路径 PrimMST prim = new PrimMST(wsGraph); prim.print(); }
public void visit(int u) { WeightSpareGraph <float> .adjIterator iter = new WeightSpareGraph <float> .adjIterator(graph, u); for (Edge <float> e = iter.begin(); !iter.isEnd(); e = iter.Next()) { if (book [e.Other(u)]) { continue; } int v = e.Other(u); // u if (toEdgeArr [v] == null) { toEdgeArr [v] = e; indexMinHeap.Insert(v, e.weight); } else { if (toEdgeArr [v].CompareTo(e) > 0) { toEdgeArr [v] = e; indexMinHeap.Change(v, e.weight); } } } }
// Use this for initialization void Start() { string name = "testWeightG1.txt"; string url = FileHelper.FileNameHelper(name); WeightSpareGraph <float> sGraph = null; ReadWeightGraph.ReadGraphFromFile(url, out sGraph, false); KrusalMST <float> krusalMST = new KrusalMST <float> (sGraph); print("Krusal算法生成的最小生成树,长度为" + krusalMST.length()); krusalMST.print(); }
//访问n节点,将所有的横切边加入最小索引堆 private void visit(int u) { WeightSpareGraph <float> .adjIterator iter = new WeightSpareGraph <float> .adjIterator(g, u); for (Edge <float> e = iter.begin(); !iter.isEnd(); e = iter.Next()) { if (book [e.Other(u)] == true) { continue; } minHeap.Insert(e); } }
public Dijkstra(WeightSpareGraph <float> graph, int src) { Debug.Assert(src >= 0 && src < graph.V()); this.src = src; this.graph = graph; this.n = graph.V(); this.m = graph.E(); shortPath = new float[n]; book = new bool[n]; from = new int[n]; for (int i = 0; i != n; i++) { book [i] = false; from [i] = -1; //假设都是可达的 } from [src] = -1; shortPath [src] = 0f; IndexMinHeap <float> indexMinHeap = new IndexMinHeap <float> (n); indexMinHeap.Insert(src, shortPath[src]); while (indexMinHeap.Size() != 0) { int u = indexMinHeap.ExtraMinItemIndex(); book [u] = true; WeightSpareGraph <float> .adjIterator iter = new WeightSpareGraph <float> .adjIterator(graph, u); for (Edge <float> e = iter.begin(); !iter.isEnd(); e = iter.Next()) { int v = e.Other(u); if (!book[v]) { if (from [v] == -1 || shortPath [v] > shortPath [u] + e.weight) { from [v] = u; shortPath [v] = shortPath [u] + e.weight; if (indexMinHeap.isContain(v)) { indexMinHeap.Change(v, shortPath [v]); } else { indexMinHeap.Insert(v, shortPath[v]); } } } } } }
private void DSF(int u) { WeightSpareGraph <float> .adjIterator iter = new WeightSpareGraph <float> .adjIterator(g, u); for (Edge <float> edge = iter.begin(); !iter.isEnd(); edge = iter.Next()) { if (book [edge.Other(u)] == false) { book [edge.Other(u)] = true; oneSpantreeEdge.Add(edge); oneSpanValue += edge.weight; DSF(edge.Other(u)); } } }
// Use this for initialization void Start() { string name = "testWeightG1.txt"; // name = "testShortPath.txt"; string url = FileHelper.FileNameHelper(name); WeightSpareGraph <float> sGraph = null; ReadWeightGraph.ReadGraphFromFile(url, out sGraph, false); sGraph.print(); Dijkstra dijkstra = new Dijkstra(sGraph, 0); dijkstra.ShowAllPath(); BellmanFord bellmanFord = new BellmanFord(sGraph, 0); bellmanFord.showAllPath(); }
private bool detectNegetiveCircle() { for (int u = 0; u != n; u++) { WeightSpareGraph <float> .adjIterator iter = new WeightSpareGraph <float> .adjIterator(graph, u); for (Edge <float> e = iter.begin(); !iter.isEnd(); e = iter.Next()) { // int v = e.Other(u); if (from [v] == -1 || shortPathValue [v] > shortPathValue [u] + e.weight) { return(false); } } } return(true); }
public static void ReadGraphFromFile(string fileName, out WeightSpareGraph <float> graph, bool isDirected) { int V, E; string[] strs = File.ReadAllLines(fileName); Debug.Assert(strs.Length >= 2); string veline = strs [0]; readGraphFileVELine(veline, out V, out E); // Debug.Log ("V , E " + V +"," + E); graph = new WeightSpareGraph <float>(V, isDirected); for (int i = 0; i != E; i++) { string line = strs [i + 1]; int p, q; float w; readGraphFileVEWLine(line, out p, out q, out w); graph.AddEdge(p, q, w); } }
public PrimMST(WeightSpareGraph <float> graph) { this.graph = graph; this.n = graph.V(); this.m = graph.E(); minSpanTreeValue = 0; book = new bool[n]; toEdgeArr = new List <Edge <float> >(); for (int i = 0; i != n; i++) { toEdgeArr.Add(null); } for (int i = 0; i != n; i++) { book [i] = false; } indexMinHeap = new IndexMinHeap <float> (m); book [0] = true; visit(0); while (indexMinHeap.Size() != 0) { int index = indexMinHeap.ExtraMinItemIndex(); Debug.Assert(toEdgeArr[index] != null); book[index] = true; visit(index); // int u = toEdgeArr [index].U (); // int v = toEdgeArr [index].V (); // if (book [u] && !book [v]) { // book [v] = true; // visit (v); // } else if(!book [u] && book [v]){ // book [u] = true; // visit (u); // } } for (int i = 1; i != n; i++) { minSpanTreeValue += toEdgeArr [i].weight; } }
//测试稠密有权图 //测试稀疏有权图 public void testWeightDSGraph() { string name = ""; string url = ""; //测试稠密有权图~ print("测试稠密有权图"); WeightDenseGraph <float> wdGraph = null; name = "testWeightG1.txt"; url = FileHelper.FileNameHelper(name); ReadWeightGraph.ReadGraphFromFile(url, out wdGraph, false); // out不可缺少 wdGraph.print(); //测试稀疏有权图 print("测试稀疏有权图"); WeightSpareGraph <float> wsGraph = null; ReadWeightGraph.ReadGraphFromFile(url, out wsGraph, false); wsGraph.print(); }
//使用深度优先搜索得到一棵深沉树 public LazyPrimMST(WeightSpareGraph <float> g, bool usingDSF) { this.g = g; this.n = g.V(); oneSpantreeEdge = new List <Edge <float> > (); oneSpanValue = 0f; book = new bool[n]; for (int i = 0; i != n; i++) { book [i] = false; } for (int u = 0; u != n; u++) { if (!book [u]) { book [u] = true; DSF(u); } } Debug.Log("一条生成树的长度为: " + oneSpanValue); }
public BellmanFord(WeightSpareGraph <float> graph, int src) { this.graph = graph; this.n = graph.V(); this.m = graph.E(); this.src = src; this.from = new int[n]; shortPathValue = new float[n]; for (int i = 0; i != n; i++) { from [i] = -1; shortPathValue [i] = 9999f; } from [src] = -1; shortPathValue [src] = 0f; for (int i = 0; i != n - 1; i++) { for (int u = 0; u != n; u++) { WeightSpareGraph <float> .adjIterator iter = new WeightSpareGraph <float> .adjIterator(graph, u); for (Edge <float> e = iter.begin(); !iter.isEnd(); e = iter.Next()) { // int v = e.Other(u); if (shortPathValue [v] > shortPathValue [u] + e.weight) { from [v] = u; shortPathValue [v] = shortPathValue [u] + e.weight; } } } } isContainNegativeCircle = detectNegetiveCircle(); }
public adjIterator(WeightSpareGraph <Weight> graph, int v) { this.graph = graph; this.v = v; index = 0; }
public KrusalMST(WeightSpareGraph <float> graph) { this.graph = graph; this.n = graph.V(); this.m = graph.E(); book = new bool[n]; for (int i = 0; i != n; i++) { book [i] = false; } minSpanTreeValue = 0f; minSpanTreeEdge = new List <Edge <float> > (); //遍历图将所有的边加入allEdge数组 allEdge = new List <Edge <float> >(); for (int i = 0; i != n; i++) { WeightSpareGraph <float> .adjIterator iter = new WeightSpareGraph <float> .adjIterator(graph, i); for (Edge <float> e = iter.begin(); !iter.isEnd(); e = iter.Next()) { int u = e.U(); int v = e.V(); if (u < v) { allEdge.Add(e); } } } Edge <float>[] edges = allEdge.ToArray(); QuickSorts(edges, edges.Length); string str = ""; for (int i = 0; i != edges.Length; i++) { str += edges [i].ToString() + "\n"; } Debug.Log(str); // UnionFind unionFind = new UnionFind (edges.Length); UnionFind uf = new UnionFind(n); for (int i = 0; i != edges.Length; i++) { int u = edges [i].U(); int v = edges [i].V(); if (uf.isConnected(u, v)) { continue; } uf.Union_Rank(u, v); minSpanTreeEdge.Add(edges[i]); } for (int i = 0; i != minSpanTreeEdge.Count; i++) { minSpanTreeValue += minSpanTreeEdge [i].weight; } Debug.Log("n,m = " + n + ", " + m); //犯了一个致命的错误, = =虽然数组只有两个状态连或者不连,但是 //当两个都是false的时候,下面设置为true,这样代表他与第一组也连了,但实际上是没有连的。 //修改~一旦两个都是false,与下一个交换= =还是不行。还是用并查集。 // minSpanTreeEdge.Add (edges[0]); // book [edges [0].U ()] = true; // book [edges [0].V ()] = true; // for (int i = 1; i != edges.Length; i++) { // int u = edges [i].U (); // int v = edges [i].V (); // // if (book [u] == book [v]) { // //both true // if (book [u]) // continue; // //both false // AlgorithmsHelp.Swap(edges[i],edges[i+1]); // book [u] = true; // book [v] = true; // minSpanTreeEdge.Add (edges [i]); // } else { // //either // book[u] = true; // book [v] = true; // minSpanTreeEdge.Add (edges [i]); // } // // } //深度搜索建立并查集,错了。 // for (int i = 0; i != n; i++) { // if (!book [i]) { // book [i] = true; // DSF (i); // // } // } }