【算法设计与分析基础】蛮力法解决旅行商问题
2016-10-15 00:14
176 查看
蛮力法解题思想:旅行商问题(又叫货郎担问题)可以表述为求一个最短的哈密顿回路问题。因为是回路,所以可以假设所有的回路都起点和终点都为同一个点,从而生成n-1个中间城市的排列。通过递归函数遍历所有城市,并记录每一种排列所得路径的长度,比较后得到最短路径。
对于上图所示的图,很显然最短的回路为:a→b→d→c→a;
首先我们选择a为出发点,遍历以a为起点/终点的所有可能的路径,并记录其长度;
再以b为出发点,遍历以b为起点/终点的所有可能的路径,并记录其长度;
......
那么如何实现呢?
这里我选择的是vc6.0。
首先我们需要写一个函数(在java中叫方法),生成n个结点的图的所有结点排列的全排列数量;
abcd,abdc,adbc....
知道规律了吗?
交换两个结点的顺序就是一个排列,所以缺少一个swap函数:
然后再写函数去调用它们;
最后是main函数
其中1.txt为:
0 2 5 7
2 0 8 3
5 7 0 2
7 3 2 0
对于上图,输出的结果为:
对于上图所示的图,很显然最短的回路为:a→b→d→c→a;
首先我们选择a为出发点,遍历以a为起点/终点的所有可能的路径,并记录其长度;
再以b为出发点,遍历以b为起点/终点的所有可能的路径,并记录其长度;
......
那么如何实现呢?
这里我选择的是vc6.0。
首先我们需要写一个函数(在java中叫方法),生成n个结点的图的所有结点排列的全排列数量;
int jiecheng(int n)//n的阶乘 { int s = 1; for(int i = 1;i <= n; i++) s=s*i; return s; }知道了全排列的数量,就要去实现全排列,那么怎么是实现呢?
abcd,abdc,adbc....
知道规律了吗?
交换两个结点的顺序就是一个排列,所以缺少一个swap函数:
void swap(int &a, int &b)//交换两个数 { int temp; temp = a; a = b; b = temp; }接下来就是生成全排列:
//求从n取m个数的排列 //A[]为等待求组合的数组,长度为n,同时用来保存结果 //start挑选的起点 //step步数 //Max全排列的数目 //dist[][]为距离矩阵 //path[]为路径 void Arrange(int A[],int start,int step,int n,int m,int Max,int *path,int **dist) { if(n < m) m = n;//从n个数中最多可以求n个数的全排列 if (step == m)//穷举求最小的路径并存到数组中 { len=0; count++; for (int i = 0;i < m; i++)//计算当前序列的路径长度 { if(i < m-1)// len = len+dist[A[i]][A[i+1]]; else len = len+dist[A[i]][A[0]]; cout<<A[i]<<" "; } if(len < mindist)//更新最短路径 { mindist = len; for(i = 0;i < m; i++) path[i] = A[i]; path[i] = A[0]; } cout<<endl; } if(count == Max)//做完之后输出最短路径及其长度 { cout<<"最短路径为:"<<mindist<<endl; cout<<"旅行路线为:"; for(int i = 0;i <= m; i++) { char name [4] = {'a','b','c','d'}; if(i != 0 && path[i] == 0)//终点 cout<<" ("<<name[path[i]]<<")"; else//非终点 cout<<" ("<<name[path[i]]<<") "<<"--"<<dist[path[i]][path[i+1]]<<"-->"; } cout<<endl; } else { //第j个数分别与它后面的数字交换就能得到新的排列 for (int j = start; j < n; j++) { swap(A[step],A[j]); Arrange(A,start+1,step+1,n,m,Max,path,dist); swap(A[j],A[step]); } } }
然后再写函数去调用它们;
//城市个数n,距离矩阵dist[][] //旅行路线path,最小距离min void solution(int n,int **dist,int *path) { int Max = jiecheng(n); //全排列的数目,算法的时间复杂度 int *Array = new int ; for(int i = 0;i < n; i++)//初始化序列(顺序) Array[i] = i; Arrange(Array,0,0,n,n,Max,path,dist); }
最后是main函数
void main() { int N = 4; cout<<"城市个数:"<<endl<<N<<endl; int *path = new int[N+1]; //存贮最优路径 int **Graph = new int * ; //建立动态的距离矩阵; for(int i = 0;i < N; i++) Graph[i] = new int ; ifstream input; input.open("1.txt"); //从txt文档读入矩阵信息 for(i = 0;i < N; i++) for(int j = 0;j < N; j++) input>>Graph[i][j]; //从txt文档输入矩阵 cout<<"距离矩阵:"<<endl; for(i = 0;i < N; i++) { for(int j = 0;j < N; j++) cout<<Graph[i][j]<<" "; cout<<endl; } cout<<"求得所有排列如下:"<<endl; solution(N,Graph,path); }
其中1.txt为:
0 2 5 7
2 0 8 3
5 7 0 2
7 3 2 0
对于上图,输出的结果为:
相关文章推荐
- 用遗传算法解决tsp旅行商问题
- 模拟退火算法解决旅行商问题_SA_TSP
- TSP_旅行商问题 - 蛮力法DFS(一)
- TSP_旅行商问题 - 蛮力法DFS(一)
- 模拟退火算法 解决旅行商(TSP)问题
- TSP_旅行商问题 - 蛮力法DFS(一)
- TSP_旅行商问题 - 蛮力法DFS(一)
- 蛮力法解决0/1背包问题
- ACO蚁群算法解决TSP旅行商问题
- ACO蚁群算法解决TSP旅行商问题
- 凸包问题之蛮力解决法
- TSP_旅行商问题 - 蛮力法DFS(一)
- 穷举法解决旅行商问题
- TSP_旅行商问题 - 蛮力法DFS(一)
- C语言编写遗传算法解决TSP旅行商问题
- 使用python解决TSP(旅行商问题)
- 分支限界解决旅行商tsp问题
- ACO蚁群算法解决TSP旅行商问题
- TSP_旅行商问题 - 蛮力法DFS(一)
- 贪心解决:TSP问题(Travelling Salesman Problem)即旅行商问题