回溯法-旅行售貨員問題(C語言)
阿新 • • 發佈:2019-02-17
1、旅行員售貨問題
問題描述
某售貨員要到若干城市去推銷商品,已知各城市之間的路程(旅費),他要選定一條從駐地出發,經過每個城市一遍,最後回到駐地的路線,使總的路程(總旅費)最小。(必須從1號店出發,最後回到出發地)
#include <stdio.h> #define N 4 //城市數目 #define NO_PATH -1 //沒有通路 #define MAX_WEIGHT 4000 int City_Graph[N+1][N+1]; //儲存圖資訊 int x[N+1]; //x[i]儲存第i步遍歷的城市 int isIn[N+1]; //儲存 城市i是否已經加入路徑 int bestw; //最優路徑總權值 int cw; //當前路徑總權值 int bw; //深度搜索完成總權值 int bestx[N+1]; //最優路徑 //----------------------------------------------------------------- void Travel_Backtrack(int t) { //遞迴法 int i,j; if(t>N) { //走完了,輸出結果 for(i=1;i<=N;i++) //輸出當前的路徑 printf("%d ",x[i]); printf("\n"); bw = cw + City_Graph[x[N]][1]; //計算總權值(非最優) if(bw < bestw) //挑選出最優總權值 { //判斷當前路徑是否是更優解 for (i=1;i<=N;i++) { bestx[i] = x[i]; } bestw = bw; } return; } else { for(j=2;j<=N;j++)//因為出發點為1號,所以後面回溯時1號不滿足後面的if條件 { //找到第t步能走的城市 if(City_Graph[x[t-1]][j] != NO_PATH && !isIn[j] /*&& cw<bestw*/)//剪枝條件:可達且未加入到路徑中且當前總權值小於最優權值 { isIn[j] = 1; x[t] = j; cw += City_Graph[x[t-1]][j]; Travel_Backtrack(t+1); isIn[j] = 0; x[t] = 0; cw -= City_Graph[x[t-1]][j]; } } } } void main() { int i; //建立圖(鄰接矩陣) /* 0 30 6 4 30 0 5 10 6 5 0 20 4 10 20 0 */ City_Graph[1][1] = NO_PATH; City_Graph[1][2] = 30; City_Graph[1][3] = 6; City_Graph[1][4] = 4; City_Graph[2][1] = 30; City_Graph[2][2] = NO_PATH; City_Graph[2][3] = 5; City_Graph[2][4] = 10; City_Graph[3][1] = 6; City_Graph[3][2] = 5; City_Graph[3][3] = NO_PATH; City_Graph[3][4] = 20; City_Graph[4][1] = 4; City_Graph[4][2] = 10; City_Graph[4][3] = 20; City_Graph[4][4] = NO_PATH; //測試遞迴法,初始化 for (i=1;i<=N;i++) { x[i] = 0; //表示第i步還沒有解 bestx[i] = 0; //還沒有最優解 isIn[i] = 0; //表示第i個城市還沒有加入到路徑中 } x[1] = 1; //第一步 走城市1 isIn[1] = 1; //第一個城市 加入路徑 bestw = MAX_WEIGHT; cw = 0; Travel_Backtrack(2); //從第二步開始選擇城市 printf("最優值為%d\n",bestw); printf("最優解為:\n"); for(i=1;i<=N;i++) { printf("%d ",bestx[i]); } printf("\n"); }