Esempio n. 1
0
        /// <summary>
        /// Computes all shortest distance between any vertices in a given graph.
        /// </summary>
        /// <param name="adjacence_matrix">Square adjacence matrix. The main diagonal
        /// is expected to consist of zeros, any non-existing edges should be marked
        /// positive infinity.</param>
        /// <returns>Two matrices D and P, where D[u,v] holds the distance of the shortest
        /// path between u and v, and P[u,v] holds the shortcut vertex on the way from
        /// u to v.</returns>
        public static ArrayMatrix[] Floyd(ArrayMatrix adjacence_matrix)
        {
            if (!adjacence_matrix.IsSquare()) throw new ArgumentException("Expected square matrix.");
            else if (!adjacence_matrix.IsReal()) throw new ArgumentException("Adjacence matrices are expected to be real.");

            var n = adjacence_matrix.RowCount;

            var D = adjacence_matrix.Clone(); // distance matrix
            var P = new ArrayMatrix(n);

            double buf;

            for (var k = 1; k <= n; k++)
                for (var i = 1; i <= n; i++)
                    for (var j = 1; j <= n; j++)
                    {
                        buf = D[i, k].Real + D[k, j].Real;
                        if (buf < D[i, j].Real)
                        {
                            D[i, j].Real = buf;
                            P[i, j].Real = k;
                        }
                    }

            return new ArrayMatrix[] {D, P};
        }
Esempio n. 2
0
        /// <summary>
        /// For this matrix A, this method solves Ax = b via LU factorization with
        /// column pivoting.
        /// </summary>
        /// <param name="b">Vector of appropriate length.</param>
        /// <remarks>Approximately n^3/3 + 2n^2 dot operations ~> O(n^3)</remarks>
        public static ArrayMatrix Solve(ArrayMatrix A, ArrayMatrix b)
        {
            var A2 = A.Clone();
            var b2 = b.Clone();

            if (!A2.IsSquare()) throw new InvalidOperationException("Cannot uniquely solve non-square equation system.");

            var n = A2.RowCount;

            var P = A2.LUSafe();

            // We know: PA = LU => [ Ax = b <=> P'LUx = b <=> L(Ux) = (Pb)] since P is orthogonal
            // set y := Ux, solve Ly = Pb by forward insertion
            // and Ux = y by backward insertion

            b2 = P*b2;

            // this solves Ly = Pb
            (A2.ExtractLowerTrapeze() - Diag(A2.DiagVector()) + Identity(n)).ForwardInsertion(b2);

            // this solves Ux = y
            (A2.ExtractUpperTrapeze()).BackwardInsertion(b2);

            return b2;
        }