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