目录

  • 一、旅行商问题简介
    • 旅行商问题
    • 问题概述
    • 问题由来
  • 二、枚举所有方案
    • 1、思路
    • 2、代码
    • 3、复杂度分析
  • 三、深度优先搜索
    • 1、思路
    • 2、代码
    • 3、复杂度分析

一、旅行商问题简介

旅行商问题

  TSP,即旅行商问题,又称TSP问题(Traveling Salesman
Problem),是数学领域中著名问题之一。

问题概述

  假设有一个旅行商人要拜访N个城市,他必须选择所要走的路径,路径的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。路径的选择目标是要求得的路径路程为所有路径之中的最小值。TSP问题是一个NPC问题。

问题由来

  TSP的历史很久,最早的描述是1759年欧拉研究的骑士周游问题,即对于国际象棋棋盘中的64个方格,走访64个方格一次且仅一次,并且最终返回到起始点。

  TSP由美国RAND公司于1948年引入,该公司的声誉以及线形规划这一新方法的出现使得TSP成为一个知名且流行的问题。

示例:

黑色数字代表点、红色代表路径的花费

输入:

4 6
1 2 1
1 4 2
1 3 4
2 3 1
2 4 2
3 4 3

输出:

最短距离为:7
共2条最短路径:
1-->4-->3-->2-->1
1-->2-->3-->4-->1

提示:

第一行输入点的个数n和边的个数m,点的编号为1~n
接下来m行输入m条边以及花费,x y v,表示点x和点y之间有一条无向边,边的花费为v

二、枚举所有方案

1、思路

  我们只需要固定起点和终点,用全排列枚举中间点的排列,判断方案是否是最优的,如果是,则记录下来
  例如4个点,那么我们固定起点为0,终点为0,枚举1-3的全排列,判断每一种方案是否是最优的,选择性第保留或者抛弃
  4个点的方案有6个:
  0 1 2 3 0
  0 1 3 2 0
  0 2 1 3 0
  0 2 3 1 0
  0 3 1 2 0
  0 3 2 1 0

2、代码

#include<bits/stdc++.h>
using namespace std;
int n,m;//n点的个数,m边的个数
int a[15][15];//邻接矩阵存无向图
int p[15];
long long ans=0x3f3f3f3f;
vector<vector<int> > paths;void init(){//初始化 memset(a,0x3f,sizeof a);//初始化为一个足够大的值,代表不可达 for(int i=0;i<15;i++){p[i]=i;}cout<<"请输入点和边的个数:"<<endl;cin>>n>>m;p[0]=0;//起点为0 p[n]=0;//终点为0 cout<<"请输入"<<m<<"条边:"<<endl;for(int i=0;i<m;i++){int x,y,val; cin>>x>>y>>val;x--;y--;a[x][y]=val;a[y][x]=val;}
} long long check(){long long sum=0;for(int i=1;i<=n;i++){if(a[p[i-1]][p[i]]==0x3f3f3f3f){//如果该点不可达,那么就直接退出 return 0x3f3f3f3f;}sum+=a[p[i-1]][p[i]];}return sum;
}void print(){//打印路径 cout<<"最短距离为:"<<ans<<endl;cout<<"共"<<paths.size()<<"条最短路径:" <<endl; for(int i=0;i<paths.size();i++){for(int j=paths[i].size()-1;j>=0;j--){if(j<paths[i].size()-1){cout<<"-->";}cout<<paths[i][j]+1;}cout<<endl;}
}int main(){init();do{long long sum=check();if(sum<=ans){if(sum<ans){//如果有更优的解,那么就抛弃掉先去的路径 paths.clear();}ans=sum;vector<int> path;for(int i=0;i<=n;i++){path.push_back(p[i]);}paths.push_back(path);//添加当前的路径 }}while(next_permutation(p+1,p+n));//枚举1~n-1的全排列 if(ans==0x3f3f3f3f){cout<<"该图无解"<<endl;return 0; }print();
}

3、复杂度分析

  时间复杂度: 枚举全排列,对每一个排列做一次查询,时间复杂度为O(n*(n!))
  空间复杂度: 存储所有的最优的路径,空间复杂度为O(n*(n!))

三、深度优先搜索

1、思路

  我们从0点出发,深度优先搜索所有的路径,符合要求则记录下来

2、代码

#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[15][15];//邻接矩阵存无向图
long long ans=0x3f3f3f3f;//存储答案
vector<vector<int> > paths;//存储路径 void init(){//初始化 memset(a,0x3f,sizeof a);//初始化为一个足够大的值,代表不可达 cout<<"请输入点和边的个数:"<<endl;cin>>n>>m;cout<<"请输入"<<m<<"条边:"<<endl;for(int i=0;i<m;i++){int x,y,val; cin>>x>>y>>val;x--;y--;a[x][y]=val;a[y][x]=val;}
} long long sum=0;
vector<int> path(1,0);//存储实时的路径
int vis[15];//判断该点是否已经走过了
void dfs(int i){//i指的是目前在哪个点 if(i==0){//目前的点是终点int flag=1;for(int j=0;j<n;j++){//并且所有的点都走过一遍if(vis[j]==0)flag=0;}if(flag==1){if(sum<=ans){if(sum<ans){//如果有更优的解,则抛弃之前存储的路径 paths.clear();}ans=sum;paths.push_back(path);//存储当前路径 }return;}}for(int j=0;j<n;j++){//深搜+回溯 if(vis[j]==0){path.push_back(j); sum+=a[i][j];vis[j]=1;dfs(j);path.pop_back();sum-=a[i][j];vis[j]=0;}} }void print(){//打印路径 cout<<"最短距离为:"<<ans<<endl;cout<<"共"<<paths.size()<<"条最短路径:" <<endl; for(int i=0;i<paths.size();i++){for(int j=paths[i].size()-1;j>=0;j--){if(j<paths[i].size()-1){cout<<"-->";}cout<<paths[i][j]+1;}cout<<endl;}
}int main(){init();dfs(0);if(ans==0x3f3f3f3f){cout<<"该图无解"<<endl;return 0; }print();
}

3、复杂度分析

  时间复杂度: 深度搜索O(n!),每次都要判断是否符合题意O(n),总时间复杂度为O(n*(n!))
  空间复杂度: 存储所有的最优的路径,空间复杂度为O(n*(n!))

c++旅行商问题 (暴力解)相关推荐

  1. [Python随笔]暴力解解决“崩铁”的引航罗盘解密

    暴力解决游戏<崩坏:星穹铁道>中的引航罗盘解密.由于复杂度较低,所以暴力解具有可行性. 图片介绍参数设定: import sys# 获取自然数余数 def get_nature_remai ...

  2. zip暴力*解工具汇总

    目录 1.Ziperello 2.Bandzip 3.zip2john && john 4.fcrackzip 4.1 fcrackzip使用示例 1.Ziperello ZIP 压缩 ...

  3. 用模拟退火算法解旅行商问题

    1.问题描述 旅行商问题(Travelling Salesman Problem, 简记TSP,亦称货郎担问题):设 有n个城市和距离矩阵D=[dij],其中dij表示 城市i到城市j的距离,i,j= ...

  4. 蚁群算法(ACA)详细介绍(JAVA实现及代码详解)

    文章目录 1.蚁群算法概要 什么是蚁群算法 蚁群算法的数学公式 蚂蚁从i城市到j城市的概率公式 信息素的释放公式 信息素的挥发公式 蚁群算法的框架 2.TSP描述(旅行商问题) 3.JAVA源代码实现 ...

  5. python数独游戏源代码100行_python实现解数独程序代码

    偶然发现linux系统附带的一个数独游戏,打开玩了几把.无奈是个数独菜鸟,以前没玩过,根本就走不出几步就一团浆糊了. 于是就打算借助计算机的强大运算力来暴力解数独,还是很有乐趣的. 下面就记录一下我写 ...

  6. 模拟退火算法求解旅行商问题(python实现)

    模拟退火算法求解旅行商问题 文章目录 模拟退火算法求解旅行商问题 一.模拟退火算法原理 二.旅行商问题 1.求解思路 2.代码 总结 旅行商问题(TSP 问题).假设有一个旅行商人要拜访全国31个省会 ...

  7. leetcode 221. Maximal Square | 221. 最大正方形(优化的暴力解法+动态规划解法)

    题目 https://leetcode.com/problems/maximal-square/ 题解 方法1:最暴力解 O((m*n)^2) public class Solution {publi ...

  8. 【BZOJ-4524】伪光滑数 堆 + 贪心 (暴力) [可持久化可并堆 + DP]

    4524: [Cqoi2016]伪光滑数 Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 183  Solved: 82 [Submit][Statu ...

  9. java中怎么创建栈_这个题如何用栈解呢?

    每日温度 今天又给大家挑了一道十分经典的题目,也是一道面试常考题目,所以大家记得打卡啊,我们先来看一下题目描述,题目很容易理解,而且用暴力法也很容易实现,因为这个题目出现了我们的栈的模块,大家能不能用 ...

最新文章

  1. Oracle 数据库设置最大进程数参数方法,oracle最大进程数满了处理方法,sysdba管理员登录报“maximum number of processes (150) exceeded“问题解决
  2. 2、Docker 常用操作命令
  3. hdu-1104-Remainder(BFS打印路径+数论)(%与mod的区别)
  4. MongoDB优化之二:常见优化方法
  5. Tensorflow 卷积神经网络(三)池化与采样
  6. 1012. 数字分类 (20)-PAT乙级真题
  7. 白鹭引擎和layabox哪个好用,哪个技术更成熟 ?
  8. 如何比较两个word文档内容是否相同
  9. python 广告联盟_谷歌广告月入10000美金的一些经验谈
  10. 创龙TI TMS320C6748定点/浮点DSP C674xSD卡接口、拓展IO信号
  11. python 从大到小循环_Python循环小实例----猜大小
  12. WiFi的单频和双频
  13. 训练集和测试集的分布差距太大有好的处理方法吗?
  14. 编译原理:文法和语言总结与梳理
  15. python怎么改字体大小_如何使用python在excel中更改字体大小
  16. 【硬核游戏攻略】2.matlab中调用Java实现《大家来找茬》快速求解器
  17. SQLSERVER2019最新补丁下载地址
  18. 跨账本资产原子互换协议
  19. 江西地区媒体邀约资源现场官方直播推荐
  20. linux密码验证机制,linux用户认证机制

热门文章

  1. 3C低头族 小心飞蚊症找上你
  2. cesium获取模型实时坐标_ContextCapture Center Master 导出来的cesium模型项目怎么设置地标和实景模型的高度?...
  3. HDFS其实很简单,分分钟学会
  4. 古典密码之维吉尼亚密码实验
  5. FFmpeg从入门到精通(一)
  6. scrollTop兼容性
  7. contains与containsKey
  8. [翻译] 在 Overleaf 上使用 xr 包来交叉引用
  9. python实验:去除注水书评
  10. 《Wireshark网络分析的艺术》《Wireshark网络分析就这么简单》书评