public static void FordFulkerson(DrawingSurface ds) { if (ds.IsUndirected()) { var err = new ErrorBox("Graph have to be directed!"); err.ShowDialog(); return; } if (ds.ContainsNegativeEdge()) { var err = new ErrorBox("Graph can not contain negative edges!"); err.ShowDialog(); return; } Dictionary <int, List <Edge> > adjList = ds.GetDestAdjList(); (var source, var sink) = GetSourceAndSink(adjList); if (source == -1 || sink == -1) { var err = new ErrorBox("Graph have to contain source and sink!"); err.ShowDialog(); return; } ; var fulkersonItems = new FulkersonItem[adjList.Count, adjList.Count]; var minimalFlow = .0; var flows = new List <double>(); msg.MoveToCorner(ds.FindForm() as Form1); msg.SetTitle("Ford-Fulkerson algorithm result:\n"); msg.StartMenu(); for (var i = 0; i < adjList.Count; ++i) { for (var j = 0; j < adjList.Count; ++j) { fulkersonItems[i, j] = new FulkersonItem(); } } for (var start = 0; start < adjList.Count; ++start) { foreach (var edge in adjList[start]) { fulkersonItems[start, edge.end].toFlow = edge.w; edge.SetLabel($"{edge.w}/{0}"); } } while (minimalFlow != -1) { ds.Vertices[source].fillColor = Color.Green; ds.Vertices[sink].fillColor = Color.Red; ds.Invalidate(); minimalFlow = ProcessFulkerson(source, sink, adjList, ref fulkersonItems, ds); if (minimalFlow != -1) { flows.Add(minimalFlow); } ClearVertices(ds); ClearEdges(ds, false); } AlgorithmDone(ds); msg.AddText($"Total maximal flow:\n"); msg.AddText("f(G) = "); for (var i = 0; i < flows.Count; ++i) { msg.AddText($"{flows[i]} "); if (i != flows.Count - 1) { msg.AddText("+ "); } Thread.Sleep(700); } msg.AddText($"= {flows.Sum()}"); msg.WaitOne(); ClearVertices(ds); ClearEdges(ds, true); }
public static void Dijkstra(DrawingSurface ds, int start) { if (ds.ContainsNegativeEdge()) { var err = new ErrorBox("Graph contains negative edges"); err.ShowDialog(); return; } Dictionary <int, List <Edge> > adjList = ds.GetDestAdjList(); var que = new C5.IntervalHeap <Edge>(new EdgeCompare()); double[] dist = Enumerable.Repeat((double)int.MaxValue, adjList.Count).ToArray(); int[] parent = Enumerable.Repeat(-1, adjList.Count).ToArray(); var visitedColor = Color.Green; var processedColor = Color.Yellow; var currentEdgeColor = Color.Red; que.Add(new Edge(ds.Vertices[start], ds.Vertices[start], 0, true)); dist[start] = 0; for (var i = 0; i < ds.Vertices.Count; ++i) { ds.Vertices[i].label = "INF"; } ds.Vertices[start].label = "0"; while (que.Count != 0) { var currEdge = que.FindMin(); que.DeleteMin(); var startVertex = (ds.Vertices[currEdge.end].fillColor == visitedColor) ? currEdge.start : currEdge.end; ReDrawCircle(ds, startVertex, visitedColor); foreach (var edge in adjList[startVertex]) { var currVertex = (edge.end != startVertex) ? edge.end : edge.start; ReDrawEdge(ds, edge, currentEdgeColor, 300); if (ds.Vertices[currVertex].fillColor != visitedColor) { ReDrawCircle(ds, currVertex, processedColor, 0); } Thread.Sleep(1000); if (dist[currVertex] > dist[startVertex] + edge.w) { dist[currVertex] = dist[startVertex] + edge.w; parent[currVertex] = startVertex; ds.Vertices[currVertex].label = $"{Math.Round(dist[currEdge.end], 3)}+{Math.Round(edge.w, 3)}"; ds.Invalidate(); Thread.Sleep(1000); que.Add(edge); } ds.Vertices[currVertex].label = (dist[currVertex] == int.MaxValue) ? "INF" : $"{dist[currVertex]}"; ReDrawEdge(ds, edge, Color.Gray, 0); } } msg.SetTitle("Dijkstra algorithm result:"); msg.MoveToCorner(ds.FindForm() as Form1); msg.StartMenu(); for (var target = 0; target < adjList.Count; ++target) { if (start != target) { var currWay = GetWay(start, target, parent); PrintWay(currWay, dist[target]); Thread.Sleep(1000); } } msg.WaitOne(); ClearEdges(ds); ClearVertices(ds); }