穷举法解决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;
}
  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言中可以使用穷举法解决旅行商问题。穷举法是一种暴力搜索的方法,它通过遍历所有可能的路径来找到最小成本的回路。 以下是一个使用穷举法解决旅行商问题的C语言代码示例: ```c #include <stdio.h> #include <limits.h> #define N 4 // 城市数量 int graph[N][N] = { // 城市之间的距离矩阵 {0, 10, 15, 20}, {10, 0, 35, 25}, {15, 35, 0, 30}, {20, 25, 30, 0} }; int visited[N]; // 记录城市是否被访问过 int minCost = INT_MAX; // 最小成本 void tsp(int currentCity, int visitedCities, int cost, int count) { if (count == N && graph[currentCity][0] != 0) { // 所有城市都已经访问过且返回起始城市 cost += graph[currentCity][0]; // 加上返回起始城市的距离 if (cost < minCost) { minCost = cost; // 更新最小成本 } return; } for (int i = 0; i < N; i++) { if (!visited[i] && graph[currentCity][i] != 0) { // 如果城市未被访问过且与当前城市相连 visited[i] = 1; // 标记城市为已访问 tsp(i, visitedCities + 1, cost + graph[currentCity][i], count + 1); // 递归访问下一个城市 visited[i] = 0; // 回溯,将城市标记为未访问 } } } int main() { visited[0] = 1; // 起始城市标记为已访问 tsp(0, 1, 0, 1); // 从起始城市开始递归搜索 printf("最小成本的回路路径成本为:%d\n", minCost); return 0; } ``` 这段代码使用了一个邻接矩阵来表示城市之间的距离,通过递归的方式遍历所有可能的路径,并记录最小成本的回路路径成本。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值