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