以下文章来源于数据魔术师 ,作者周航
前言
大家好呀!我们你们好久不见的。。。咳咳,初次见面的小编!
之前重新整理了ILS的代码,有人留言问能不能提供java版。
正好最近在学启发式算法和java,为了造福人类小编打算提供模拟退火法和迭代局部搜索求解TSP的java版本,方便一些不喜欢C++的同鞋~~
代码是基于我自己写的版本,但我是学习了公众号推文之后写的,同时有参照原文代码,因此虽然与C++代码有些许区别,但总体是类似的。
本文不再赘述TSP或者SA,ILS了,有需要请点击下方链接学习(一看就懂的那种哦!):
干货 | 用模拟退火(SA, Simulated Annealing)算法解决旅行商问题
干货|迭代局部搜索算法(Iterated local search)探幽(附C++代码及注释)
不多说了,开始看代码吧~!
代码下载
欲下载本文相关的代码及算例,请关注公众号【程序猿声】,后台回复【SAILSJAVA】不包括【】即可
SA求解TSP的JAVA代码
SA分为四个类:MainRun,Data,Path,SimulatedAnnealing。
MainRun是程序的入口。
package SA;
/**
* 主函数运行类
*/
public class MainRun {
public static void main (String args[])
{
long begintime = System.nanoTime();
Data.PrintData();
SimulatedAnnealing.SA();
SimulatedAnnealing.PrintPath();
long endtime = System.nanoTime();
double usedTime= (endtime - begintime)/(1e9);
System.out.println();
System.out.println("程序耗时:"+usedTime+"s");
}
}
Data是数据类,存放SA和TSP的数据。
package SA;
/**
* 数据类,包括:
* TSP城市坐标,采用柏林52城
* SA系数。
*/
public class Data {
public static final double T0=50000.0, // 初始温度
T_min=1e-8, // 结束温度
q=0.98, // 退火系数
K=1; //公式中的常数K
public static final int L=1000, // 每个温度时的迭代次数,即链长
N=52; // 城市数量
public static double[][] city_pos= //柏林52城城市坐标,最优解7542
{
{
565,575 },{
25,185 },{
345,750 },{
945,685 },{
845,655 },
{
880,660 },{
25,230 },{
525,1000 },{
580,1175 },{
650,1130 },
{
1605,620 },{
1220,580 },{
1465,200 },{
1530,5 },
{
845,680 },{
725,370 },{
145,665 },
{
415,635 },{
510,875 },{
560,365 },{
300,465 },{
520,585 },{
480,415 },
{
835,625 },{
975,580 },{
1215,245 },{
1320,315 },{
1250,400 },{
660,180 },
{
410,250 },{
420,555 },{
575,665 },{
1150,1160 },{
700,580 },{
685,595 },
{
685,610 },{
770,610 },{
795,645 },{
720,635 },{
760,650 },{
475,960 },
{
95,260 },{
875,920 },{
700,500 },{
555,815 },{
830,485 },{
1170,65 },
{
830,610 },{
605,625 },{
595,360 },{
1340,725 },{
1740,245 }
};
public static void PrintData()
{
System.out.println("模拟退火算法,初始温度T0="+T0+
",降温系数q="+q+",每个温度迭代"+L+"次");
}
}
Path是路径类,打包处理路径的静态方法。
package SA;
import static SA.Data.*;
import static java.lang.Math.*;
/**
* 路径类,打包处理路径的静态方法:
* 计算两点间距离 distance
* 计算路径长度 path_len
* 产生新解(新路径)create_new
*/
public class Path {
public static double distance(double[] p1,double[] p2) //计算两点间距离
{
double dis=0;
dis=sqrt(pow(p1[0]-p2[0],2)+pow(p1[1]-p2[1],2));
return dis;
}
public static double path_len(int[] city_list) //计算路径长度
{
double path=