/// <summary> /// ベルマン-フォード法 /// 最短経路を解くアルゴリズム /// 負の辺が存在しても、正しい解を導出できる。 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="self"></param> /// <param name="start"></param> /// <param name="end"></param> /// <returns></returns> public static SelfStack <T> BellmanFordSearch <T>(this SelfGraph <T, int> self, T start, T end) { if (self.IsDirected) { throw new Exception("無方向グラフでしか対応してまてん"); } var evalDic = InitializeEvalDictionary(self, start, end); bool isUpdated = true; while (isUpdated) { var queue = new Queue <T>(); queue.Enqueue(start); while (queue.Count > 0) { var pos = queue.Dequeue(); evalDic[pos].Checked = true; foreach (var(toVertex, eValue) in self.Data[pos]) { if (evalDic[toVertex].Checked) { continue; } queue.Enqueue(toVertex); isUpdated = UpdateEval(evalDic, pos, toVertex, eValue) || UpdateEval(evalDic, toVertex, pos, eValue); } } } return(CreateRoot(self, evalDic, start, end)); }
private static Dictionary <T, EvalVertex> InitializeEvalDictionary <T>(SelfGraph <T, int> graph, T start, T end) { var evalDic = new Dictionary <T, EvalVertex>(); foreach (var vertex in graph.Data.Keys) { if (vertex.Equals(start)) { evalDic.Add(vertex, new EvalVertex(0)); continue; } evalDic.Add(vertex, new EvalVertex(int.MaxValue)); } return(evalDic); }
private static SelfStack <T> CreateRoot <T>(SelfGraph <T, int> graph, Dictionary <T, EvalVertex> evalDic, T start, T end) { var data = graph.Data; var stack = new SelfStack <T>(); stack.Push(end); var cur = end; while (!cur.Equals(start)) { foreach (var(vertex, edge) in data[cur]) { if ((evalDic[cur].EvalValue - edge) == evalDic[vertex].EvalValue) { cur = vertex; stack.Push(vertex); break; } } } return(stack); }
/// <summary> /// ダイクストラ法 /// 最短経路を解くアルゴリズム /// ベルマンフォード法より早いが、負の辺が存在する場合は正しい解を導出できない。 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="self"></param> /// <param name="start"></param> /// <returns></returns> public static SelfStack <T> DijkstraSearch <T>(this SelfGraph <T, int> self, T start, T end) { if (self.IsDirected) { throw new Exception("無方向グラフでしかできまてん"); } var evalDic = InitializeEvalDictionary(self, start, end); var queue = new Queue <T>(); queue.Enqueue(start); while (queue.Count > 0) { var pos = queue.Dequeue(); evalDic[pos].Checked = true; foreach (var(vertex, value) in self.Data[pos]) { if (evalDic[vertex].Checked) { continue; } UpdateEval(evalDic, pos, vertex, value); } var minEval = evalDic.Where(e => !e.Value.Checked).OrderBy(e => e.Value.EvalValue).FirstOrDefault(); if (minEval.Value != null) { if (minEval.Key.Equals(end)) { break; } queue.Enqueue(minEval.Key); } } return(CreateRoot(self, evalDic, start, end)); }