/// <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); }
public AdjacencyVertex <T> CreateVertex(AdjacencyVertex <T> vertex) { return(new AdjacencyVertex <T>() { Key = vertex.Key, Identifier = vertex.Identifier }); }
public AdjacencyEdge <T> CreateEdge(AdjacencyVertex <T> start, AdjacencyVertex <T> end, int weight) { var edge = new AdjacencyEdge <T>(start, end); edge.Weight = weight; return(edge); }
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); }
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 void AddEdge(AdjacencyVertex <T> first, AdjacencyVertex <T> second) { AddEdge(CreateEdge(first, second)); if (!HasDirection) { AddEdge(CreateEdge(second, first)); } }
public void AddVertex(AdjacencyVertex <T> vertex) { if (!IsVertexExist(vertex)) { _adjacencyDictionary[vertex.Identifier] = vertex; } else { } }
public AdjacencyVertex <T> CreateVertex(T key) { var vertex = new AdjacencyVertex <T>() { Key = key }; vertex.Identifier = GetCurrentIdentifier(); return(vertex); }
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); }
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); } } } }
public int GenericPushRelabel( AdjacencyListGraph <T> graph , AdjacencyVertex <T> source , AdjacencyVertex <T> target ) { var maxFolw = 0; InitializePreflow(graph, source); while (true) { } return(maxFolw); }
/// <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); }
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); }
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); }
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); } } }
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; }
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); } }
public bool Equals(AdjacencyVertex <T> other) { return(Key.Equals(other.Key)); }
private void Relabel(AdjacencyListGraph <T> graph, AdjacencyVertex <T> vertex) { }
public AdjacencyEdge(AdjacencyVertex <T> start, AdjacencyVertex <T> end) { Start = start; End = end; }
public FlowEdge(AdjacencyVertex <T> start, AdjacencyVertex <T> end, int capacity) : base(start, end) { Capacity = capacity; }
public AdjacencyEdge <T> CreateEdge(AdjacencyVertex <T> start, AdjacencyVertex <T> end) { return(new AdjacencyEdge <T>(start, end)); }
public bool IsVertexExist(AdjacencyVertex <T> vertex) { return(_adjacencyDictionary.ContainsKey(vertex.Identifier)); }