# include # include # include # include # include # include "tsp_att48.h" int main ( ); void tsp_display ( char *prefix, int n, double *x2 ); double tsp_tour_cost ( int n, double *x, int *order ); void timestamp ( ); /******************************************************************************/ int main ( ) /******************************************************************************/ /* Purpose: tsp_att48_test() tests tsp_att48(). Licensing: This code is distributed under the MIT license. Modified: 26 July 2026 Author: John Burkardt */ { double cost; int *att48_order; double *att48_xy; int i; int i2; int n; double *x2; timestamp ( ); printf ( "\n" ); printf ( "tsp_att48_test():\n" ); printf ( " C version\n" ); printf ( " Test tsp_att48(), which returns the AT&T 48 city\n" ); printf ( " traveling salesperson problem challenge data.\n" ); n = 48; att48_order = tsp_att48_order ( ); att48_xy = tsp_att48_xy ( ); printf ( "\n" ); printf ( " City coordinates:\n" ); printf ( "\n" ); for ( i = 0; i < n; i++ ) { printf ( " %2d %8g %8g\n", i, att48_xy[2*i], att48_xy[2*i+1] ); } /* Report the minimal cost. */ cost = tsp_tour_cost ( n, att48_xy, att48_order ); printf ( "\n" ); printf ( " Cost of shortest round trip is %g\n", cost ); /* Copy the city locations in TSP order. */ x2 = ( double * ) malloc ( ( n + 1 ) * 2 * sizeof ( double ) ); for ( i2 = 0; i2 <= n; i2++ ) { if ( i2 < n ) { i = att48_order[i2]; } else { i = att48_order[0]; } x2[2*i2] = att48_xy[2*i]; x2[2*i2+1] = att48_xy[2*i+1]; } /* Display the locations. */ tsp_display ( "att48", n + 1, x2 ); /* Free memory. */ free ( att48_order ); free ( att48_xy ); free ( x2 ); /* Terminate. */ printf ( "\n" ); printf ( "tsp_att48_test():\n" ); printf ( " Normal end of execution.\n" ); timestamp ( ); return 0; } /******************************************************************************/ void tsp_display ( char *prefix, int n, double *x2 ) /******************************************************************************/ /* Purpose: tsp_display() plots cities and a tour connecting them. Discussion: If a "round trip" is desired, then the x2 array must repeat the first city at the end. Licensing: This code is distributed under the MIT license. Modified: 12 June 2026 Author: John Burkardt Input: char *prefix: a string that defines the name of the problem. It is also used to create file names needed for input to gnuplot. int n: the number of cities. double x[n*2]: the x and y coordinates of the cities. */ { char command_filename[80]; FILE *command; FILE *data; char data_filename[80]; int i; /* Create the data file. */ strcpy ( data_filename, prefix ); strcat ( data_filename, "_data.txt" ); data = fopen ( data_filename, "wt" ); for ( i = 0; i < n; i++ ) { fprintf ( data, "%14.6g %14.6g\n", x2[2*i], x2[2*i+1] ); } fclose ( data ); printf ( " Created data file '%s'\n", data_filename ); /* Create the command file. */ strcpy ( command_filename, prefix ); strcat ( command_filename, "_commands.txt" ); command = fopen ( command_filename, "wt" ); fprintf ( command, "# %s\n", command_filename ); fprintf ( command, "#\n" ); fprintf ( command, "# Usage:\n" ); fprintf ( command, "# gnuplot < %s\n", command_filename ); fprintf ( command, "#\n" ); fprintf ( command, "set term png\n" ); fprintf ( command, "set output '%s.png'\n", prefix ); fprintf ( command, "set xlabel '<--- X --->'\n" ); fprintf ( command, "set ylabel '<--- Y --->'\n" ); fprintf ( command, "set title '%s'\n", prefix ); fprintf ( command, "set grid\n" ); fprintf ( command, "unset key\n" ); fprintf ( command, "set style data lines\n" ); fprintf ( command, "plot '%s' using 1:2 lw 3 linecolor rgb 'blue', \\\n", data_filename ); fprintf ( command, " '%s' using 1:2 with points pointtype 7 pointsize 3 linecolor rgb 'green'\n", data_filename ); fprintf ( command, "quit\n" ); fclose ( command ); printf ( " Created command file '%s'\n", command_filename ); return; } /******************************************************************************/ double tsp_tour_cost ( int n, double *x, int *order ) /******************************************************************************/ /* Purpose: tsp_tour_cost() evaluates the cost of a round trip. Licensing: This code is distributed under the MIT license. Modified: 18 June 2026 Author: John Burkardt Input: int n: the number of cities. double x[n,2]: the city locations. int order[n]: the order in which the cities are visited. Output: double cost: the cost of the route. */ { double cost; int from; int to; cost = 0.0; from = n - 1; for ( to = 0; to < n; to++ ) { cost = cost + sqrt ( pow ( x[order[from]*2] - x[order[to]*2], 2 ) + pow ( x[order[from]*2+1] - x[order[to]*2+1], 2 ) ); from = to; } return cost; } /******************************************************************************/ void timestamp ( ) /******************************************************************************/ /* Purpose: timestamp() prints the current YMDHMS date as a time stamp. Example: 17 June 2014 09:45:54 AM Licensing: This code is distributed under the MIT license. Modified: 01 May 2021 Author: John Burkardt */ { # define TIME_SIZE 40 static char time_buffer[TIME_SIZE]; const struct tm *tm; time_t now; now = time ( NULL ); tm = localtime ( &now ); strftime ( time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm ); printf ( "%s\n", time_buffer ); return; # undef TIME_SIZE }