Exemplo n.º 1
0
        private void InitializePreflow(AdjacencyListGraph <T> graph
                                       , AdjacencyVertex <T> source)
        {
            var vertexs = graph.GetVertexs();

            foreach (var vertex in vertexs)
            {
                vertex.Height  = 0;
                vertex.Preflow = 0;
            }

            var edges = graph.GetEdges();

            foreach (FlowEdge <T> edge in edges)
            {
                edge.Flow            = 0;
                edge.Revolution.Flow = 0;
            }

            source.Height = vertexs.Count();

            var sourceEdges = graph.GetVertexEdge(source);

            foreach (FlowEdge <T> sourceEdge in sourceEdges)
            {
                sourceEdge.Flow            = sourceEdge.Capacity;
                sourceEdge.Revolution.Flow = -sourceEdge.Capacity;
                sourceEdge.End.Preflow     = sourceEdge.Capacity;
                source.Preflow             = source.Preflow - sourceEdge.Capacity;
            }
        }
        public static void InitializeSingleSource <T>(
            this AdjacencyListGraph <T> graph,
            AdjacencyVertex <T> source
            ) where T : IEquatable <T>
        {
            var vertexs = graph.GetVertexs();

            foreach (var vertex in vertexs)
            {
                vertex.WeightBound = int.MaxValue;
                vertex.Predecessor = null;
            }

            source.WeightBound = 0;
        }
        /// <summary>
        /// 单源最短路径会把一个点到其它所有点的最短路径算出来
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="graph"></param>
        /// <param name="source"></param>
        /// <param name="weightFuc"></param>
        /// <returns></returns>
        public static void Dijkstra <T>(
            this AdjacencyListGraph <T> graph,
            AdjacencyVertex <T> source,
            Func <AdjacencyListGraph <T>, AdjacencyVertex <T>, AdjacencyVertex <T>, int> weightFuc
            ) where T : IEquatable <T>
        {
            graph.InitializeSingleSource(source);

            var calcVertexs = new List <AdjacencyVertex <T> >();

            var vertexs = graph.GetVertexs().ToList();

            //不想再增加AdjacencyVertex对象的负担了

            var queue = new ExtentionBinanyHeap <AdjacencyVertex <T> >
                        (
                vertexs,
                (first, second) =>
            {
                return(first.WeightBound < second.WeightBound);
            }
                        );

            //  while (!queue.IsEmpty) 竟然把while写成if有才
            while (!queue.IsEmpty)
            {
                var min = queue.Extract();

                Console.WriteLine("calcVertex");
                Console.WriteLine(min);

                calcVertexs.Add(min);

                var edges = graph.GetVertexEdge(min);
                foreach (var edge in edges)
                {
                    var oldWeight = edge.End.WeightBound;
                    Relax(graph, edge.Start, edge.End, weightFuc);

                    //没有索引位置一下让我傻逼了!网上找了一下也是有调整的。
                    if (oldWeight != edge.End.WeightBound)
                    {
                        queue.UpdateKey(edge.End, edge.End);
                    }
                }
            }
        }
        /// <summary>
        /// MST
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="graph"></param>
        /// <param name="weightFunc"></param>
        /// <returns></returns>
        public static IEnumerable <AdjacencyEdge <T> > GetMininumSpanningTreeKruskal <T>(
            this AdjacencyListGraph <T> graph,
            Func <AdjacencyEdge <T>, int> weightFunc
            ) where T : IEquatable <T>
        {
            var vertexs = graph.GetVertexs();
            var edges   = graph.GetEdges().ToList();

            var sets = new Dictionary <AdjacencyVertex <T>, DisjointSet <AdjacencyVertex <T> > >();

            var result = new List <AdjacencyEdge <T> >();

            foreach (var vertex in vertexs)
            {
                sets[vertex] = (new DisjointSet <AdjacencyVertex <T> >(vertex));
            }

            foreach (var edge in edges)
            {
                edge.Weight = weightFunc(edge);
            }

            //吃自己写的狗粮,这狗粮不好吃啊
            var sort      = new QuickSort();
            var sortEdges = sort.Sort(edges, (f, s) => f.Weight.CompareTo(s.Weight) > 0);

            foreach (var sortEdge in sortEdges)
            {
                var startDisjointSet = sets[sortEdge.Start];
                var endDisjointSet   = sets[sortEdge.End];

                DisjointSet <AdjacencyVertex <T> > newSet;

                if (startDisjointSet.Find(startDisjointSet.GetNode(sortEdge.Start))
                    != endDisjointSet.Find(endDisjointSet.GetNode(sortEdge.End)))
                {
                    newSet = startDisjointSet.Union(endDisjointSet);

                    result.Add(sortEdge);
                    sets[sortEdge.Start] = newSet;
                    sets[sortEdge.End]   = newSet;
                }
            }

            return(result);
        }
        /// <summary>
        /// 怎么输出最小生成树?
        /// 很神奇的是这个贪心算法是对的
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="graph"></param>
        /// <param name="root"></param>
        /// <param name="weightFunc"></param>
        public static IList <AdjacencyEdge <T> > GetMininumSpanningTreePrim <T>(
            this AdjacencyListGraph <T> graph,
            AdjacencyVertex <T> root,
            Func <AdjacencyEdge <T>, int> weightFunc
            ) where T : IEquatable <T>
        {
            var vertexs = graph.GetVertexs().ToList();

            //TempStorage顶点到到某一顶点相连的最小权值。
            foreach (var vertex in vertexs)
            {
                vertex.TempStorage = int.MaxValue;
                vertex.Predecessor = null;
            }
            root.TempStorage = 0;


            var result = new List <AdjacencyEdge <T> >();

            var queue = new ExtentionBinanyHeap <AdjacencyVertex <T> >(vertexs, (f, s) => f.TempStorage < s.TempStorage);

            while (!queue.IsEmpty)
            {
                var min = queue.Extract();
                if (min != root)
                {
                    result.Add(graph.GetEdge(min.Predecessor, min));
                }

                var edges = graph.GetVertexEdge(min);
                foreach (var edge in edges)
                {
                    var weight = weightFunc(edge);
                    //TODO: 还有一个包含判断
                    if (edge.End.BelongedHeap == queue && weight < edge.End.TempStorage)
                    {
                        edge.End.Predecessor = min;
                        edge.End.TempStorage = weight;
                        queue.UpdateKey(edge.End, edge.End);
                    }
                }
            }

            return(result);
        }
Exemplo n.º 6
0
        public IDictionary <AdjacencyVertex <T>, FlowEdge <T> > GetResidualPath(
            AdjacencyListGraph <T> graph
            , AdjacencyVertex <T> source
            , AdjacencyVertex <T> target)
        {
            var path = new Dictionary <AdjacencyVertex <T>, FlowEdge <T> >();

            var vertexs = graph.GetVertexs();

            foreach (var vertex in vertexs)
            {
                vertex.Predecessor = null;
            }

            path[source] = null;

            var queue = new Queue <AdjacencyVertex <T> >();

            queue.Enqueue(source);

            while (!queue.IsEmpty)
            {
                var current      = queue.Dequeue();
                var currentEdges = graph.GetVertexEdge(current);
                foreach (FlowEdge <T> currentEdge in currentEdges)
                {
                    if (currentEdge.End != source &&
                        currentEdge.End.Predecessor == null &&
                        currentEdge.Capacity > currentEdge.Flow
                        )
                    {
                        path[currentEdge.End]       = currentEdge;
                        currentEdge.End.Predecessor = current;
                        queue.Enqueue(currentEdge.End);
                    }
                }
            }

            if (target.Predecessor == null)
            {
                return(null);
            }

            return(path);
        }
Exemplo n.º 7
0
        /// <summary>
        /// 获取连通图的算法是我有信心感觉我自己想的结构是对的,之后继续再验证。
        /// </summary>
        /// <param name="graph"></param>
        /// <returns></returns>
        public static IEnumerable <DisjointSet <AdjacencyVertex <T> > > GetConnectedComponenets <T>
        (
            this AdjacencyListGraph <T> graph
        ) where T : IEquatable <T>
        {
            var vertexs = graph.GetVertexs();
            var edges   = graph.GetEdges();

            var sets = new Dictionary <AdjacencyVertex <T>, DisjointSet <AdjacencyVertex <T> > >();

            var result = new List <DisjointSet <AdjacencyVertex <T> > >();



            foreach (var vertex in vertexs)
            {
                sets[vertex] = (new DisjointSet <AdjacencyVertex <T> >(vertex));
            }

            foreach (var edge in edges)
            {
                var startDisjointSet = sets[edge.Start];
                var endDisjointSet   = sets[edge.End];

                DisjointSet <AdjacencyVertex <T> > newSet;

                if (startDisjointSet.Find(startDisjointSet.GetNode(edge.Start))
                    != endDisjointSet.Find(endDisjointSet.GetNode(edge.End)))
                {
                    newSet = startDisjointSet.Union(endDisjointSet);

                    sets[edge.Start] = newSet;
                    sets[edge.End]   = newSet;


                    if (!result.Contains(newSet))
                    {
                        result.Add(newSet);
                    }
                }
            }
            return(result);
        }
        /// <summary>
        /// 有向无回路图
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="graph"></param>
        /// <param name="source"></param>
        /// <param name="weightFuc"></param>
        /// <returns></returns>
        public static void DAGShortestPath <T>(
            this AdjacencyListGraph <T> graph,
            AdjacencyVertex <T> source,
            Func <AdjacencyListGraph <T>, AdjacencyVertex <T>, AdjacencyVertex <T>, int> weightFuc
            ) where T : IEquatable <T>
        {
            graph.TopologicalSort();

            graph.InitializeSingleSource(source);

            var vertexs = graph.GetVertexs();

            foreach (var orderVertex in vertexs)
            {
                var edges = graph.GetVertexEdge(orderVertex);

                foreach (var edge in edges)
                {
                    graph.Relax(edge.Start, edge.End, weightFuc);
                }
            }
        }