一、TSP问题
TSP问题(Travelling Salesman Problem)即旅行商问题,又译为旅行推销员问题、货郎担问题。假设有一个旅行商人要拜访n个城市,他必须选择所要走的路径,路径的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。路径的选择目标是要求得的路径路程为所有路径之中的最小值。
二、贪心算法
贪心算法,总是做出在当前看来最好的选择,它所做的每一个在当前状态下某种意义上是最好的选择即贪心选择,并希望通过每次所作的贪心选择导致最终得到问题最优解。必须注意的是,贪心算法不是对所有问题都能得到整体最优解,选择的贪心策略必须具备无后效性,即某个状态以后的过程不会影响以前的状态,只与当前状态有关。
1、贪心算法的基本思路
从问题的某一个初始解触发逐步逼近给定的目标,以尽可能快地求得更好的解。当达到某算法中的某一步不能再继续前进时,算法停止。大致步骤如下:
1)建立数学模型来描述问题;
2)把求解的问题分成若干个子问题
3)对每一个子问题求解,得到子问题的局部最优解
4)把子问题的局部最优解合成原问题的一个解
2、贪心算法的实现框架
贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择,而贪心策略适用的前提是:局部最优策略能导致产生全局最优解。
从问题的某一初始解出发;
while (能朝给定总目标前进一步)
{
利用可行的决策,求出可行解的一个解元素;
}
由所有解元素组合成问题的一个可行解;
3、贪心算法存在的问题
1)不能保证求得的最后解是最佳的;
2)不能用来求最大最小解问题;
马踏棋盘、背包、装箱等
三、贪心算法求解TSP问题
贪心策略:在当前节点下遍历所有能到达的下一节点,选择距离最近的节点作为下一节点。基本思路是,从一节点出发遍历所有能到达的下一节点,选择距离最近的节点作为下一节点,然后把当前节点标记已走过,下一节点作为当前节点,重复贪心策略,以此类推直至所有节点都标记为已走节点结束
package com.tsp;
public class Tsp {
private int cityNum=4;
private int[][] distance={ //每个城市的距离矩阵
{999,2,6,5},
{2,999,5,4},
{6,5,999,2},
{5,4,2,999}
};
private boolean[] col=new boolean[4];//标记数组,用于标记列是否被访问
private boolean[] row=new boolean[4];//标记数组,用于标记行是否被访问
private void getTsp(){
for(int i=0;i<cityNum;i++){//初始化标记数组
col[i]=false;
row[i]=false;//默认都没有被访问
}
col[0]=true;//从标号为0的节点开始
int current=0;//当前节点 (在矩阵中也表示当前行)
int next=0;//下一个节点
int[] temp=new int[cityNum];//用于存储当前节点到其他节点的距离
String path=”0″;//用于保存路径
int sum=0;
int count=0;//用于计数
while(row[current]==false){//终点是回到第一个节点,已经被标记已经访问过
count++;
if(count>=cityNum){
path+=”–>0″;
sum+=temp[0];
System.out.println(“path:”+path);
System.out.println(“sum:”+sum);
}
for(int j=0;j<cityNum;j++)
temp[j]=distance[current][j];
int index=0;
int min=Integer.MAX_VALUE;
for(int k=0;k<cityNum;k++){//寻找当前节点相连的最小的节点
if(temp[k]<min&&col[k]==false){
min=temp[k];
index=k;
}
}
sum+=min;
path=path+”–>”+index;
row[current]=true;
col[next]=true;
next=index;
current=next;
}
}
public static void main(String[] args) {
new Tsp().getTsp();
}
}