算法设计大作业—求解Tsps问题

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

基于贪心算法求解TSP问题

一、TSP问题

TSP问题(Travelling Salesman Problem)即旅行商问题,又译为旅行推销员问题、货郎担问题,是数学领域中著名问题之一。假设有一个旅行商人要拜访n个城市,他必须选择所要走的路径,路径的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。路径的选择目标是要求得的路径路程为所有路径之中的最小值。

TSP问题是一个组合优化问题。该问题可以被证明具有NPC计算复杂性。TSP问题可以分为两类,一类是对称TSP问题(Symmetric TSP),另一类是非对称问题(Asymmetric TSP)。所有的TSP问题都可以用一个图(Graph)来描述:

V={c1, c2, …, ci, …, cn},i = 1,2, …, n,是所有城市的集合.ci表示第i个城市,n为城市的数目;

E={(r, s): r,s∈V}是所有城市之间连接的集合;

C = {crs: r,s∈V}是所有城市之间连接的成本度量(一般为城市之间的距离);

如果crs = csr, 那么该TSP问题为对称的,否则为非对称的。

一个TSP问题可以表达为:

求解遍历图G = (V, E, C),所有的节点一次并且回到起始节点,使得连接这些节点的路径成本最低。

二、贪心算法

贪心算法,又名贪婪算法,是一种常用的求解最优化问题的简单、迅速的算法。贪心算法总是做出在当前看来最好的选择,它所做的每一个在当前状态下某种意义上是最好的选择即贪心选择,并希望通过每次所作的贪心选择导致最终得到问题最优解。必须注意的是,贪心算法不是对所有问题都能得到整体最优解,选择的贪心策略必须具备无后效性,即某个状态以后的过程不会影响以前的状态,只与当前状态有关。

1、贪心算法的基本思路

从问题的某一个初始解触发逐步逼近给定的目标,以尽可能快地求得更好的解。当达到某算法中的某一步不能再继续前进时,算法停止。大致步骤如下:

1)建立数学模型来描述问题;

2)把求解的问题分成若干个子问题

3)对每一个子问题求解,得到子问题的局部最优解

4)把子问题的局部最优解合成原问题的一个解

2、贪心算法的实现框架

贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择,而贪心策略适用的前提是:局部最优策略能导致产生全局最优解。

从问题的某一初始解出发;

while (能朝给定总目标前进一步)

{

利用可行的决策,求出可行解的一个解元素;

}

由所有解元素组合成问题的一个可行解;

3、贪心算法存在的问题

1)不能保证求得的最后解是最佳的;

2)不能用来求最大最小解问题;

3)只能在某些特定条件约束的情况下使用,例如贪心策略必须具备无后效性等。

4、典型的贪心算法使用领域

马踏棋盘、背包、装箱等

三、贪心算法求解TSP问题

贪心策略:在当前节点下遍历所有能到达的下一节点,选择距离最近的节点作为下一节点。基本思路是,从一节点出发遍历所有能到达的下一节点,选择距离最近的节点作为下一节点,然后把当前节点标记已走过,下一节点作为当前节点,重复贪心策略,以此类推直至所有节点都标记为已走节点结束。

贪心法的方法是在每个节点中找到与其他节点的最小距离,并且有顺序,比如从第1节点出发,到其他节点的最小节点为3,在从第3节点到不包含节点1的最小节点距离为节点5,以此继续下去,找到路线1-3-5-4-2-1回路。

四、C++算法如下:

#include

#define N 5

void copy(int A[N][N],int B[N][N])

{

for(int i=0;i

for(int j=0;j

}

int main()

{

int a[5][5]={{1000,3,1,5,8},{3,1000,6,7,9},{1,6,1000,4,2},{5,7,4,1000,3},{8,9,2,3,1000}};

int A[N][N];

copy(A,a);

//int a[5][5]={{1000,3,1,5,8},{3,1000,6,17,9},{1,6,1000,4,2},{5,17,4,1000,3},{8,9,2,3,1000}};

int b[5]={0};

int n=sizeof(b)/sizeof(int);

int i=1,j,k;

while(i

{

int visit=0;

int min=1000;

for(j=0;j

{

a[j][b[i-1]]=-1;

}

for(j=0;j

{

if(min>a[b[i-1]][j]&&a[b[i-1]][j]>0)

{

visit=j;

min=a[b[i-1]][j];

a[b[i-1]][j]=-1;

}

}

b[i++]=visit;

for(j=0;j

{

for(k=0;k

{

cout<

}

cout<

}

cout<

}

cout<<"贪心法路线为:"<

for(i=0;i

{

cout<"<<"\t";

}

cout<

cout<<"贪心法路线长度为:";

int sum=0;

for(i=0;i

{

sum=sum+A[b[i]][b[i+1]];

}

cout<

}

输出结果:

算法分析

时间复杂度:对于节点数为n的tsp问题,用贪心算法,时间复杂度为O(n^2)

相关文档
最新文档