private void createWeight(LineViewModel lineVM) { if (VM.ShowWeights) { var dialog = new SelectWeightWindow(); dialog.Weight = Graph.getWeight(lineVM.StartNode, lineVM.EndNode); dialog.ShowDialog(); int node1 = lineVM.StartNode; int node2 = lineVM.EndNode; int weight = dialog.Weight; Graph.setWeight(node1, node2, weight); Graph.OnChange(); } }
/// <summary> /// Wyznacza wage polaczenia /// przydatne do Bellmana forda /// </summary> /// <param name="g">graf</param> /// <param name="list">sciezka z elementem poczatkowym /reszta/ koniec</param> /// <returns></returns> public static int pathWeight(DirectedGraphMatrix g, List <int> list) { int sum = 0; for (int i = 0; i < list.Count - 1; i++) { sum += g.getWeight(list[i], list[i + 1]); //Console.Write(list[i] + "->" + list[i + 1] + ":" + g.getWeight(list[i], list[i + 1]) + "; "); } //Console.WriteLine(); return(sum); }
public MaxFlow1(DirectedGraphMatrix g) { int nodes = g.NodesNr; FlowMatrix = new int[nodes, nodes]; weightMatrix = new int[nodes, nodes]; for (int i = 0; i < nodes; ++i) { for (int j = 0; j < nodes; ++j) { weightMatrix[i, j] = g.getWeight(i, j); } } }
public static DirectedGraphList ConvertToSList(DirectedGraphMatrix from) { DirectedGraphList x = new DirectedGraphList(from.NodesNr); for (int i = 0; i < from.NodesNr; i++) { for (int j = 0; j < from.NodesNr; j++) { if (from.GetConnection(i, j)) { x.MakeConnection(i, j); } x.setWeight(i, j, from.getWeight(i, j)); } } return(x); }
/// <summary> /// Implementacja algorytmu Floyda-Warshalla /// </summary> /// <param name="g"></param> Graf ktory jest spojny. Ten algorytm dziala takze dla grafow niespojnych w przeciwienstwie do johnsona /// <returns></returns> Macierz odleglosci miedzy wszystkimi wierzcholkami public static int[,] FloydWarshall(DirectedGraphMatrix graph) { int nodes = graph.NodesNr; int[,] distances = new int[nodes, nodes]; int w = 0; const int INF = int.MaxValue - 10000; for (int i = 0; i < nodes; ++i) { for (int j = 0; j < nodes; ++j) { distances[i, j] = INF; if (graph.GetConnection(i, j)) { distances[i, j] = graph.getWeight(i, j); } } distances[i, i] = 0; } for (int k = 0; k < nodes; ++k) { for (int i = 0; i < nodes; ++i) { for (int j = 0; j < nodes; ++j) { if (k == i || k == j || i == j) { continue; } if ((distances[i, k] == INF) || (distances[k, j] == INF)) { continue; } w = distances[i, k] + distances[k, j]; if (distances[i, j] > w) { distances[i, j] = w; } } } } return(distances); }
/// <summary> /// Tworzenie macierzy odleglosci pomiedzy wszystkimi parami wierzcholkow w grafie spojnym skierowanym, wykorzystuje algorytm Dijkstry /// </summary> /// <param name="from"></param> Graf skierowany, w ktorym liczymy odleglosci miedzy wszystkimi parami wierzcholkow /// <returns></returns> distances - Macierz odleglosci miedzy wszystkimi parami wierzcholkow public static int[,] distancesDirectedMatrix(DirectedGraphMatrix graph) { int nodes = graph.NodesNr; int[,] distances = new int[nodes, nodes]; List <int> path = new List <int>(); int total_dist = 0; int dist = 0; const int INF = int.MaxValue - 10000; for (int i = 0; i < nodes; ++i) { for (int j = 0; j < nodes; ++j) { if (i == j) { distances[i, j] = 0; } else { distances[i, j] = INF; } } } for (int i = 0; i < nodes; ++i) { for (int j = 0; j < nodes; ++j) { if (i == j) { continue; } else { path = PathFinding.Dijkstra(graph, i, j); if (path.Count == 0) { continue; } else if (path.Count == 1) { distances[i, j] = graph.getWeight(i, path[0]); path.Clear(); } else { for (int k = 0; k < path.Count - 1; ++k) { dist += graph.getWeight(path[k], path[k + 1]); } total_dist = dist + graph.getWeight(i, path[0]); distances[i, j] = total_dist; total_dist = dist = 0; path.Clear(); } } } } return(distances); }
/// <summary> /// Implementacja algorytmu Johnsona, korzysta z algorytmow Bellmana-Forda i Dijkstry /// </summary> /// <param name="g"></param> Musi to byc graf skierowany ktory ma juz randomowe wagi i musi byc on spojny(WAŻNE)!!!! /// Mozna np stworzyc graf skierowany, wydobyc z niego skladowa maksymalnie spojna i nadać jej randomowe wagi /// <returns></returns> Macierz odleglosci miedzy wszystkimi wierzcholkami public static int[,] Johnson(DirectedGraphMatrix graph) { try { int nodes = graph.NodesNr; int[,] distances = new int[nodes, nodes]; int[] d = new int[nodes]; const int INF = int.MaxValue - 10000; int[,] wagi = new int[nodes, nodes]; int q = nodes + 1; int[,] new_connect = new int[q, q]; for (int i = 0; i < nodes; ++i) { for (int j = 0; j < nodes; ++j) { new_connect[i, j] = graph.getConnect(i, j); wagi[i, j] = graph.getWeight(i, j); } } DirectedGraphMatrix dgraph = new DirectedGraphMatrix(q, new_connect); for (int i = 0; i < q - 1; ++i) { dgraph.MakeConnection(q - 1, i, 0); dgraph.setWeight(i, q - 1, INF); for (int j = 0; j < q - 1; ++j) { dgraph.setWeight(i, j, graph.getWeight(i, j)); } } List <List <int> > bellman = new List <List <int> >(); for (int i = 0; i < nodes; ++i) { bellman.Add(BellmanFord(dgraph, q - 1, i)); d[i] = pathWeight(dgraph, bellman[i]); if (ujemnyCykl(graph, wagi)) { throw new Exception("Algorytm Johnsona zostal zatrzymany."); } } for (int i = 0; i < q - 1; ++i) { for (int j = 0; j < q - 1; ++j) { if (dgraph.GetConnection(i, j)) { dgraph.setWeight(i, j, dgraph.getWeight(i, j) + d[i] - d[j]); } } } int[,] last_connect = new int[nodes, nodes]; for (int i = 0; i < nodes; ++i) { for (int j = 0; j < nodes; ++j) { last_connect[i, j] = dgraph.getConnect(i, j); } } DirectedGraphMatrix lgraph = new DirectedGraphMatrix(nodes, last_connect); for (int i = 0; i < nodes; ++i) { for (int j = 0; j < nodes; ++j) { lgraph.setWeight(i, j, dgraph.getWeight(i, j)); } } distances = distancesDirectedMatrix(lgraph); for (int i = 0; i < nodes; ++i) { for (int j = 0; j < nodes; ++j) { distances[i, j] = distances[i, j] - d[i] + d[j]; } } return(distances); } catch (Exception) { Console.WriteLine("Algorytm Johnsona zatrzymany z powodu ujemnego cyklu w grafie."); return(new int[5, 5]); } }
/// <summary> /// Bellman ford /// </summary> /// <param name="g"></param> /// <param name="start">skad</param> /// <param name="finish">dokad</param> /// <returns>lista wierzcholkow po ktorych otrzymamy najkrotsza sciezke start /rest/ finish</returns> public static List <int> BellmanFord(DirectedGraphMatrix g, int start, int finish) { const int INF = int.MaxValue - 1000; //uzywam jako nieskonczonosci var map = new Dictionary <int, Tuple <int, int> >(); //nr wierzch. < odleglosc, skad przyszedl > for (int i = 0; i < g.NodesNr; i++) { if (i == start) { map.Add(i, new Tuple <int, int>(0, -1)); } else { map.Add(i, new Tuple <int, int>(INF, -1)); } } var con = new List <Tuple <int, int, int> >();//lista polaczen skad / dokad / waga for (int i = 0; i < g.NodesNr; i++) { for (int j = 0; j < g.NodesNr; j++) { if (g.GetConnection(i, j)) { con.Add(new Tuple <int, int, int>(i, j, g.getWeight(i, j))); } } } for (int i = 0; i < g.NodesNr - 1; i++) { for (int j = 0; j < con.Count; j++) { if (map[con[j].Item2].Item1 == INF && map[con[j].Item1].Item1 == INF)//pozbywam sie operacji na nieskonczonosciach { continue; } if (map[con[j].Item2].Item1 > map[con[j].Item1].Item1 + con[j].Item3)//relaksacja { map[con[j].Item2] = new Tuple <int, int>(map[con[j].Item1].Item1 + con[j].Item3, con[j].Item1); } } } //sprawdzenie czy istnieje cykl ujemny //jesli wykona sie warunek istnieje ujemny for (int j = 0; j < con.Count; j++) { if (map[con[j].Item2].Item1 > map[con[j].Item1].Item1 + con[j].Item3) //relaksacja { return(null); //jesli relaksacja jest możliwa po V-1 przejściach istnieje cykl ujemny } } //sciezka wynikowa List <int> path = new List <int>(); recBellman(map, path, start, finish); //sciezke otrzymamy od konca if (path.Count == 1) //brak sciezki { return(null); } path.Reverse(); return(path); }