標籤:eal imu 數列 double 思想 span dom png wap
嗯哼,今天記錄下採用Java編寫的爬山演算法(Hill Algorithm)求解TSP問題。
爬山演算法與其他智能演算法類似,是一種用來求解多峰函數最值的演算法,爬山演算法的基本思想是新解不劣於當前解則轉移,否則不轉移。通俗的解說是兔子爬山的例子,其他部落格上介紹的十分細緻,在此不再贅述。
爬山演算法的演算法描述為:
-
- Step1:初始化。通過某種方法產生初始解S0,令當前解S = S0,全域最優解的值bs = inf,全域最優解BS = S0,當前迭代次數count = 0,最大迭代次數為MaxCount;
- Step2:評價當前解。通過評價函數 Eval() 對當前解S進行評價;
- Step3:更新最優解。如果 Eval(S) 優於(或不劣於) bs,則令全域最優解BS = S,全域最優解的值bs = Eval(BS);
- Step3:更新當前解。令當前解S = BS,迭代次數count++;
- Step4:終止條件判定。如果count < MaxCount, 轉至Step2,否者終止程式,輸出結果。
下面上乾貨:
1 package Hill_Algorithm; 2 3 import java.util.Random; 4 5 /** 6 * @file_name SATSP.java 7 * @author xzl 8 * @date 2018年8月11日 9 * @detail Simulated Annealing to solve Travel Salesman Problem10 */11 12 public class HATSP {13 14 public static double[] HA() {15 16 //參數列表17 int MaxCount = 10000;18 19 //初始化20 double[][] xy = Data.XY();21 int N = xy.length;22 23 double bs ;24 double Nowbs;25 int[] BS = new int[N];26 int[] S = new int[N];27 28 //產生隨機初始解29 for (int i = 0; i < N; i++) {30 S[i] = i + 1;31 }32 for (int k = 0; k < N;k++) {33 Random rand = new Random();34 int r = rand.nextInt(N);35 int tmp;36 tmp = S[r];37 S[r] = S[k];38 S[k] = tmp;39 }40 bs = Evaluate.Eval(S);41 42 //進入迭代過程43 int effI = 0;44 for (int count = 0; count < MaxCount; count++) {45 46 //產生一個新解47 int[] newS = new int[N];48 double R = Math.random();49 50 if (R < 0.33) {51 newS = Sharking.Swap(S);52 }else if (R > 0.67) {53 newS = Sharking.Insert(S);54 }else {55 newS = Sharking.Flip(S);56 }57 Nowbs = Evaluate.Eval(newS); 58 59 //解的更新60 if (Nowbs < bs) {61 bs = Nowbs;62 effI++;63 System.out.println( "第 " + effI + "次有效迭代出現在第 " + count + "次迭代,對應的解為 " + bs);64 System.arraycopy(newS, 0, BS, 0, N);65 }66 System.arraycopy(BS, 0, S, 0, N);67 }68 69 //結果輸出70 double[] Solution = new double[N + 2];71 Solution[0] = bs;72 Solution[1] = MaxCount;73 74 for (int i = 2; i < N+2; i++) {75 Solution[i] = BS[i-2];76 }77 return Solution;78 }79 }
求解31個城市的TSP,求解結果如下,程式總迭代次數為10000次,有效迭代次數為89次,最後一次有效迭代出現在第3637次。與目前已知最優解誤差0.16%。
Java版HA_TSP