/// <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
 public AdjacencyVertex <T> CreateVertex(AdjacencyVertex <T> vertex)
 {
     return(new AdjacencyVertex <T>()
     {
         Key = vertex.Key, Identifier = vertex.Identifier
     });
 }
예제 #3
0
        public AdjacencyEdge <T> CreateEdge(AdjacencyVertex <T> start, AdjacencyVertex <T> end, int weight)
        {
            var edge = new AdjacencyEdge <T>(start, end);

            edge.Weight = weight;
            return(edge);
        }
예제 #4
0
        private void DepthFirstSearchVisit(AdjacencyVertex <T> source, Action <AdjacencyVertex <T> > finalVisitAction)
        {
            source.Color          = Color.Gray;
            _time                 = _time + 1;
            source.FisrtVisitTime = _time;

            var edges = GetVertexEdge(source);

            foreach (var item in edges)
            {
                var vertex = item.End;
                if (vertex.Color == Color.White)
                {
                    vertex.Predecessor = source;
                    DepthFirstSearchVisit(vertex, finalVisitAction);
                }
            }

            source.Color = Color.Black;

            _time = _time + 1;
            source.FinalVisitTime = _time;

            finalVisitAction?.Invoke(source);
        }
예제 #5
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;
            }
        }
예제 #6
0
 public void AddEdge(AdjacencyVertex <T> first, AdjacencyVertex <T> second)
 {
     AddEdge(CreateEdge(first, second));
     if (!HasDirection)
     {
         AddEdge(CreateEdge(second, first));
     }
 }
예제 #7
0
 public void AddVertex(AdjacencyVertex <T> vertex)
 {
     if (!IsVertexExist(vertex))
     {
         _adjacencyDictionary[vertex.Identifier] = vertex;
     }
     else
     {
     }
 }
예제 #8
0
        public AdjacencyVertex <T> CreateVertex(T key)
        {
            var vertex = new AdjacencyVertex <T>()
            {
                Key = key
            };

            vertex.Identifier = GetCurrentIdentifier();
            return(vertex);
        }
예제 #9
0
        public IEnumerable <AdjacencyEdge <T> > GetVertexEdge(AdjacencyVertex <T> vertex)
        {
            var edges = new List <AdjacencyEdge <T> >();
            var edge  = vertex.FirstEdge;

            while (edge != null)
            {
                edges.Add(edge);
                edge = edge.Next;
            }
            return(edges);
        }
예제 #10
0
        public AdjacencyEdge <T> GetEdge(AdjacencyVertex <T> first, AdjacencyVertex <T> second)
        {
            var edge = first.FirstEdge;

            while (edge != null)
            {
                if (edge.End == second)
                {
                    return(edge);
                }
                edge = edge.Next;
            }
            return(null);
        }
        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;
        }
        public static void Relax <T>(
            this AdjacencyListGraph <T> graph,
            AdjacencyVertex <T> first,
            AdjacencyVertex <T> second,
            Func <AdjacencyListGraph <T>, AdjacencyVertex <T>, AdjacencyVertex <T>, int> weightFuc
            ) where T : IEquatable <T>
        {
            var newBound = Add(first.WeightBound, weightFuc(graph, first, second));

            if (second.WeightBound > newBound)
            {
                second.WeightBound = newBound;
                second.Predecessor = first;
            }
        }
        /// <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);
                    }
                }
            }
        }
예제 #14
0
        public int GenericPushRelabel(
            AdjacencyListGraph <T> graph
            , AdjacencyVertex <T> source
            , AdjacencyVertex <T> target
            )
        {
            var maxFolw = 0;

            InitializePreflow(graph, source);


            while (true)
            {
            }

            return(maxFolw);
        }
예제 #15
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);
        }
        /// <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);
        }
예제 #17
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);
        }
예제 #18
0
        public IEnumerable <AdjacencyEdge <T> > CreateNonDirectionEdge(AdjacencyVertex <T> start, AdjacencyVertex <T> end, int weight)
        {
            var edges = new List <AdjacencyEdge <T> >();

            var edge = new AdjacencyEdge <T>(start, end);

            edge.Weight = weight;
            edges.Add(edge);

            var secondedge = new AdjacencyEdge <T>(end, start);

            secondedge.Weight = weight;
            //加边加错了,bug就是这么神奇
            //edges.Add(edge);
            edges.Add(secondedge);

            return(edges);
        }
예제 #19
0
        public IEnumerable <AdjacencyVertex <T> > GetPath(AdjacencyVertex <T> source, AdjacencyVertex <T> vertex)
        {
            var path = new List <AdjacencyVertex <T> >();

            if (source == vertex)
            {
                path.Add(vertex);
                return(path);
            }
            if (vertex.Predecessor == null)
            {
                return(null);
                // Console.WriteLine("no path form source:{0} vertex:{1}", source, vertex);
            }
            else
            {
                path.AddRange(GetPath(source, vertex.Predecessor));
                return(path);
            }
        }
        /// <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);
                }
            }
        }
예제 #21
0
        private void DepthFirstSearchVisitStronglyConnected
            (AdjacencyVertex <T> source
            , AdjacencyListGraph <T> graph
            )
        {
            source.Color          = Color.Gray;
            _time                 = _time + 1;
            source.FisrtVisitTime = _time;

            var edges = GetVertexEdge(source);

            //调整
            var newSource = CreateVertex(source);

            graph.AddVertex(newSource);

            foreach (var item in edges)
            {
                var vertex = item.End;

                if (vertex.Color == Color.White)
                {
                    //调整

                    var newVertex = CreateVertex(vertex);
                    graph.AddVertex(newVertex);

                    graph.AddEdge(new AdjacencyEdge <T>(newVertex, newSource));

                    vertex.Predecessor = source;
                    DepthFirstSearchVisitStronglyConnected(vertex, graph);
                }
            }

            source.Color = Color.Black;

            _time = _time + 1;
            source.FinalVisitTime = _time;
        }
예제 #22
0
        public void BreadthFirstSearch(AdjacencyVertex <T> source, Action <AdjacencyVertex <T> > finalVisitAction)
        {
            var grayQueue = new Queue <AdjacencyVertex <T> >();

            foreach (var vertex in _adjacencyDictionary.Values)
            {
                if (vertex == source)
                {
                    continue;
                }
                vertex.Distance    = int.MaxValue;
                vertex.Predecessor = null;
                vertex.Color       = Color.White;
            }

            source.Color       = Color.Gray;
            source.Predecessor = null;
            source.Distance    = 0;

            grayQueue.Enqueue(source);
            while (!grayQueue.IsEmpty)
            {
                var startVertex = grayQueue.Dequeue();
                foreach (var edge in GetVertexEdge(startVertex))
                {
                    var endVertex = edge.End;
                    if (endVertex.Color == Color.White)
                    {
                        endVertex.Color       = Color.Gray;
                        endVertex.Distance    = startVertex.Distance + 1;
                        endVertex.Predecessor = startVertex;
                        grayQueue.Enqueue(endVertex);
                    }
                }
                startVertex.Color = Color.Black;
                finalVisitAction(startVertex);
            }
        }
예제 #23
0
 public bool Equals(AdjacencyVertex <T> other)
 {
     return(Key.Equals(other.Key));
 }
예제 #24
0
 private void Relabel(AdjacencyListGraph <T> graph, AdjacencyVertex <T> vertex)
 {
 }
예제 #25
0
 public AdjacencyEdge(AdjacencyVertex <T> start, AdjacencyVertex <T> end)
 {
     Start = start;
     End   = end;
 }
예제 #26
0
 public FlowEdge(AdjacencyVertex <T> start, AdjacencyVertex <T> end, int capacity)
     : base(start, end)
 {
     Capacity = capacity;
 }
예제 #27
0
 public AdjacencyEdge <T> CreateEdge(AdjacencyVertex <T> start, AdjacencyVertex <T> end)
 {
     return(new AdjacencyEdge <T>(start, end));
 }
예제 #28
0
 public bool IsVertexExist(AdjacencyVertex <T> vertex)
 {
     return(_adjacencyDictionary.ContainsKey(vertex.Identifier));
 }