public void Run() { Console.WriteLine("Choose file:"); // Prompt Console.WriteLine("1 - tinyEWD.txt"); // Prompt Console.WriteLine("2 - mediumEWD.txt"); // Prompt //Console.WriteLine("3 - mediumEWG.txt"); // Prompt Console.WriteLine("or quit"); // Prompt var fileNumber = Console.ReadLine(); string fileName; switch (fileNumber) { case "1": fileName = "tinyEWD.txt"; break; case "2": fileName = "mediumEWD.txt"; break; //case "3": // fileName = "largeEWG.zip"; // break; case "quit": return; default: return; } var @in = new In($"Files\\Graphs\\{fileName}"); var lines = @in.ReadAllLines(); var lineIterator = 0; var v = 0; var e = 0; var edges = new List<DirectedEdge>(); foreach (var line in lines) { if (lineIterator == 0) { v = Convert.ToInt32(line); } if (lineIterator == 1) { e = Convert.ToInt32(line); } if (lineIterator > 1) { var lineSplitted = line.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries); var ve = Convert.ToInt32(lineSplitted[0]); var we = Convert.ToInt32(lineSplitted[1]); var weight = Convert.ToDouble(lineSplitted[2], CultureInfo.InvariantCulture); var edge = new DirectedEdge(ve, we, weight); edges.Add(edge); } lineIterator++; } var adjMatrixEdgeWeightedDigraph = new AdjMatrixEdgeWeightedDigraph(v, e, edges); Console.WriteLine(adjMatrixEdgeWeightedDigraph); // run Floyd-Warshall algorithm var spt = new FloydWarshall(adjMatrixEdgeWeightedDigraph); // print all-pairs shortest path distances Console.Write(" "); for (var vv = 0; vv < adjMatrixEdgeWeightedDigraph.V; vv++) { Console.Write($"{vv} "); } Console.WriteLine(); for (var vv = 0; vv < adjMatrixEdgeWeightedDigraph.V; vv++) { Console.Write($"{vv}: "); for (var w = 0; w < adjMatrixEdgeWeightedDigraph.V; w++) { Console.Write(spt.HasPath(vv, w) ? $"{spt.Dist(vv, w):00} " : " Inf "); } Console.WriteLine(); } // print negative cycle if (spt.HasNegativeCycle) { Console.WriteLine("Negative cost cycle:"); foreach (var edge in spt.NegativeCycle()) Console.WriteLine(edge); Console.WriteLine(); } // print all-pairs shortest paths else { for (var vv = 0; vv < adjMatrixEdgeWeightedDigraph.V; vv++) { for (var w = 0; w < adjMatrixEdgeWeightedDigraph.V; w++) { if (spt.HasPath(vv, w)) { Console.Write($"{vv} to {w} {spt.Dist(vv, w):00} "); foreach (var edge in spt.Path(vv, w)) Console.Write($"{edge} "); Console.WriteLine(); } else { Console.Write($"{vv} to {w} no path{Environment.NewLine}"); } } } } Console.ReadLine(); }
private readonly DirectedEdge[][] _edgeTo; // edgeTo[v][w] = last edge on shortest v->w path #endregion Fields #region Constructors /// <summary> /// Computes a shortest paths tree from each vertex to to every other vertex in /// the edge-weighted digraph <tt>G</tt>. If no such shortest path exists for /// some pair of vertices, it computes a negative cycle. /// </summary> /// <param name="g">G the edge-weighted digraph</param> public FloydWarshall(AdjMatrixEdgeWeightedDigraph g) { var vv = g.V; _distTo = new double[vv][]; for (var i = 0; i < vv; i++) { _distTo[i] = new double[vv]; } _edgeTo = new DirectedEdge[vv][]; for (var i = 0; i < vv; i++) { _edgeTo[i] = new DirectedEdge[vv]; } // initialize distances to infinity for (var v = 0; v < vv; v++) { for (var w = 0; w < vv; w++) { _distTo[v][w] = double.PositiveInfinity; } } // initialize distances using edge-weighted digraph's for (var v = 0; v < g.V; v++) { foreach (var e in g.Adj(v)) { _distTo[e.From()][e.To()] = e.Weight; _edgeTo[e.From()][e.To()] = e; } // in case of self-loops if (_distTo[v][v] >= 0.0) { _distTo[v][v] = 0.0; _edgeTo[v][v] = null; } } // Floyd-Warshall updates for (var i = 0; i < vv; i++) { // compute shortest paths using only 0, 1, ..., i as intermediate vertices for (var v = 0; v < vv; v++) { if (_edgeTo[v][i] == null) continue; // optimization for (var w = 0; w < vv; w++) { if (_distTo[v][w] > _distTo[v][i] + _distTo[i][w]) { _distTo[v][w] = _distTo[v][i] + _distTo[i][w]; _edgeTo[v][w] = _edgeTo[i][w]; } } // check for negative cycle if (_distTo[v][v] < 0.0) { HasNegativeCycle = true; return; } } } }
private readonly DirectedEdge[][] _edgeTo; // edgeTo[v][w] = last edge on shortest v->w path /// <summary> /// Computes a shortest paths tree from each vertex to to every other vertex in /// the edge-weighted digraph <tt>G</tt>. If no such shortest path exists for /// some pair of vertices, it computes a negative cycle. /// </summary> /// <param name="g">G the edge-weighted digraph</param> public FloydWarshall(AdjMatrixEdgeWeightedDigraph g) { var vv = g.V; _distTo = new double[vv][]; for (var i = 0; i < vv; i++) { _distTo[i] = new double[vv]; } _edgeTo = new DirectedEdge[vv][]; for (var i = 0; i < vv; i++) { _edgeTo[i] = new DirectedEdge[vv]; } // initialize distances to infinity for (var v = 0; v < vv; v++) { for (var w = 0; w < vv; w++) { _distTo[v][w] = double.PositiveInfinity; } } // initialize distances using edge-weighted digraph's for (var v = 0; v < g.V; v++) { foreach (var e in g.Adj(v)) { _distTo[e.From()][e.To()] = e.Weight; _edgeTo[e.From()][e.To()] = e; } // in case of self-loops if (_distTo[v][v] >= 0.0) { _distTo[v][v] = 0.0; _edgeTo[v][v] = null; } } // Floyd-Warshall updates for (var i = 0; i < vv; i++) { // compute shortest paths using only 0, 1, ..., i as intermediate vertices for (var v = 0; v < vv; v++) { if (_edgeTo[v][i] == null) { continue; // optimization } for (var w = 0; w < vv; w++) { if (_distTo[v][w] > _distTo[v][i] + _distTo[i][w]) { _distTo[v][w] = _distTo[v][i] + _distTo[i][w]; _edgeTo[v][w] = _edgeTo[i][w]; } } // check for negative cycle if (_distTo[v][v] < 0.0) { HasNegativeCycle = true; return; } } } }
public void Run() { Console.WriteLine("Choose file:"); // Prompt Console.WriteLine("1 - tinyEWD.txt"); // Prompt Console.WriteLine("2 - mediumEWD.txt"); // Prompt //Console.WriteLine("3 - mediumEWG.txt"); // Prompt Console.WriteLine("or quit"); // Prompt var fileNumber = Console.ReadLine(); string fileName; switch (fileNumber) { case "1": fileName = "tinyEWD.txt"; break; case "2": fileName = "mediumEWD.txt"; break; //case "3": // fileName = "largeEWG.zip"; // break; case "quit": return; default: return; } var @in = new In($"Files\\Graphs\\{fileName}"); var lines = @in.ReadAllLines(); var lineIterator = 0; var v = 0; var e = 0; var edges = new List<DirectedEdge>(); foreach (var line in lines) { if (lineIterator == 0) { v = Convert.ToInt32(line); } if (lineIterator == 1) { e = Convert.ToInt32(line); } if (lineIterator > 1) { var lineSplitted = line.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries); var ve = Convert.ToInt32(lineSplitted[0]); var we = Convert.ToInt32(lineSplitted[1]); var weight = Convert.ToDouble(lineSplitted[2], CultureInfo.InvariantCulture); var edge = new DirectedEdge(ve, we, weight); edges.Add(edge); } lineIterator++; } var adjMatrixEdgeWeightedDigraph = new AdjMatrixEdgeWeightedDigraph(v, e, edges); Console.WriteLine(adjMatrixEdgeWeightedDigraph); Console.ReadLine(); }