예제 #1
0
        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();
        }
예제 #2
0
        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;
                    }
                }
            }
        }
예제 #3
0
        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();
        }