# include # include # include # include # include using namespace std; # include "floyd.hpp" //****************************************************************************80 int i4_huge ( ) //****************************************************************************80 // // Purpose: // // i4_huge() returns a "huge" I4. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 16 May 2003 // // Author: // // John Burkardt // // Parameters: // // Output, int I4_HUGE, a "huge" I4. // { return 2147483647; } //****************************************************************************80 void i4mat_floyd ( int n, int a[] ) //****************************************************************************80 // // Purpose: // // i4mat_floyd(): shortest distances between pairs of nodes in a directed graph. // // Discussion: // // We assume we are given the adjacency matrix A of the directed graph. // // We assume that A is an I4MAT, that is, a two-dimensional array of I4's. /// // The adjacency matrix is NOT assumed to be symmetric. // // If there is not a direct link from node I to node J, the distance // would formally be infinity. We assume that such distances are assigned // some large value. For technical reasons, this number should be no // greater than 2147483647/2 so that the "infinity+infinity" does not // suddenly become a negative value! // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 02 March 2014 // // Author: // // John Burkardt // // Parameters: // // Input, int N, the order of the matrix. // // Input/output, int A[N*N]. // On input, A(I,J) contains the direct distance from node I to node J. // On output, A(I,J) contains the shortest distance from node I to node J. // An input entry of -1 means there is no direct route from node I to node J. // An output entry of -1 means there // { int i; const int i4_huge = 2147483647; int j; int k; for ( k = 0; k < n; k++ ) { for ( j = 0; j < n; j++ ) { if ( a[k+j*n] < i4_huge ) { for ( i = 0; i < n; i++ ) { if ( a[i+k*n] < i4_huge ) { a[i+j*n] = min ( a[i+j*n], a[i+k*n] + a[k+j*n] ); } } } } } return; } //****************************************************************************80 void i4mat_print ( int m, int n, int a[], string title ) //****************************************************************************80 // // Purpose: // // i4mat_print() prints an I4MAT, with an optional title. // // Discussion: // // An I4MAT is an MxN array of I4's, stored by (I,J) -> [I+J*M]. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 30 April 2003 // // Author: // // John Burkardt // // Parameters: // // Input, int M, the number of rows in A. // // Input, int N, the number of columns in A. // // Input, int A[M*N], the M by N matrix. // // Input, string TITLE, a title. // { i4mat_print_some ( m, n, a, 1, 1, m, n, title ); return; } //****************************************************************************80 void i4mat_print_some ( int m, int n, int a[], int ilo, int jlo, int ihi, int jhi, string title ) //****************************************************************************80 // // Purpose: // // i4mat_print_some() prints some of an I4MAT. // // Discussion: // // An I4MAT is an MxN array of I4's, stored by (I,J) -> [I+J*M]. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 14 June 2005 // // Author: // // John Burkardt // // Parameters: // // Input, int M, the number of rows of the matrix. // M must be positive. // // Input, int N, the number of columns of the matrix. // N must be positive. // // Input, int A[M*N], the matrix. // // Input, int ILO, JLO, IHI, JHI, designate the first row and // column, and the last row and column to be printed. // // Input, string TITLE, a title. // { # define INCX 10 int i; int i2hi; int i2lo; int j; int j2hi; int j2lo; cout << "\n"; cout << title << "\n"; // // Print the columns of the matrix, in strips of INCX. // for ( j2lo = jlo; j2lo <= jhi; j2lo = j2lo + INCX ) { j2hi = j2lo + INCX - 1; j2hi = min ( j2hi, n ); j2hi = min ( j2hi, jhi ); cout << "\n"; // // For each column J in the current range... // // Write the header. // cout << " Col:"; for ( j = j2lo; j <= j2hi; j++ ) { cout << " " << setw(6) << j; } cout << "\n"; cout << " Row\n"; cout << "\n"; // // Determine the range of the rows in this strip. // i2lo = max ( ilo, 1 ); i2hi = min ( ihi, m ); for ( i = i2lo; i <= i2hi; i++ ) { // // Print out (up to INCX) entries in row I, that lie in the current strip. // cout << setw(5) << i; for ( j = j2lo; j <= j2hi; j++ ) { cout << " " << setw(6) << a[i-1+(j-1)*m]; } cout << "\n"; } } cout << "\n"; return; # undef INCX } //****************************************************************************80 void r8mat_floyd ( int n, double a[] ) //****************************************************************************80 // // Purpose: // // r8mat_floyd(): shortest distance between pairs of nodes in a directed graph. // // Discussion: // // We assume we are given the adjacency matrix A of the directed graph. // // We assume that A is an R8MAT, that is, a two-dimensional array of R8's. // // The adjacency matrix is NOT assumed to be symmetric. // // If there is not a direct link from node I to node J, the distance // would formally be infinity. We assume that such distances are assigned // the value HUGE_VAL. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 02 March 2014 // // Author: // // John Burkardt // // Parameters: // // Input, int N, the order of the matrix. // // Input/output, double A[N*N]. // On input, A(I,J) contains the direct distance from node I to node J. // On output, A(I,J) contains the shortest distance from node I to node J. // { int i; int j; int k; for ( k = 0; k < n; k++ ) { for ( j = 0; j < n; j++ ) { if ( a[k+j*n] < HUGE_VAL ) { for ( i = 0; i < n; i++ ) { if ( a[i+k*n] < HUGE_VAL ) { a[i+j*n] = fmin ( a[i+j*n], a[i+k*n] + a[k+j*n] ); } } } } } return; } //****************************************************************************80 void r8mat_print ( int m, int n, double a[], string title ) //****************************************************************************80 // // Purpose: // // r8mat_print() prints an R8MAT, with an optional title. // // Discussion: // // An R8MAT is a doubly dimensioned array of R8 values, stored as a vector // in column-major order. // // Entry A(I,J) is stored as A[I+J*M] // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 29 August 2003 // // Author: // // John Burkardt // // Parameters: // // Input, int M, the number of rows in A. // // Input, int N, the number of columns in A. // // Input, double A[M*N], the M by N matrix. // // Input, string TITLE, a title. // { r8mat_print_some ( m, n, a, 1, 1, m, n, title ); return; } //****************************************************************************80 void r8mat_print_some ( int m, int n, double a[], int ilo, int jlo, int ihi, int jhi, string title ) //****************************************************************************80 // // Purpose: // // r8mat_print_some() prints some of an R8MAT. // // Discussion: // // An R8MAT is a doubly dimensioned array of R8 values, stored as a vector // in column-major order. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 09 April 2004 // // Author: // // John Burkardt // // Parameters: // // Input, int M, the number of rows of the matrix. // M must be positive. // // Input, int N, the number of columns of the matrix. // N must be positive. // // Input, double A[M*N], the matrix. // // Input, int ILO, JLO, IHI, JHI, designate the first row and // column, and the last row and column to be printed. // // Input, string TITLE, a title. // { # define INCX 5 int i; int i2hi; int i2lo; int j; int j2hi; int j2lo; cout << "\n"; cout << title << "\n"; // // Print the columns of the matrix, in strips of 5. // for ( j2lo = jlo; j2lo <= jhi; j2lo = j2lo + INCX ) { j2hi = j2lo + INCX - 1; j2hi = min ( j2hi, n ); j2hi = min ( j2hi, jhi ); cout << "\n"; // // For each column J in the current range... // // Write the header. // cout << " Col: "; for ( j = j2lo; j <= j2hi; j++ ) { cout << setw(7) << j << " "; } cout << "\n"; cout << " Row\n"; cout << "\n"; // // Determine the range of the rows in this strip. // i2lo = max ( ilo, 1 ); i2hi = min ( ihi, m ); for ( i = i2lo; i <= i2hi; i++ ) { // // Print out (up to) 5 entries in row I, that lie in the current strip. // cout << setw(5) << i << " "; for ( j = j2lo; j <= j2hi; j++ ) { cout << setw(12) << a[i-1+(j-1)*m] << " "; } cout << "\n"; } } return; # undef INCX } //****************************************************************************80 double r8vec_diff_norm ( int n, double a[], double b[] ) //****************************************************************************80 // // Purpose: // // r8vec_diff_norm() returns the L2 norm of the difference of R8VEC's. // // Discussion: // // An R8VEC is a vector of R8's. // // The vector L2 norm is defined as: // // R8VEC_NORM_L2 = sqrt ( sum ( 1 <= I <= N ) A(I)^2 ). // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 24 June 2011 // // Author: // // John Burkardt // // Parameters: // // Input, int N, the number of entries in A. // // Input, double A[N], B[N], the vectors. // // Output, double R8VEC_DIFF_NORM, the L2 norm of A - B. // { int i; double value; value = 0.0; for ( i = 0; i < n; i++ ) { value = value + ( a[i] - b[i] ) * ( a[i] - b[i] ); } value = sqrt ( value ); return value; }