旅行商问题之回溯法

该博客介绍了如何利用回溯法解决经典的旅行商问题。通过C++代码实现了一个简单的回溯法求解旅行商问题的算法,包括邻接矩阵的初始化、路径存储和最优路径更新等步骤。样例展示了当有5个节点和9条边的城市时,如何找到最短的旅行路径。
摘要由CSDN通过智能技术生成

旅行商问题之回溯法

代码实现

//回溯法 旅行商问题
#include<iostream>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int INF=1e7;//正无穷
int n;//节点个数
int m;//边的个数
int**matrix;//邻接矩阵
int*x;//当前路径
int*bestx;//最优路径
int cl;//当前路径长度
int bestl;//最优路径长度
void init(int n){
    //申请邻接矩阵空间
    matrix=(int**)malloc(sizeof(int*)*n);
    for(int i=0;i<n;i++)
        matrix[i]=(int*)malloc(sizeof(int)*n);
    //初始化邻接矩阵
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            matrix[i][j]=matrix[j][i]=INF;//初始化不可达
        }
    }
    bestl=INF;
    cl=0;
    //申请当前路径存储空间
    x=(int*)malloc(sizeof(int)*n);
    //申请最优路径长度
    bestx=(int*)malloc(sizeof(int)*n);
    for(int i=0;i<n;i++){
        x[i]=i;
        bestx[i]=-1;//初始化无解
    }
}

void Traveling(int t){
    if(t>=n){//到达叶子节点
        //从末尾节点最优路径长度+末尾->起点<bestl 则是一个更优解
        if(matrix[x[n-1]][0]!=INF&&(cl+matrix[x[n-1]][0])<bestl){
            //更新路径最优解
            for(int j=0;j<n;j++){
                bestx[j]=x[j];
            }
            //更新最优路径长度
            bestl+=cl+matrix[x[n-1]][0];
        }
    }else{//没有到达叶子节点
        //逐个试探t层节点的孩子节点
        for(int j=t;j<n;j++){
            //t-1 层的节点 与 t 层的相连且有可能取得更优路线,否则进行界限剪枝处理
            if(matrix[x[t-1]][x[j]]!=INF&&(cl+matrix[x[t-1]][x[j]])<bestl){
                swap(x[t],x[j]);
                cl+=matrix[x[t-1]][x[t]];
                Traveling(t+1);
                cl-=matrix[x[t-1]][x[t]];
                swap(x[t],x[j]);
            }
        }
    }
}

int main(void){
    cout<<"请输入节点的个数"<<endl;
    cin>>n;
    cout<<"请输入边的个数"<<endl;
    cin>>m;
    init(n);//初始化邻接矩阵
    cout<<"输入两个节点的距离"<<endl;
    int v1,v2,w;
    for(int i=0;i<m;i++){
        cin>>v1>>v2>>w;
        matrix[v1][v2]=matrix[v2][v1]=w;
    }
    Traveling(1);//从0节点开始走
    for(int i=0;i<n;i++)free(matrix[i]);
    free(matrix);
    for(int i=0;i<n;i++){
        cout<<bestx[i]<<"--";
    }
    cout<<"0";
    free(x);
    free(bestx);
    return 0;
}

样例

请输入节点的个数
5
请输入边的个数
9
输入两个节点的距离
0 1 3
0 3 8
0 4 9
1 2 3
1 3 10
1 4 5
2 3 4
2 4 3
3 4 20
0--4--1--2--3--0
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高万禄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值