public MinCreateTreeUseKruskal(WeightGraph weightGraph) { _weightGraph = weightGraph; _result = new List <WeightEdge>(); //cc检测是否联通 List <WeightEdge> list = new List <WeightEdge>(); for (int i = 0; i < _weightGraph.V; i++) { foreach (var w in _weightGraph.GetAllContiguousEdge(i)) { if (i > w) { continue; } int weight = _weightGraph.GetWeight(i, w); list.Add(new WeightEdge(i, w, weight)); } } list.Sort(); UnionFindAggregate uf = new UnionFindAggregate(_weightGraph.V); foreach (var e in list) { if (uf.IsConnected(e.V, e.W)) { continue; } _result.Add(e); uf.Union(e.V, e.W); } }
public Edmonds_Karp(WeightGraph weightGraph, int s, int t) { _weightGraph = weightGraph; _s = s; _t = t; if (!weightGraph.Directed) { throw new Exception("directed graph can be supported"); } if (_weightGraph.V < 2) { throw new Exception("vertex must be more than 2"); } _weightGraph.ValidateNumber(s); _weightGraph.ValidateNumber(t); if (s == t) { throw new Exception("source point and sink point can't be same"); } _residualQuantityGraph = new WeightGraph(_weightGraph.V, true); for (int v = 0; v < _weightGraph.V; v++) { foreach (var w in _weightGraph.GetAllContiguousEdge(v)) { int weight = _weightGraph.GetWeight(v, w); _residualQuantityGraph.AddEdge(v, w, weight); _residualQuantityGraph.AddEdge(w, v, 0); } } while (true) { List <int> path = GetArgumentingPath(); if (path.Count == 0) { break; } int f = int.MaxValue; for (int i = 1; i < path.Count; i++) { int v = path[i - 1]; int w = path[i]; f = Math.Min(f, _residualQuantityGraph.GetWeight(v, w)); } MaxFlow += f; for (int i = 1; i < path.Count; i++) { int v = path[i - 1]; int w = path[i]; int weight = _residualQuantityGraph.GetWeight(v, w); int residualQuantity = _residualQuantityGraph.GetWeight(w, v); _residualQuantityGraph.SetWeight(v, w, weight - f); _residualQuantityGraph.SetWeight(w, v, residualQuantity + f); } } }
public Bellman_Ford(WeightGraph weightGraph, int s) { this._weightGraph = weightGraph; this._s = s; _pre = new int[_weightGraph.V]; _dirs = new int[_weightGraph.V]; for (int i = 0; i < _weightGraph.V; i++) { _dirs[i] = Int32.MaxValue; } _dirs[s] = 0; for (int i = 0; i < _weightGraph.V - 1; i++) { for (int j = 0; j < _weightGraph.V; j++) { foreach (var w in _weightGraph.GetAllContiguousEdge(j)) { if (_dirs[j] != int.MaxValue && _dirs[j] + _weightGraph.GetWeight(j, w) < _dirs[w]) { _dirs[w] = _dirs[j] + _weightGraph.GetWeight(j, w); _pre[w] = j; } } } } for (int j = 0; j < _weightGraph.V; j++) { foreach (var w in _weightGraph.GetAllContiguousEdge(j)) { if (_dirs[j] != int.MaxValue && _dirs[j] + _weightGraph.GetWeight(j, w) < _dirs[w]) { IsHaveCircle = true; } } } }
public Floyed(WeightGraph weightGraph) { this._weightGraph = weightGraph; _dirs = new int[_weightGraph.V][]; _pre = new int[_weightGraph.V, _weightGraph.V]; for (int i = 0; i < _weightGraph.V; i++) { for (int j = 0; j < _weightGraph.V; j++) { _pre[i, j] = i; } } for (int i = 0; i < _weightGraph.V; i++) { _dirs[i] = new int[_weightGraph.V]; Array.Fill(_dirs[i], int.MaxValue); } for (int v = 0; v < _weightGraph.V; v++) { foreach (var w in _weightGraph.GetAllContiguousEdge(v)) { _dirs[v][w] = _weightGraph.GetWeight(v, w); } } //Floyed for (int t = 0; t < _weightGraph.V; t++) { for (int v = 0; v < _weightGraph.V; v++) { for (int w = 0; w < _weightGraph.V; w++) { if (_dirs[v][t] != Int32.MaxValue && _dirs[t][w] != Int32.MaxValue && _dirs[v][t] + _dirs[t][w] < _dirs[v][w]) { _dirs[v][w] = _dirs[v][t] + _dirs[t][w]; _pre[v, w] = _pre[t, w]; } } } } for (int i = 0; i < _weightGraph.V; i++) { if (_dirs[i][i] < 0) { IsHaveNegativeCircle = true; } } }
public Dijkstra(WeightGraph weightGraph, int s) { this._weightGraph = weightGraph; this._s = s; _pre = new int[_weightGraph.V]; _visited = new bool[_weightGraph.V]; _dirs = new int[_weightGraph.V]; for (int i = 0; i < _weightGraph.V; i++) { _dirs[i] = int.MaxValue; } _dirs[_s] = 0; while (true) { int curDis = Int32.MaxValue; int cur = -1; for (int i = 0; i < _weightGraph.V; i++) { if (!_visited[i] && _dirs[i] < curDis) { curDis = _dirs[i]; cur = i; } } if (cur == -1) { break; } _visited[cur] = true; foreach (var w in _weightGraph.GetAllContiguousEdge(cur)) { if (!_visited[w] && _dirs[w] > _dirs[cur] + _weightGraph.GetWeight(cur, w)) { _dirs[w] = _dirs[cur] + _weightGraph.GetWeight(cur, w); _pre[w] = cur; } } } }
private List <int> GetArgumentingPath() { Queue <int> queue = new Queue <int>(); queue.Enqueue(_s); int[] pre = new int[_residualQuantityGraph.V]; for (int i = 0; i < _residualQuantityGraph.V; i++) { pre[i] = -1; } pre[_s] = _s; while (queue.Count > 0) { int v = queue.Dequeue(); foreach (var w in _residualQuantityGraph.GetAllContiguousEdge(v)) { if (pre[w] == -1 && _residualQuantityGraph.GetWeight(v, w) > 0) { pre[w] = v; queue.Enqueue(w); } } } List <int> path = new List <int>(); if (pre[_t] == -1) { return(path); } int cur = _t; while (cur != _s) { path.Add(cur); cur = pre[cur]; } path.Add(_s); path.Reverse(); return(path); }
public MinCreateTreeUsePrim(WeightGraph weightGraph) { this._weightGraph = weightGraph; _result = new List <WeightEdge>(); //cc 的联通分量个数==1 bool[] visited = new bool[_weightGraph.V]; visited[0] = true; for (int i = 0; i < _weightGraph.V - 1; i++) { WeightEdge min = new WeightEdge(-1, -1, int.MaxValue); for (int j = 0; j < visited.Length; j++) { if (visited[j] == false) { continue; } foreach (var w in _weightGraph.GetAllContiguousEdge(j)) { if (visited[w]) { continue; } int weight = _weightGraph.GetWeight(j, w); WeightEdge cur = new WeightEdge(j, w, weight); if (cur.CompareTo(min) < 0) { min = cur; } } } _result.Add(min); visited[min.W] = true; visited[min.V] = true; } }