淘先锋技术网

首页 1 2 3 4 5 6 7

这个程序实现了模拟退火,用于计算att48数据集。

这个程序由两部分组成SA1和Line1。SA1是主程序,结合了蚁群算法改写的。主要思路是先用蚁群算法生成一个原始路径,然后随机交换两个城市的位置,如果得到的距离好于最优值或者满足退火条件就保留这次更改,不断迭代直到最优值到达要求。

Line1程序用于画图。

 

程序中一共有4个本地路径

d:/工业/hk/aaa.csv   保存SA1的计算结果

d:/工业/hk/统计.csv  保存每步的距离变化

d:/工业/hk/t/zz.csv   48个城市的坐标

d:/工业/hk/重排.csv  临时文件用于画图

 

性能测试数据

用这组参数进行性能测试

SA(48, 1000, 2000,  0.99815 , 1500, "d:/工业/hk/t/zz.csv" );

 

 

耗时ms

耗时min

1

422

316819

5.2803167

2

530

399003

6.65005

3

92

74823

1.24705

4

435

423858

7.0643

5

53

51973

0.8662167

6

143

139023

2.31705

7

137

133736

2.2289333

8

493

474521

7.9086833

9

388

378521

6.3086833

10

241

234907

3.9151167

11

39

37827

0.63045

12

509

488905

8.1484167

13

38

37292

0.6215333

14

125

124406

2.0734333

15

677

665224

11.087067

这个程序共运行了15次,达到10628平均需要288步,4.42分钟。每一步需要交换2百万次。也就是平均每次计算需要交换5.76亿次才能达到最优值。

 

SA1代码

Line1代码

d:/工业/hk/t/zz.csv

package plan;

import java.io.BufferedReader;  
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;  
import java.io.InputStreamReader;  
import java.util.Random; 

public class SA1 {

		//实现了退火算法
		
		 static int cityNum; // 城市数量,编码长度  
	     static int N;// 每个温度迭代次数
	     static int T;// 重复降温次数  
	     static double a;// 降温系数  
	     static double t1;// 初始温度  
	  
	     static int[][] distance; // 距离矩阵  
	     static int bestT=0;// 最佳出现代数  
	  
	     static int[] Ghh;// 初始路径编码  
	     static int ge;  
	     static int[] bestGhh;// 最好的路径编码  
	     static int be;  
	     static int[] tempGhh;// 存放临时编码  
	     static int te;  
	     static int min=100000;
	     
	     private static Random random;  
	  
	    //退火算法即照顾了广度也照顾了深度
	 
	    public static int SA(int cn, int n, int t, double aa, float tt  ,String filename  ) throws IOException {  
	        cityNum = cn;  
	        N = n;  
	        T = t;  
	        a = aa; 
	        t1 = tt;  
	        
	        int fan=0;
	        init( filename);
	        
	        fan=solve();
	        
	        return fan;
	    }  
	  
	    // 读取数据  
	    public static void init(String filename) throws IOException {  
	   
	        int[] x;  
	        int[] y;  
	        String strbuff;  
	        BufferedReader data = new BufferedReader(new InputStreamReader(  
	                new FileInputStream(filename)));  
	        distance = new int[cityNum][cityNum];  
	        x = new int[cityNum];  
	        y = new int[cityNum];  
	        for (int i = 0; i < cityNum; i++) {  
	           	
	        	//System.out.println(i+"************ ");
	        	
	            // 读取一行数据,数据格式1 6734 1453  
	            strbuff = data.readLine();  
	            // 字符分割  
	            String[] strcol = strbuff.split(",");  
	            x[i] = Integer.valueOf(strcol[1]);// x坐标  
	            y[i] = Integer.valueOf(strcol[2]);// y坐标  
	                   
	        }  
	        
	        // 计算距离矩阵  
	        for (int i = 0; i < cityNum - 1; i++) {  
	            distance[i][i] = 0; // 对角线为0  
	            for (int j = i + 1; j < cityNum; j++) {  
	             
	            	double rij = Math.sqrt(((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]))/10); 
	                
	                // 四舍五入,取整  
	                int tij = (int) Math.round(rij);  
	                if (tij < rij) {  
	                    distance[i][j] = tij + 1;  
	                    distance[j][i] = distance[i][j];  
	                } else {  
	                    distance[i][j] = tij;  
	                    distance[j][i] = distance[i][j];  
	                }  
	            }  
	        }  
	        distance[cityNum - 1][cityNum - 1] = 0;  
	  
	        Ghh = new int[cityNum];  
	        bestGhh = new int[cityNum];  
	        be = Integer.MAX_VALUE;  
	        tempGhh = new int[cityNum];  
	        te = Integer.MAX_VALUE;  
	        bestT = 0;  
	        random = new Random(System.currentTimeMillis());  
	          
	       // System.out.println(cityNum+","+N+","+T+","+a+","+t0);  
	  
	    }  
	  
	    // 初始化编码Ghh  
	    public static void initGroup() {  
	        int i, j;  
	        Ghh[0] = random.nextInt(65535) % cityNum;  
	        for (i = 1; i < cityNum;)// 编码长度  
	        {  
	            Ghh[i] = random.nextInt(65535) % cityNum;  //得到是小于cityNum的数
	            
	         //   System.out.println( Ghh[i]+"  "+i+"  "  );
	            for (j = 0; j < i; j++) {  
	                if (Ghh[i] == Ghh[j]) {  
	                    break;  
	                }  
	            }
	            
	           // System.out.println( Ghh[i]+"  "+i+"  * "  );
	            
	            if (j == i) {   //检查没有重复
	                i++;  
	            }    
	            
	        }  
	    }  
	  
	    // 复制编码Gha到Ghb  
	    public static void copyGh(int[] Gha, int[] Ghb) {  
	        for (int i = 0; i < cityNum; i++) {  
	            Ghb[i] = Gha[i];  
	        }  
	    }  
	  
	    // 计算距离
	    public static int evaluate(int[] chr) {  
	        
	        int len = 0;  
	        // 编码,起始城市,城市1,城市2...城市n  
	        for (int i = 1; i < cityNum; i++) {  
	            len += distance[chr[i - 1]][chr[i]];  
	        }  
	        // 城市n,起始城市  
	        len += distance[chr[cityNum - 1]][chr[0]];  
	        return len;  
	    }  
	  
	    // 邻域交换,得到邻域  ,随机两个值交换
	    public static void Linju(int[] Gh, int[] tempGh) {  
	        int i, temp;  
	        int ran1, ran2;  
	  
	        for (i = 0; i < cityNum; i++) {  
	            tempGh[i] = Gh[i];  
	        }  
	        ran1 = random.nextInt(65535) % cityNum;  
	        ran2 = random.nextInt(65535) % cityNum;  
	        while (ran1 == ran2) {  
	            ran2 = random.nextInt(65535) % cityNum;  
	        }  
	        temp = tempGh[ran1];  
	        tempGh[ran1] = tempGh[ran2];  
	        tempGh[ran2] = temp;  
	    }  
	  
	    public static int solve() {  
	        // 初始化编码Ghh  
	        initGroup();   //用随机的方式生成原始数列
	        copyGh(Ghh, bestGhh);// 复制当前编码Ghh到最好编码bestGh  
	        be = evaluate(Ghh);  
	        ge = be;  
	        int k = 0;// 降温次数  
	        int n = 0;// 迭代步数  
	        double t = t1;  
	        double r = 0.0;  
			 
	       int count=0;
	          
	        while (k < T) {  //降温次数  
	            n = 0;  
	            while (n < N) {  //每个温度迭代步长  
	                Linju(Ghh, tempGhh);// 得到当前编码Ghh的邻域编码tempGhh  
	                te = evaluate(tempGhh);  
	                if (te < be)  
	                {  
	                    copyGh(tempGhh, bestGhh);  
	                    bestT = k;  
	                    be = te;  
	                } 
	                
	                Random rand =new Random();
	                r = rand.nextDouble();  
	                
	                if (te < ge  ||Math.exp((ge - te)  /t) > r 
	                     //   ||  (GhhEvaluation == tempEvaluation)    
	                		) 
	                		
	                		{  
	                		
	                    copyGh(tempGhh, Ghh);  
	                    
	                    //随着温度的降低这个冗余度也会逐渐减小,所以增大初始温度,减慢温度下降速度更有利收敛
	                        
	                  if(   Math.abs(Math.exp((ge - te) / t)  -0)<0.00001  )
	                    {
	                    	       
	                    	count++;
	                    }
	                 
	                   ge = te;  
	                        
	                }  
	                n++;  
	            }  
	            
	        
	            t = a * t;  
	            //控制t值的可能范围,这个是最为核心的参数
	            
	          if(k==T-1)
	            {
	        System.out.println(t+"  "+a+"    "+k+"  "+count+ "  "+bestT);
	            }
	             
	            //0.08634329    2000
	            //0.043171644   1000
	            
	            k++;  
	        }  
	        
	        
	        if(be<min)
	        {
	        	min=be;
	        }
	        
	        return be;
	    }  
	  
	   
	    
	    public static void route() throws IOException {
	    	int max=100000;
	        
	    	  FileWriter fileWriter1=new FileWriter("d:/工业/hk/aaa.csv"); 
	    	  FileWriter fileWriter2=new FileWriter("d:/工业/hk/统计.csv"); 
	    	 
	    	  int count=0;

	    	         while(max>10628 )
	    	        {
	    	    	
	    	        	 count++;
	    	    	//城市数量         每个温度迭代次数        重复 降温次数        初始温度           降温系数 
	    	 
	    	           max= SA(48, 1000, 2000,  0.99815 , 1500, "d:/工业/hk/t/zz.csv" ); 
	    	         // N T a t1
	    	         
	    	         fileWriter2.write( max+","+min +"\r\n ");
	    	 	       fileWriter2.flush();
	    	        
	    	        System.out.println( max +"  ** ** "+count);
	    	        } 
	    	         
	    	         for (int i = 0; i < cityNum ; i++) {
	    		    	 
	    	   	      // System.out.println(bestTour[i][0]+"  ***  ");
	    	   	       
	    	   	       fileWriter1.write( bestGhh[i] +"\r\n ");
	    	   	       fileWriter1.flush();

	    	   	     }
	    	         
	    	         fileWriter1.write( bestGhh[0] +"\r\n ");
	    	 	       fileWriter1.flush();
	    	         
	    	         new  Line1();	 
	    		
	    }
	    
	    
	    
	    
	    public static void main(String[] args) throws IOException {  
	    	
	    	long sysDate1 = System.currentTimeMillis();
	    	route();
	    	long sysDate2 = System.currentTimeMillis();  

	    	System.out.println( (sysDate2-sysDate1) +"  ** ** " );
	    	    
	    }  
	}  
package plan;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;
import javax.swing.JFrame;


public class Line1 extends JFrame {
	 
    public Line1() {  
        super();  
        setBounds(0, 0, 2000, 2000);  
        addWindowListener(new WindowAdapter() {  
            public void windowClosing(WindowEvent ev) {  
                dispose();  
                System.exit(0);  
            }  
        });  
        setVisible(true);  
    }
    
    
    public static String read(String a) throws IOException{
		String as;
	{       
		  String tops="";
			BufferedReader ins=new BufferedReader(new FileReader(a));
			String ss;
			List<String> nns=new LinkedList<String>();
			while((ss=ins.readLine())!=null)
				nns.add(ss);
			String kps = nns.toString();
			kps = kps.substring(1,kps.length()-1);
             tops=kps;
			ins.close();
		
		 as=tops;
	}
	
	as=as.trim();
	 return as;
	
	}
      
    
    public void paint(Graphics g) {  
   
    	g.setColor(Color.white);  //底色
        
        g.setColor(Color.blue);  
        
        int r1=8;
        
        int r=7;
    	String we;
     
		try {
			
			coordinate( );
			
			we = read("d:/工业/hk/重排.csv");
			String[] te=Pattern.compile(",").split(we);
			
            
			double des=0.0;
			
			   for (int b =1 ;b<te.length/3 ;b++) 
			   {
				   
				   int bx=Integer.parseInt(te[(b-1)*3+1].trim())/r1;
				   int  by=Integer.parseInt(te[(b-1)*3+2].trim())/r;
				   
				   
				   int cx=Integer.parseInt(te[b*3+1].trim())/r1;
				   int  cy=Integer.parseInt(te[b*3+2].trim())/r;
				   
				   des=des+  Math.pow((Math.pow( (cx*r1-bx*r1) , 2) +Math.pow(cy*r-by*r, 2)),0.5);
			    
				     
				   int pyh=180;  //(+向右 -向左)
				   int pyz=800;  //(-向上  +向下)
				   
				   g.drawLine((pyh+bx),(pyz-by),(pyh+cx),(pyz-cy));
   
			   }
			   
			   g.setColor(Color.red);  
		        
		     //   g.drawLine(0,0,100,200);
		     //   g.drawLine(0,0,6743/20,1543/20);
			
		} catch (IOException e) {
		 
			e.printStackTrace();
		}	 
    
    
    }  
     
    
    public static void coordinate( ) throws IOException
    {
    	 
    	FileWriter fileWriter1=new FileWriter("d:/工业/hk/重排.csv");  
    	 	
    	String wee= read("d:/工业/hk/aaa.csv");
		
		String[] tee=Pattern.compile(",").split(wee);
		
		
        String we = read("d:/工业/hk/t/zz.csv");
		String[] te=Pattern.compile(",").split(we);
		
		
		   for (int z =0 ; z<tee.length ; z++) 
		   {
			  // System.out.println( z+"  z     " +Integer.parseInt( tee[z].trim())     );
			   
			   int d=Integer.parseInt( tee[z].trim());
		
		   for (int b =0 ;b<te.length/3 ;b++) 
		   {
			   
			   if(Integer.parseInt(te[b*3].trim())==(d +1)      )
			   {

			   fileWriter1.write( te[b*3] +","+te[b*3+1]+","+te[b*3+2]+"\r\n ");
			   fileWriter1.flush();
    
			   }
    
		   }
		   
		   }

    }
    

  
    public static void main(String[] args) throws IOException, ParseException {  
    	  	
    	 //SA1.route();
           
         new Line1(); 
    }  
}

d:/工业/hk/t/zz.csv

1

6734

1453

2

2233

10

3

5530

1424

4

401

841

5

3082

1644

6

7608

4458

7

7573

3716

8

7265

1268

9

6898

1885

10

1112

2049

11

5468

2606

12

5989

2873

13

4706

2674

14

4612

2035

15

6347

2683

16

6107

669

17

7611

5184

18

7462

3590

19

7732

4723

20

5900

3561

21

4483

3369

22

6101

1110

23

5199

2182

24

1633

2809

25

4307

2322

26

675

1006

27

7555

4819

28

7541

3981

29

3177

756

30

7352

4506

31

7545

2801

32

3245

3305

33

6426

3173

34

4608

1198

35

23

2216

36

7248

3779

37

7762

4595

38

7392

2244

39

3484

2829

40

6271

2135

41

4985

140

42

1916

1569

43

7280

4899

44

7509

3239

45

10

2676

46

6807

2993

47

5185

3258

48

3023

1942