#define MAX_CITY 100 /* 最大市の数 */ int tsp(int *spath, int *xcity, int *ycity, int ncity) { int slen = -1; /* 最短パスの距離 */ int tpath[MAX_CITY]; /* あるパス */ static int guess(); static void evaluate(); while (1) { if (guess(tpath, slen, xcity, ycity, ncity) == 1) /* パスを作り出す */ break; evaluate(&slen, spath, tpath, xcity, ycity, ncity); /* そのパスの距離を計算する */ } return slen; } /* 巡回パスを作り出す。あらゆる組合せを考える必要がある */ static int guess(int *tpath, int slen, int *xcity, int *ycity, int ncity) { int i, j, k; int tmp[MAX_CITY]; if (slen < 0) { for (i = 0; i < ncity; i++) tpath[i] = i; return 0; } for (i = ncity - 2; i >= 1; i--) { for (j = 0; j < ncity; j++) tmp[j] = j; for (j = 0; j <= i; j++) tmp[tpath[j]] = MAX_CITY; for (j = 0; j < ncity; j++) if (tmp[j] != MAX_CITY) if (tmp[j] > tpath[i]) { tpath[i] = tmp[j]; goto NEXT; } } return 1; /* 終了 */ NEXT: for (j = i+1; j < ncity; j++) { for (k = 0; k < ncity; k++) tmp[k] = k; for (k = 0; k < j; k++) tmp[tpath[k]] = MAX_CITY; for (k = 0; k < ncity; k++) if (tmp[k] != MAX_CITY) { tpath[j] = tmp[k]; break; } } return 0; } /* 巡回パスの距離を算出する */ static void evaluate(int *slen, int *spath, int *tpath, int *xcity, int *ycity, int ncity) { int i; int dx, dy; int tlen; /* パスの距離の計算 */ dx = xcity[tpath[0]] - xcity[tpath[ncity-1]]; dy = ycity[tpath[0]] - ycity[tpath[ncity-1]]; if (dx < 0) dx = -dx; if (dy < 0) dy = -dy; tlen = dx + dy; for (i = 1; i < ncity; i++) { dx = xcity[tpath[i]] - xcity[tpath[i-1]]; dy = ycity[tpath[i]] - ycity[tpath[i-1]]; if (dx < 0) dx = -dx; if (dy < 0) dy = -dy; tlen += dx + dy; } if (*slen < 0 || tlen < *slen) { /* 最短ならば... */ for (i = 0; i < ncity; i++) spath[i] = tpath[i]; *slen = tlen; } }