1. 程式人生 > >回溯法-旅行售貨員問題(C語言)

回溯法-旅行售貨員問題(C語言)

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");  
}