模拟退火算法

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();
	}
    
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值