算法-动态规划2图问题-TSP问题

算法-动态规划2-TSP问题

问题:
旅行家要旅行n个城市,要求各个城市经历且仅经历一次然后回到出发城市,并要求所走的路程最短。
在这里插入图片描述
设s, s1, s2, …, sp, s是从s出发的一条路径长度最短的简单回路,假设从s到下一个城市s1已经求出,则问题转化为求从s1到s的最短路径,显然s1, s2, …, sp, s一定构成一条从s1到s的最短路径,所以TSP问题是构成最优子结构性质的,用动态规划来求解也是合理的。

在这里插入图片描述

在这里插入图片描述
代码:

#include <iostream>
#include <stdio.h>
#include<iomanip>
using namespace std;

int dis[12][12], d[12][1 << 11];//距离地图表,d函数表,d[]为动态规划存储的城市经过矩阵

int main()
{
	int n, temp, minDis;
	//给距离地图表赋值
		cin >> n;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			scanf_s("%d", &dis[i][j]);
		}
	}

	//给d函数表赋值
	for (int i = 1; i < n; i++) {     //将所有城市到第0个城市的路径初始化为两市间的距离
		d[i][0] = dis[i][0];
	}
	//除了第0行以外的其余
	for (int j = 1; j < (1 << (n - 1)); j++) {//j用二进制表示的城市集合,先说j再说i,动态规划从j的底层到上层,j数值越来越大
		for (int i = 1; i < n; i++) {
			//i不在j表示的城市集合中,可以对d[i][j]赋值,否则赋0;
			if (((1 << (i - 1)) & j) == 0) {
				//temp=dis[i][k]+d[k][V-{k}]开始对V中所有的k进行遍历
				int minDis = 60000;
				for (int k = 1; k < n; k++) {
					if ((1 << (k - 1)) & j) {//k表示的城市在j表示的城市集合中 
						temp = dis[i][k] + d[k][j - (1 << (k - 1))];
						if (temp < minDis) {//d(1,{2,3})=min{ C12+d(2,{3})||C13+d(3,{2})}
							minDis = temp;   //所有k中最小的距离
							d[i][j] = minDis;//给d函数表每个位置赋值
						}
					}
				}
			}

		}
	}
	//对第0行最后一个d(0,{123})赋值,d(0,{1,2,3})=min {C01+d(1,{2,3})|| C02+d{2,{1,3}}||C03+d{3,{1,2}})
	minDis = 600;
	for (int k = 1; k < n; k++) {
		temp = dis[0][k] + d[k][((1 << (n - 1)) - 1) - (1 << (k - 1))];//d[k][{123}-{k}]
		if (minDis > temp) {
			minDis = temp;
			d[0][(1 << (n - 1)) - 1] = minDis;
		}
	}
	//此部分可以输出看看形成的d[][]矩阵,便于理解执行过程
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < (1 << (n - 1)); j++) {
			cout << d[i][j] << "  ";
		}
		cout << endl;
	}

	/*cout << d[0][(1 << (n - 1)) - 1];*/


	return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值