tsp的动态规划实现,最短长度和最短路径

#include "stdio.h"
#include "string.h"
#define INF 999999999
typedef struct _node 
{
	int value;      //indicate the value of the minimum distance of the state in this phase.
	int min_index;  //keep trace of the index which is just before this node
}node;


node table[40][6];
int bit[6];
int n = 6;
int path[5];
int dis[6][6] = 
{
	0, 10, 20, 30, 40, 50,
	12, 0 ,18, 30, 25, 21,
	23, 19, 0, 5,  10, 15,
	34, 32, 4, 0,  8,  16,
	45, 27, 11,10, 0,  18,
	56, 22, 16,20, 12,  0
};


int  init(){
	int i;
	int j;
	int t;
	memset( table, -1, sizeof(table) );
	for( i = 0; i < n; i++ )
	{
		bit[i] = 1<<i;
	}
	t = 1;
	for( i = 1; i < n; i++ )
	{
		table[ t<<( i - 1 ) ][i].value = dis[0][i];
	}
	return 1;
}




int getTable(int s,int k)
{
	int t,tt;
	int i;
	int min = INF;
	if(table[s][k].value != -1)
	{
		return table[s][k].value;
	}
	t = s & (~bit[k - 1]);
	for(i = 1; i < n; i++)
	{
		tt=t & bit[i-1];
		if(tt > 0){
			if(getTable(t, i) + dis[i][k] < min)
			{
				min = getTable(t, i) + dis[i][k];
				table[s][k].min_index = i;
			}
		}
	}
	table[s][k].value = min;
	return table[s][k].value;
}
int main(){
	int i;
	int t;
	int ret;
	t=0;
	int set;
	ret=INF;
	init();
	for(i = 1; i < n; i++)
	{
		t = t<<1;
		t = t|1;
	}
	set = t;
	for(i = 1; i < n; i++)
	{
		if(getTable(t,i)+dis[i][0]<ret)
		{
			ret=getTable(t,i)+dis[i][0];
			path[4] = i;
			
		}
	}
  
	for (int i = 4;i > 0;i--)
	{
		int index = table[set][path[i]].min_index;
		path[i - 1] = index;
		set = set & (~bit[path[i] - 1]);
	}
    printf("the intermediate vertice are :\n");
	for(int i = 0; i < 5;++i)
	{
		printf("%d ",path[i] + 1);
	}


	printf("\nthe minimum distance is :\n%d\n",ret);
	
	getchar();
	return 1;
}

主体代码转自http://blog.sina.com.cn/s/blog_48f85e1d0100qz58.html
记c(s,k)状态为从v0,遍历了S中所有的节点,最后停在K点的所有路径的最小值,那么状态转移方程为:
c(s,k)=min(c(s-{vk},vi)+g[vi][k])~~~~~~vi属于s-{vk}
初始状态很明显,就是c(ti,i)=g[0][i],ti表示只含有v0一个元素的集合.

具体实现是用二进制位来表示节点是否在集合中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值