浅谈贪心法与TSP问题

贪心法

贪心法把一个复杂问题分解为一系列较为简单的局部最优选择,每一步选择都是对当前解的一个扩展,直到获得问题的完整解。贪心法的典型应用是求解最优化问题,而且对许多问题都能得到整体的最优解,即使不能得到整体最优解,通常也是最优解的很好近似。

TSP

TSP问题是指旅行家要旅行n个城市,要求各个城市经历且仅经历一次然后回到出发城市,并要求所走的路程最短。(下面以给出无向图的代价矩阵为例,从左到右,从上到下,表示城市:1~5,100表示城市本身(无穷大),在自己的写的代码中,可以自行调整这数值)
浅谈贪心法与TSP问题_第1张图片

解决思想

思想1:最近邻点策略
从任意城市出发,每次在没有到过的城市中选择最近的一个,直到经过了所有的城市,最后回到出发城市。

按照这种思想,如果从顶点1出发,那么根据代价矩阵,我们可以得出的路径是:1->4->3->5->2->1。总代价是14.

我们可以先大概写出伪代码,有了伪代码以后,我们就可以更好的用代码实现,伪代码如下:
浅谈贪心法与TSP问题_第2张图片
算法实现1:
设函数TSP1实现最近邻点贪心策略求解TSP问题,数组arc[n][n]存储代价矩阵,TSPLength存储最短哈密顿回路(经过所有顶点一次仅且一次的回路)的长度,标志数组flag[n]表示某顶点是否已加入哈密顿回路,算法用C++语言描述如下:

 int TSP1(int arc[n][n],int w)  //假定从顶点w出发
 { 
     int edgeCount=0,TSPlength=0;
     int min,u,v;
     int flag[n]={0};    //顶点均为加入哈密顿回路
     u=w;flag[w]=1;
     while(edgeCount"<"<
思想2:最短链接策略
每次在整个图的范围内选择最短边加入解集合中,但是,要保证加入解集合中的边最终形成
一个哈密顿回路。因此,当从剩余边集E中选择一条边(u,v)加入解集合S中,应满足以下
条件:
1.边(u,v)是剩余边集E中代价最小的边;
2.边(u,v)加入解集合S后,S中不产生回路;
3.边(u,v)加入解集合S后,S中不产生分歧

按照这种思想,依次选择的边是:1----4;2----5;3-----4;1-----2;3-----5;
伪代码如下:

算法策略:最短链接策略求解TSP问题
输入:无向带权图G=(V,E)
输出:回路长度TSPLength
1.初始化:P={  };TSPLength=0;
2.E' = E;
3.循环直到集合P中包含n-1条边
   3.1  在E'中选取最短边(u,v);
   3.2   E'=E'-{(u,v)};
   3.3   如果(顶点u和v在P中不连通 && 不产生分枝)则P=P+{ (u,v) };TSPLength+
          =C (顶点u-->v);
4.输出TSPLength。

根据这种思想,下面小编给出具体的实现代码,在变量方面跟伪代码中的不太一样(原创),结合小编给出的注释自行理解(代码效率和整洁性自行评估,根据自己的需求进行修改)

#include
#define M 5
#define N 5
int TSP(int C[M][N],int s) ;//表示从s点开始出发
int main(){
	int C[M][N]={{1000,3,3,2,6},{3,1000,7,3,2},{3,7,1000,2,5},{2,3,2,1000,3},{6,2,5,3,1000}}; //初始化TSP问题的代价矩阵,1000表示节点本身
//    int C[5][5]={{1000,1,1,7,6},{1,1000,1,2,6},{1,2,1000,5,4},{7,2,5,1000,3},{6,5,4,3,1000}};
	printf("\nTSP的最短路程为(默认从1开始):%d\n",TSP(C,1));
	return 1;
}

int TSP(int C[M][N],int s) //表示从s点开始出发
{
    int max=100,p=M-1,length=0,j=0,k=0; //max初始化路径最大值
    int start[M]={-1}; //表示已走过路径的起点
    int end[N]={-1};    //表示已走过路径的终点
    int du[N]={0};      //初始化每个节点的度,为0
    for(int i=0;i0){
       int min=1000;
       int i,a,x=0,y=0;
       for(i=0;i%d\n",start[g]+1,end[g]+1);
    return length;
}

以上就是用贪心法解决TSP问题的两种不同策略,虽然用贪心法不一定能得到TSP问题的最优解,但是在实际运用中,随着数据输入规模越来越大,去追求一个问题的最优解要花费大量的开销,所以,贪心法求得的最有近似解具有很重要的参考价值。

求解TSP问题还可以用蛮力法、动态规划法、回溯法、分支限界法等,每种方法都有自身的特点,读者根据自己的需要自行拓展自己的知识面。本文的编写参考了王红梅 胡明 的《算法分析与设计(第二版)》,第二种算法代码为原创,在这本书中没有具体代码,算是小编在学习过程中的一个总结吧。

上面若有错误,欢迎留言指出。 By Mr.Lito

你可能感兴趣的:(算法)