TSP-贪心启发式算法求解

1、贪心算法
(1)概念
贪心算法(贪婪算法),是求解最优化问题常见的简单、迅速的算法,它只是做出在当前看来最好的选择,而不可考虑整体
(2)思路
第一步:描述问题和建立数学模型
第二步:把原问题分解成若干个子问题
第三步:对每个子问题进行求解,得到子问题的局部最优解
第四步:把子问题的局部最优解合并成原问题的解
(3)缺点
求的的解可能与原问题的最优解相差较大

2、贪心算法求解TSP
本文用的算例是经典的att48(可直接百度tsplib获取),它是一个对称的TSP问题,城市规模为48,其最优值为10628
代码结构如下图所示:
TSP-贪心启发式算法求解_第1张图片
其中Data类表示定义数据、变量初始化和读取数据的类

package com.chb.greedy;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;

public class Data {
	public static int cityNum=48;//城市数量,手动设置
	public static int point[][]=new int[cityNum][2];//每个城市的坐标
	public static int dist[][]=new int[cityNum][cityNum];//距离矩阵
	public static int cloable[]=new int[cityNum];//代表列,表示是否走过,走过则为0
	public static int row[]=new int[cityNum];//代表行,选过则为0
    
	//读取数据并初始化
	public static void read_data(String filepath) throws FileNotFoundException {
		String line=null;
		String substr[]=null;
		Scanner cin=new Scanner(new BufferedReader(new FileReader(filepath)));
		for (int i = 0; i < cityNum; i++) {
			line=cin.nextLine();
			line.trim();
			substr=line.split(" ");
			 point[i][0]=Integer.parseInt(substr[1]);//x坐标
			 point[i][1]=Integer.parseInt(substr[2]);//y坐标
		}
		cin.close();
		//计算距离矩阵,注意这里的计算方式,才用的是伪欧式距离
		for (int i = 0; i < cityNum; i++) {
			dist[i][i]=0;//对角线元素为0
			for (int j = i+1; j < cityNum; j++) {
				double rij=Math.sqrt((Math.pow(point[i][0]-point[j][0], 2)+
						             Math.pow(point[i][1]-point[j][1], 2))/10.0);
				//rij四舍五入取整
				int tij=(int) Math.round(rij);
				if(tij

Greedy类是算法主体类

package com.chb.greedy;

import java.io.FileNotFoundException;

public class Greedy {
	public static void solve() {
		int[]temp=new int[Data.cityNum];
		String path="0";
		int s=0;//计算距离
		int i=0;//当前节点
		int j=0;//下一个节点
		//默认从0开始
		while(Data.row[i]==1) {
			//复制一行
			for (int k = 0; k < Data.cityNum; k++) {
				temp[k]=Data.dist[i][k];
			}
			//选择下一个节点,要求没有走过,且与i不同
			j=selectmin(temp);
			Data.row[i]=0;//行设置为0,表示已经选过
			Data.cloable[j]=0;//列设置为0,表示已经走过
			path+="-->"+j;
			s=s+Data.dist[i][j];
			i=j;//当前节点指向下一个节点
		}
		System.out.println("路径:"+path);
		System.out.println("总距离:"+s);
	}

	private static int selectmin(int[] p) {
		int j=0;
		int m=p[0];
		int k=0;
		//寻找第一个可用节点,注意最后一次寻找没有可用节点
		while(Data.cloable[j]==0) {
			j++;
			if(j>=Data.cityNum) {
				//没有可用节点,最后一次为-->0
				m=p[0];
				break;
			}else {
				m=p[j];
			}
		}
		//从可用节点j开始向后找,找出距离最小的节点
		for (; j < Data.cityNum; j++) {
			if(Data.cloable[j]==1) {
				if(m>p[j]) {
					m=p[j];
					k=j;
				}
			}
		}
		return k;
	}
	public static void main(String[] args) throws FileNotFoundException {
		Data.read_data("data/att48.txt");
		Greedy.solve();
	}
}

data文件夹中的att48.txt是测试文件,可直接百度TSPLIB下载,或从https://pan.baidu.com/s/1Pc71mAN7WBbdxkzOkOK8gw处下载
运行结果:
在这里插入图片描述
:本文提炼、转载自http://blog.csdn.net/wangqiuyun/article/details/38680151

你可能感兴趣的:(TSP,算法基础)