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 PrimSpanningTree(DrawingSurface ds) { if (!ds.IsFullyConnected() || ds.IsDirected()) { ErrorBox err = new ErrorBox("Graph has to be undirected and fully connected"); err.ShowDialog(); return; } const int INF = int.MaxValue; var vertexNum = ds.Vertices.Count; var spanningTreeColor = Color.Red; var adjMatrix = ds.GetDistMatrix(); var used = new bool[vertexNum]; double[] minEdge = Enumerable.Repeat((double)INF, vertexNum).ToArray(); int[] selectedEdge = Enumerable.Repeat(-1, vertexNum).ToArray(); minEdge[0] = 0; for (var i = 0; i < vertexNum; ++i) { var vertex = -1; for (var j = 0; j < vertexNum; ++j) { if (!used[j] && (vertex == -1 || minEdge[j] < minEdge[vertex])) { vertex = j; } } if (minEdge[vertex] == INF) { ErrorBox err = new ErrorBox("Minimum spanning tree cannot be found"); err.ShowDialog(); return; } used[vertex] = true; if (selectedEdge[vertex] != -1) { for (var k = 0; k < ds.Edges.Count; ++k) { if (((ds.Edges[k].start == vertex && ds.Edges[k].end == selectedEdge[vertex]) || (ds.Edges[k].start == selectedEdge[vertex] && ds.Edges[k].end == vertex))) { ds.Edges[k].fillColor = spanningTreeColor; ds.Invalidate(); ds.Vertices[ds.Edges[k].start].fillColor = spanningTreeColor; ds.Vertices[ds.Edges[k].end].fillColor = spanningTreeColor; ds.Invalidate(); Thread.Sleep(2000); } } } for (var toVertex = 0; toVertex < vertexNum; ++toVertex) { if (adjMatrix[vertex, toVertex] < minEdge[toVertex]) { minEdge[toVertex] = adjMatrix[vertex, toVertex]; selectedEdge[toVertex] = vertex; } } } Thread.Sleep(5000); ClearEdges(ds); ClearVertices(ds); ds.Invalidate(); }
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); }
public static void BackTrackingColouring(DrawingSurface ds, int colorAmount) { bool isSafe(int[,] adjmat, int[] color) { for (var i = 0; i < ds.Vertices.Count; ++i) { for (var j = i + 1; j < ds.Vertices.Count; ++j) { if (adjmat[i, j] == 1 && color[j] == color[i]) { return(false); } } } return(true); } bool GraphColouring(int[,] adjmat, int bound, int index, int[] color) { if (index == ds.Vertices.Count) { if (isSafe(adjmat, color)) { for (var k = 0; k < ds.Vertices.Count; ++k) { ReDrawCircle(ds, k, colors[color[k]]); } return(true); } return(false); } for (var j = 1; j <= bound; ++j) { color[index] = j; if (GraphColouring(adjmat, bound, index + 1, color)) { return(true); } color[index] = 0; } return(false); } var adjMatrix = ds.GetAdjMatrix(); var colorsList = new List <int> { }; if (!ds.IsUndirected()) { var err = new ErrorBox("Graph has to be unoriented"); err.ShowDialog(); return; } for (var i = 0; i < ds.Vertices.Count; ++i) { colorsList.Add(0); } if (!GraphColouring(adjMatrix, colorAmount, 0, colorsList.ToArray())) { var err = new ErrorBox($"Graph cannot be coloured into {colorAmount} colours"); err.ShowDialog(); return; } Thread.Sleep(5000); ClearVertices(ds); }