TSP_旅行商问题 - 蛮力法DFS

一、前言

    【旅行商问题】旅行商问题(TravelingSalesmanProblem,TSP)是一个经典的组合优化问题。经典的TSP可以描述为:一个商品推销员要去若干个城市推销商品,该推销员从一个城市出发,需要经过所有城市后,回到出发地。应如何选择行进路线,以使总的行程最短。从图论的角度来看,该问题实质是在一个带权完全无向图中,找一个权值最小的Hamilton回路。由于该问题的可行解是所有顶点的全排列,随着顶点数的增加,会产生组合爆炸,它是一个NP完全问题。由于其在交通运输、电路板线路设计以及物流配送等领域内有着广泛的应用,国内外学者对其进行了大量的研究。早期的研究者使用精确算法求解该问题,常用的方法包括:分枝定界法、线性规划法、动态规划法等。但是,随着问题规模的增大,精确算法将变得无能为力,因此,在后来的研究中,国内外学者重点使用近似算法或启发式算法,主要有遗传算法、模拟退火法、蚁群算法、禁忌搜索算法、贪婪算法和神经网络等。【参考百度百科】。

TSP_旅行商问题 - 蛮力法DFS_第1张图片TSP_旅行商问题 - 蛮力法DFS_第2张图片

二、本文概要

    本文基于蛮力法(此处采用深度优先遍历,DFS)解决旅行商问题。通过遍历出所有满足条件的路径情况,并保持更新最优解,直到所有情况都遍历完,得到全局最优解。但是,使用蛮力法需要遍历的城市个数高达city_num的阶乘,当city_num=12的时候,需遍历479001600种情况,程序所需时间以小时为单位。

运行结果

TSP_旅行商问题 - 蛮力法DFS_第3张图片

代码:

#include 
#include 

using namespace std;
const int maxSize = 999;
int arcNum,vertexNum,pathNum,pathIndex = 1,bestLength = maxSize;//pathIndex表示当前已经经过的点数
int vertex[maxSize],visited[maxSize];
int arc[maxSize][maxSize];
int path_DFS[maxSize][maxSize];//存放走过的路径
int length_DFS[maxSize];//存放每条路径对应的长度

void DFS(int index)
{
    if(pathIndex == vertexNum&&arc[index][1] != 0)
    {
        path_DFS[pathNum][pathIndex] = index;//当前到达的点
        path_DFS[pathNum][pathIndex + 1] = 1; // 最后一个到达的位置为1号点
        length_DFS[pathNum] = 0; // 存储最短路径
        //计算最短的路径
        for(int i = 1;i <= vertexNum;i++)
        {
            //当前点到下一个点的距离
            length_DFS[pathNum] += arc[path_DFS[pathNum][i]][path_DFS[pathNum][i + 1]];
        }
        if(bestLength > length_DFS[pathNum])
        {
            bestLength = length_DFS[pathNum];
        }
        for(int i = 1;i <= vertexNum + 1;i++)
        {
            cout << path_DFS[pathNum][i] << " ";
            path_DFS[pathNum + 1][i] = path_DFS[pathNum][i];
        }
        cout << endl << "length"<< length_DFS[pathNum] < 0&&visited[i] == 0)
            {
                visited[i] = 1;
                path_DFS[pathNum][pathIndex] = index;
                pathIndex++;
                DFS(i);
                visited[i] = 0;
                pathIndex--;
            }
        }
    }
}

int main()
{
    memset(visited,0,sizeof(visited));
    cin >> arcNum >> vertexNum;
    for(int i = 1;i <= vertexNum;i++)
    {
        vertex[i] = i;
    }
    for(int k = 0;k < arcNum;k++)
    {
        int i,j,weight;
        cin >> i >> j >> weight;
        arc[i][j] = weight;
        arc[j][i] = weight;
    }
    //一号点已经走过了
    visited[1] = 1;
    DFS(1);
    cout << bestLength << endl;
    return 0;
}

 

你可能感兴趣的:(上课的小题目)