算法 |【实验5.2】1-深度优先搜索暴力求解旅行商问题

简介: 算法 |【实验5.2】1-深度优先搜索暴力求解旅行商问题

使用深度优先搜索暴力求解旅行商问题


1.题目描述

商品推销员要去n个城市推销商品,城市从1至n编号,任意两个城市间有一定距离,该推销员从城市1出发,需要经过所有城市并回到城市1,求最短总路径长度。


把旅行商问题看作一种排列问题,不难想出,这道题的蛮力做法即穷举所有路线。选定起点有n种选法,选定起点后的下一个目的地有(n- 1)种选择方法,再下一个是(n-2)……总共有n!种排列方法,算法复杂度达到O(n!)。


一个20城市的TSP问题有大约60,000,000,000,000,000个可能解。如果一台计算机每秒搜索1000个解,需要大约1902587年才能搜索完所有的解。


因此蛮力法只能解决小规模问题。


image.png


2.问题分析与算法设计思路


总体思路: 深度优先搜索,递归


算法过程:


使用二维数组 dis 存放任意两个城市之间的距离


从城市 1 开始


使用一个循环遍历下一个城市的不同选择,且忽略已经走过的城市、不能直接到达的城市


每次遍历,更新到达当前城市走过的路径长度 len 。


走过所有城市后,len 再加上当前城市到城市 1 的距离(最后要回到 1 ),保存该条路径的长度。


在所有路径长度中找出最小值。


小结:


“先规划好思路,然后才开始编写代码”,这句话很早就听到说过了,但是能真正静下心来做到这一点的时候,却是不多。但我感觉,这很有用。


3.算法实现


完整可运行代码,C++实现:


//深度优先搜索求解旅行商问题
#include<iostream>
using namespace std;
const int Max = 10;
int len_min = 999;//最短总路径长度
int road[Max] = {1};//存放路径 
int it_r = 1;
//搜索求解
//参数dis:城市距离,now:所在城市,have:走过城市,
//len:走过路径长度,n:城市总数,num:已走过城市数 
void dfs(int dis[][Max], int now, bool have[], int len, int n, int num){
    //显示路径 
    cout<<"road:";
    for(int i = 0; i < it_r; i++){
        cout<<road[i]<<" ";
    }
    cout<<endl;
    //一条完整路径 
    if(num == n){
        len += dis[now][1];
        if(len < len_min){
            len_min = len;
        }
    }
    //遍历下一个城市 
    for(int i = 2; i <= n; i++){
        //排除已走过、不能到达的城市 
        if(have[i] == true || dis[now][i] == 0){
            continue;
        }
        int len_next = len + dis[now][i];
        have[i] = true;
        road[it_r++] = i;
        dfs(dis, i, have, len_next, n, num+1);
        road[--it_r] = 0;
        have[i] = false;
    }
}
int main(){
    int dis[Max][Max] = {};//任意两城市距离,0表示不能直接到达 
    bool have[Max] = {1};//已走过哪些城市 
    int n = 0;//城市的个数
    int e = 0;//道路的个数
    cin>>n>>e;
    for(int i = 1; i <= e; i++){
        int a = 0, b = 0, x = 0;
        cin>>a>>b>>x;
        dis[a][b] = x;
        dis[b][a] = x;
    } 
    //显示城市距离 
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            cout<<dis[i][j]<<" ";
        }
        cout<<endl;
    }
    dfs(dis, 1, have, 0, n, 1);
    cout<<"最短路径:"<<len_min;
    return 0;
} 
/*
测试数据一 
4 5
1 2 5
1 3 3
1 4 4
2 3 7
2 4 6
*/

4.运行结果

image.png


5.算法分析

算法的时间复杂度在前面的题目描述中已经讲到了,达到了o ( n ! ) o(n!)o(n!) 。


空间复杂度应为o ( n 2 ) o(n^2)o(n2),因为使用了二维数组来存放城市间距离。

相关文章
|
1月前
|
算法 测试技术 定位技术
数据结构与算法——DFS(深度优先搜索)
数据结构与算法——DFS(深度优先搜索)
|
23天前
|
算法 搜索推荐 Java
java 后端 使用 Graphics2D 制作海报,画echarts图,带工具类,各种细节:如头像切割成圆形,文字换行算法(完美实验success),解决画上文字、图片后不清晰问题
这篇文章介绍了如何使用Java后端技术,结合Graphics2D和Echarts等工具,生成包含个性化信息和图表的海报,并提供了详细的代码实现和GitHub项目链接。
83 0
java 后端 使用 Graphics2D 制作海报,画echarts图,带工具类,各种细节:如头像切割成圆形,文字换行算法(完美实验success),解决画上文字、图片后不清晰问题
|
30天前
|
算法
计科一二班算法数据结构实验9答案
计科一二班算法数据结构实验9答案
13 0
|
1月前
|
算法 C++
【算法解题思想】动态规划+深度优先搜索(C/C++)
【算法解题思想】动态规划+深度优先搜索(C/C++)
|
3月前
|
算法 Java 测试技术
算法分析(蛮力法与减治算法应用实验报告)
这篇文章是关于算法分析的实验报告,介绍了如何使用蛮力法解决背包问题,并通过伪代码和Java代码实现,同时分析了其时间效率;还介绍了基于减治法思想实现的二叉查找树的插入与查找,同样提供了伪代码、Java源代码实现和时间效率分析,最后展示了测试结果截图。
算法分析(蛮力法与减治算法应用实验报告)
|
3月前
|
机器学习/深度学习 算法 Java
算法设计(动态规划应用实验报告)实现基于贪婪技术思想的Prim算法、Dijkstra算法
这篇文章介绍了基于贪婪技术思想的Prim算法和Dijkstra算法,包括它们的伪代码描述、Java源代码实现、时间效率分析,并展示了算法的测试用例结果,使读者对贪婪技术及其应用有了更深入的理解。
算法设计(动态规划应用实验报告)实现基于贪婪技术思想的Prim算法、Dijkstra算法
|
3月前
|
算法 Java 测试技术
算法设计(动态规划实验报告) 基于动态规划的背包问题、Warshall算法和Floyd算法
这篇文章介绍了基于动态规划法的三种算法:解决背包问题的递归和自底向上实现、Warshall算法和Floyd算法,并提供了它们的伪代码、Java源代码实现以及时间效率分析。
算法设计(动态规划实验报告) 基于动态规划的背包问题、Warshall算法和Floyd算法
|
3月前
|
算法 搜索推荐
算法设计 (分治法应用实验报告)基于分治法的合并排序、快速排序、最近对问题
这篇文章是关于分治法应用的实验报告,详细介绍了如何利用分治法实现合并排序和快速排序算法,并探讨了使用分治法解决二维平面上的最近对问题的方法,包括伪代码、源代码实现及时间效率分析,并附有运行结果和小结。
|
5月前
|
Python
求解带有限重的三维装箱问题——启发式深度优先搜索算法
求解带有限重的三维装箱问题——启发式深度优先搜索算法
95 4
|
5月前
|
算法 Java
Java数据结构与算法:图算法之深度优先搜索(DFS)
Java数据结构与算法:图算法之深度优先搜索(DFS)