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