/// <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); }