【算法设计与分析】 深度优先搜索算法求解TSP问题(搜索算法)
【问题描述】
采用深度优先搜索算法求解TSP问题,并在搜索过程中,使用界限条件(当前结点已经走过的路径长度要小于已求得的最短路径)进行“剪枝”操作(不再对后续结点进行遍历),从而提高搜索效率。采用queue模块中的栈(LifoQueue)来实现深度优先搜索。
【输入形式】
在屏幕上输入顶点个数和连接顶点间的边的邻接矩阵,边上的权可能有小数点。
【输出形式】
在整个算法过程中的先后搜索路径(最多输出20次最先搜索的路径),最优值和其中一条最优路径。
【样例1输入】
4
0 30 6 4
30 0 5 10
6 5 0 20
4 10 20 0
【样例1输出】
1
1->2
1->2->3
1->2->3->4
1->2->4
1->3
1->3->2
1->3->2->4
1->3->4
1->4
1->4->2
1->4->2->3
1->4->3
25: 1->3->2->4
【样例说明】
输入:顶点个数为4。连接顶点间边的邻接矩阵大小为4行4列,位置[i,j]上元素值表示第i个顶点到第j个顶点的距离,0表示两个顶点间没有边连接。
输出:在整个算法过程中的先后搜索路径,最优值为25,最优路径为:1->3->2->4。
【题解代码】
#include <iostream>
#include <cstdio>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;
const int INF=1000000000;//无穷大
int n;//顶点个数
double g[1005][1005];//邻接矩阵
double bestcost=INF;//记录最优值
vector<int> bestpath;//记录最优路径
struct node
{
vector<int> path;
double cost;
void printpath()
{
int size=path.size();
cout<<path[0];
for(int i=1;i<size;i++)
cout<<"->"<<path[i];
cout<<endl;
}
};
void TSP_DFS()
{
int time=0;
stack<node> open;//open表
open.push({{1},0});//起始节点入栈
while(!open.empty())
{
node cur=open.top();
open.pop();
time++;
if(time<=20)
cur.printpath();//打印当前路径
if(cur.cost>=bestcost)
continue;
if(int(cur.path.size())==n)//cur为叶子结点
{
double totcost=cur.cost+g[1][cur.path[cur.path.size()-1]];
if(totcost<bestcost)//检测是否是更优解,更新最优解
{
bestcost=totcost;
bestpath=cur.path;
}
}
else//cur不是叶子结点
{
vector<int> curpath=cur.path;
double curcost=cur.cost;
for(int i=n;i>=1;i--)//生成所有满足条件的子节点,倒序加入open中
{
if(find(curpath.begin(),curpath.end(),i)==curpath.end())
{
curcost+=g[curpath[curpath.size()-1]][i];
curpath.push_back(i);
if(curcost<bestcost)
open.push({curpath,curcost});
curpath.pop_back();
curcost-=g[curpath[curpath.size()-1]][i];
}
}
}
}
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
cin>>g[i][j];
if(g[i][j]==0)
g[i][j]=INF;
}
TSP_DFS();
cout<<bestcost<<": "<<bestpath[0];
int size=bestpath.size();
for(int i=1;i<size;i++)
cout<<"->"<<bestpath[i];
cout<<endl;
return 0;
}