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

            for (int i = 1; i <= graph.VertexLenght; i++)
            {
                foreach (var edge in graph.GetEdges())
                {
                    graph.Relax(edge.Start, edge.End, weightFuc);
                }
            }

            foreach (var edge in graph.GetEdges())
            {
                if (edge.Start.WeightBound >
                    Add(edge.End.WeightBound, weightFuc(graph, edge.Start, edge.End)))
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #2
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;
            }
        }
コード例 #3
0
        /// <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);
        }
コード例 #4
0
        /// <summary>
        /// 看不懂算法导论上的实现
        /// </summary>
        /// <param name="graph"></param>
        /// <param name="source"></param>
        /// <param name="target"></param>
        public int EdmondsKarp(
            AdjacencyListGraph <T> graph
            , AdjacencyVertex <T> source
            , AdjacencyVertex <T> target)
        {
            var maxflow = 0;

            var edges = graph.GetEdges().Select(d => d as FlowEdge <T>);

            foreach (var edge in edges)
            {
                edge.Flow = 0;
            }


            while (true)
            {
                var path = GetResidualPath(graph, source, target);
                if (path == null || path.Count == 0)
                {
                    break;
                }
                var tempFlow = int.MaxValue;

                //感觉第一次写这样的for循环
                for (var edge = path[target]; edge != null; edge = path[edge.Start])
                {
                    tempFlow = Math.Min(tempFlow, edge.ResidualCapacity);
                }

                Console.WriteLine();
                Console.WriteLine($"pathflow:{tempFlow}");

                for (var edge = path[target]; edge != null; edge = path[edge.Start])
                {
                    edge.Flow            = edge.Flow + tempFlow;
                    edge.Revolution.Flow = edge.Revolution.Flow - tempFlow;
                    Console.WriteLine($"edge:{edge}");
                }

                maxflow = maxflow + tempFlow;
            }

            return(maxflow);
        }
コード例 #5
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);
        }