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; } }
/// <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> /// 怎么输出最小生成树? /// 很神奇的是这个贪心算法是对的 /// </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); }
/// <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); } } }