Ejemplo n.º 1
0
        /// <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));
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        /// <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));
        }