import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class SA_module {
public static int citynum;//城市的个数
public static int iteration; //单个温度下的迭代次数
public static int coolingtime; //降温次数;
public static double aerfa;//降温系数;
public static double t0;//初始温度;
public static double[][] distance;//距离矩阵
public static int[] initialgraph;//初始路径编码
public static int[] bestgraph;//最好路径编码
public static int[] tempgraph;//临时存放编码;
public static int initialevaluation;//初始路径评价值
public static int bestevaluation;//最好路径评价值
public static int tempevaluation;//临时路径评价值;
public static int bestrank;//最优解出现的代数
SA_module(int citynum,int iteration,int coolingtime,double aerfa,double t0){
SA_module.citynum = citynum;
SA_module.iteration = iteration;
SA_module.coolingtime = coolingtime;
SA_module.aerfa = aerfa;
SA_module.t0 = t0;
}
public static void initial(String filename) throws IOException{
double[] tempx = new double[citynum+1];
double[] tempy = new double[citynum+1];
distance = new double[citynum+1][citynum+1];
String strbuffer;
BufferedReader data = new BufferedReader(new InputStreamReader(new FileInputStream(filename)));
for(int i=1;i<=citynum;i++){
// 读取一行数据,数据格式: [x坐标+" "+y左边]
strbuffer = data.readLine();
String[] temp = strbuffer.split(" ");
tempx[i] = Integer.valueOf(temp[0]);
tempy[i] = Integer.valueOf(temp[1]);
}
for(int i=1;i<=citynum;i++){
distance[i][i] = 0;
for(int j=i+1;j<=citynum;j++){
double temp = Math.sqrt(Math.pow(tempx[i]-tempx[j], 2)+Math.pow(tempy[i]-tempy[j], 2));
distance[i][j] = temp;
distance[j][i] = temp;
}
}
initialgraph = new int[citynum+1];
bestgraph = new int[citynum+1];
tempgraph = new int[citynum+1];
bestevaluation = Integer.MAX_VALUE;
tempevaluation = Integer.MAX_VALUE;
bestrank = 0;
System.out.println("初始化成功,城市个数为:"+citynum+",同一温度迭代次数为:"+iteration+",降温次数为:"+coolingtime+",降温系数为:"+aerfa+",初始温度为:"+t0);
}
void initialgraph(){
initialgraph[1] = (int)(Math.random()*citynum+1);
for(int x=2;x<=citynum;){
boolean judge = true;//默认可以通过检测
initialgraph[x] = (int)(Math.random()*citynum+1);
//检查不能和前面的相同
for(int y=1;y<=x-1;y++){
if(initialgraph[x]==initialgraph[y]){//如果有相同的就重新生成一个数
judge = false;//有相同的就不能通过检测
break;
}
}
if(judge) x++;//如果可以通过检测就开始拿下一个数字
}
}
void copygraph(int[] grapha,int[] graphb){//用前面的顺序编码覆盖后面的顺序编码
for(int i=1;i<=citynum;i++){
graphb[i] = grapha[i];
}
}
int evaluation(int[] temp){
int res = 0;
for(int i=1;i<=citynum-1;i++){
res += distance[temp[i]][temp[i+1]];
}
res+= distance[temp[0]][temp[citynum]];
return res;
}
//前面序列随机交换一个后得到后面序列
void nabor(int[] graph,int[] newgraph){
for(int i=1;i<=citynum;i++){
newgraph[i] = graph[i];
}
int temp;
int x;
int y;
do{
x = (int)(Math.random()*citynum+1);
y = (int)(Math.random()*citynum+1);
}while(x==y);
temp = newgraph[x];
newgraph[x] = newgraph[y];
newgraph[y] = temp;
}
void solve(){
initialgraph();//初始化initialgraph
copygraph(initialgraph,bestgraph);//现在initialgraph为bestgraph
bestevaluation = evaluation(initialgraph);
initialevaluation = bestevaluation;
int curcoolingtime = 1;//现在降温次数为1
int curiteration = 1;//现在迭代次数为1
double t = t0;
while(curcoolingtime<=coolingtime){
curiteration = 1;
while(curiteration<=iteration){
nabor(initialgraph,tempgraph);//得到当前编码的领域编码
tempevaluation = evaluation(tempgraph);
if(tempevaluation<bestevaluation){//如果这个是最好的评估值就记下来
copygraph(tempgraph,bestgraph);
bestrank = curcoolingtime;
bestevaluation = tempevaluation;
}
if(tempevaluation<initialevaluation||Math.exp((initialevaluation-tempevaluation)/t)>Math.random()){
copygraph(tempgraph,initialgraph);
initialevaluation = tempevaluation;
}
curiteration++;
}
t *= aerfa;
curcoolingtime++;
}
System.out.println("运算完成,最优路径长度:"+bestevaluation+",在第"+bestrank+"代出现,路径为:");
for(int i=1;i<=citynum;i++){
System.out.print(bestgraph[i]+" ");
}
}
public static void main(String[] args) throws IOException {
System.out.println("Start....");
SA_module sa = new SA_module(48, 40, 400, 250, 0.95);
SA_module.initial("文件路径导入");
sa.solve();
}
}
模拟退火算法
最新推荐文章于 2022-10-02 18:36:13 发布