模拟退火算法总结(含例子)

一.模拟退火算法概述

  模拟退火算法来源于固体退火原理,将固体加温至充分高,再让其徐徐冷却,加温时,固体内部粒子随温升变为无序状,内能增大,而徐徐冷却时粒子渐趋有序,在每个温度都达到平衡态,最后在常温时达到基态,内能减为最小。根据Metropolis准则,粒子在温度T时趋于平衡的概率为e-ΔE/(kT),其中E为温度T时的内能,ΔE为其改变量,k为Boltzmann常数。用固体退火模拟组合优化问题,将内能E模拟为目标函数值f,温度T演化成控制参数t,即得到解组合优化问题的模拟退火算法:由初始解i和控制参数初值t开始,对当前解重复“产生新解→计算目标函数差→接受或舍弃”的迭代,并逐步衰减t值,算法终止时的当前解即为所得近似最优解,这是基于蒙特卡罗迭代求解法的一种启发式随机搜索过程。退火过程由冷却进度表(Cooling Schedule)控制,包括控制参数的初值t及其衰减因子Δt、每个t值时的迭代次数L和停止条件S。

二.流程图

Java代码   收藏代码
  1. 伪码描述:    
  2. Simulated-Annealing()    
  3. Create initial solution S    
  4. repeat    
  5.     for i=1 to iteration-length do    
  6.         Generate a random transition from S to Si    
  7.         If ( C(S) <= C(Si) ) then    
  8.             S=Si    
  9.         else if( exp(C(S)-C(Si))/kt > random[0,1) ) then    
  10.             S=Si    
  11.     Reduce Temperature t    
  12. until ( no change in C(S) )    
  13.     
  14. C(S): Cost or Loss function of Solution S    
  三.旅行商问题上的应用

    旅行商问题就是指旅行商按一定的顺序访问N个城市的每个城市,使得每个城市都能被访问且仅能被访问一次,最后回到起点,而使花费的代价最小。本例中从第0个城市开始然后回到原点.

示例代码:

Java代码   收藏代码
  1. /**  
  2.  *   
  3.  */    
  4. package anneal.tsp;    
  5.     
  6. import java.io.BufferedReader;    
  7. import java.io.File;    
  8. import java.io.FileReader;    
  9. import java.io.IOException;    
  10. import java.util.Arrays;    
  11. import java.util.Random;    
  12.     
  13. /**  
  14.  * @author Dukie 下午02:22:13 2010  
  15.  *   
  16.  */    
  17. public class Anneal {    
  18.     
  19.     private  static double[][] city;    
  20.     private  static int[] currPath;    
  21.     private  static int[] bestPath;    
  22.     private  static double shortesDistance;    
  23.     private  static int numOfCity = 20;    
  24.     //trace item    
  25.     private static int iterator = 0;    
  26.     
  27.     public void printInfo() {    
  28.         System.out.println("bestPath: " + Arrays.toString(bestPath));    
  29.         System.out.println("shortest distance: " + shortesDistance);    
  30.         System.out.println("iterator times: " + iterator);    
  31.     }    
  32.     
  33.     private void init() throws IOException {    
  34.         city = new double[numOfCity][numOfCity];    
  35.         currPath = new int[numOfCity];    
  36.         bestPath = new int[numOfCity];    
  37.         shortesDistance = 0;    
  38.         loadCity();    
  39.         int lenth = currPath.length;    
  40.         for (int i = 0; i < lenth; i++) {    
  41.             currPath[i] = i;    
  42.         }    
  43.     }    
  44.     
  45.     private void loadCity() throws IOException {    
  46.         //DistanceMatrix.csv" a file stores the distance info.    
  47.         File file = new File("E:\\TSP\\DistanceMatrix.csv");    
  48.         inputGraph(file, city);    
  49.     }    
  50.     
  51.     private void inputGraph(File file, double[][] city) throws IOException {    
  52.         BufferedReader in = new BufferedReader(new FileReader(file));    
  53.         String str = "";    
  54.         int length = 0;    
  55.         while ((str = in.readLine()) != null) {    
  56.             str = str.replaceAll(", "",");    
  57.             String[] line = str.split(",");    
  58.             for (int j = 0; j < numOfCity; j++)    
  59.                 // ten cities    
  60.                 city[length][j] = Double.parseDouble(line[j]);    
  61.             length++;    
  62.         }    
  63.     }    
  64.     
  65.     /**  
  66.      * key function  
  67.      * @throws IOException  
  68.      */    
  69.     public void anneal() throws IOException {    
  70.     
  71.         double temperature = 10000.0D;    
  72.         double deltaDistance = 0.0D;    
  73.         double coolingRate = 0.9999;    
  74.         double absoluteTemperature = 0.00001;    
  75.     
  76.         init();    
  77.     
  78.         double distance = getToatalDistance(currPath);    
  79.     
  80.         int[] nextPath;     
  81.         Random random = new Random();    
  82.         while (temperature > absoluteTemperature) {    
  83.             nextPath = generateNextPath();    
  84.             deltaDistance = getToatalDistance(nextPath) - distance;    
  85.     
  86.             if ((deltaDistance < 0)    
  87.                     || (distance > 0 &&     
  88.                           Math.exp(-deltaDistance / temperature) > random.nextDouble())) {    
  89.                 currPath = Arrays.copyOf(nextPath, nextPath.length);    
  90.                 distance = deltaDistance + distance;    
  91.             }    
  92.     
  93.             temperature *= coolingRate;    
  94.             iterator++;    
  95.             System.out.println("iterator: " + iterator + " path: " + Arrays.toString(currPath));    
  96.         }    
  97.         shortesDistance = distance;    
  98.         System.arraycopy(currPath, 0, bestPath, 0, currPath.length);    
  99.     
  100.     }    
  101.     
  102.     /**  
  103.      * calculate total distance  
  104.      * @param currPath  
  105.      * @return  
  106.      */    
  107.     private double getToatalDistance(int[] currPath) {    
  108.         int length = currPath.length;    
  109.         double totalDistance = 0.0D;    
  110.         for (int i = 0; i < length - 1; i++) {    
  111.             totalDistance += city[currPath[i]][currPath[i + 1]];    
  112.         }    
  113.         totalDistance += city[currPath[length - 1]][0];    
  114.     
  115.         return totalDistance;    
  116.     }    
  117.     
  118.     /**  
  119.      * swap two elements in the old array to genreate new array  
  120.      * @return  
  121.      */    
  122.     private int[] generateNextPath() {    
  123.         int[] nextPath = Arrays.copyOf(currPath, currPath.length);    
  124.         Random random = new Random();    
  125.         int length = nextPath.length;    
  126.         int fistIndex = random.nextInt(length - 1) + 1;    
  127.         int secIndex = random.nextInt(length - 1) + 1;    
  128.         while (fistIndex == secIndex) {    
  129.             secIndex = random.nextInt(length - 1) + 1;    
  130.         }    
  131.         int tmp = nextPath[fistIndex];    
  132.         nextPath[fistIndex] = currPath[secIndex];    
  133.         nextPath[secIndex] = tmp;    
  134.     
  135.         return nextPath;    
  136.     }    
  137.     
  138. }    

 20个城市测试数据:

Java代码   收藏代码
  1. 0118931463310172807812843100791439580561423211714930912517115749720137271385214330106608138    
  2. 1189301056890311105090391062214138873891228817130999984130631154611379885014111137758073    
  3. 1463310568014174133381262914418103911444412956140401283513486142491403981861473088861286212365    
  4. 1017290311417409422118141413311645104951309914712149881166214561133501078114886115491304411194    
  5. 8078110501333894220986811492124161467212894111811431092311269712617885611850133021255811165    
  6. 128439039126291181498680100691060587999295140781234914367950111379134311072388451042714821    
  7. 10079106221441814133114921006901273486561383012681131651158386109202983810755106741388113024    
  8. 1439514138103911164512416106051273401198013753111741460313478125431297411059879911781137979287    
  9. 8056873814444104951467287998656119800111088725112531227713086947612513959711850138668605    
  10. 14232912212956130991289492951383013753111080143018065137069212830182581481792771274214550    
  11. 11714881714040147121118114078126811117487251430108133138419062107041336613779137101283212812    
  12. 93091309912835149881431012349131651460311253806581330807995549760116171056693821210511755    
  13. 12517998413486116629231143671158313478122771370613841807909991147171308211787146141169810970    
  14. 115741306314249145611269795018610125431308692129062955499910143638175123099042112519250    
  15. 97201154614039133501261711379920212974947683011070497601471714363012291121731097190009868    
  16. 13727113798186107818856134319838110591251382581336611617130828175122910142911291595839671    
  17. 1385288501473014886118501072310755879995971481713779105661178712309121731429101365786219089    
  18. 143301411188861154913302884510674117811185092771371093821461490421097112915136570970910960    
  19. 10660137751286213044125581042713881137971386612742128321210511698112519000958386219709013131    
  20. 8138807312365111941116514821130249287860514550128121175510970925098689671908910960131310    
 在我机上对20个顸城市进行测试后,效果比较好. 对10城市时,在几秒钟来就达到全局最优解.

注意:模拟退火算法与初始值无关,算法求得的解与初始解状态S(是算法迭代的起点)无关;模拟退火算法具有渐近收敛性,已在理论上被证明是一种以概率l 收敛于全局最优解的全局优化算法;模拟退火算法具有并行性。

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值