穷举法解决TSP问题

一、问题描述

TSP问题(Travelling Salesman Problem)即旅行商问题,是NP-hard的经典问题之一。可描述为:一销售商从n个城市中的某一城市出发,不重复地走完其余n—1个城市并回到原出发点,在所有可能的路径中求出路径长度最短的一条。本题假定该旅行商从第1个城市出发。

二、算法说明

这里我们尝试用穷举法解决TSP问题。即将每一个城市编号为0~n-1,通过生成随机数种子的方法生成城市之间的代价,调用next_permutation()函数生成城市编号的全排列,然后计算每种排列的代价,选取代价最小的路径输出。

三、源码示例

#include<iostream>
#include<vector>
#include<algorithm>
#include<chrono>
#include<random>
using namespace std;
#define MAX_DOUBLE_NUM 1e20
typedef vector<vector<int>> VVT;  //定义代价矩阵的数据结构
unsigned seed1 = std::chrono::high_resolution_clock::now()
                 .time_since_epoch().count();
std::mt19937 mt(seed1); //生成随机数种子

//城市个数n,代价矩阵c
//旅行路线tpath[],最小费用min
void salesman_problem(int n, double &min, int path[], VVT c) {
	int *p=new int [n];
	int i = 1;
	double cost;
	for (i = 0; i < n; i++)
		p[i] = i;
	min = MAX_DOUBLE_NUM;
	for (i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
		{
			c[i][j] = 100 + mt() % 100;
			if(i!=j)
			   cout << i << "城市和" << j << "城市之间的代价:" << c[i][j] << endl;
		}
	do{
		//产生n个城市的全排列
		cost = 0;// 最优解路径的代价
		for (i = 0; i < n - 1; i++) 
			cost += c[p[i]][p[i + 1]];
		cost += c[p[n - 1]][p[0]];
   
		if (cost < min) {//若当前路径的代价比cost小,保留当前路径并更新cost
			for (i = 0; i < n; i++) 
				path[i] = p[i];
			min = cost;
		}
	} while (next_permutation(p+1, p + n));
}
int main() {
	int n,path[100];
	double mincost;
	VVT c(10, vector<int>(10));
	cout << "********************************************************************************" << endl;
	cout << "***程序说明:输入城市数目(请尽可能小),程序随机生成城市之间代价并输出最优解***" << endl;
	cout << "********************************************************************************" << endl;
	cout << "输入城市数目:" << endl;
	cin >> n;
	salesman_problem(n, mincost, path, c);
	cout << "最小代价:"<<mincost << endl;
	cout << "最优路径:" << endl;
	for (int i = 0; i < n; i++)
		cout << path[i] << "-->";
	cout << path[0] << endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值