###前提・実現したいこと
Javaで山登り法というアルゴリズムを用いて,2つの都市を入れ替え続けるというソースコードです.最終的にツアーの経路がより短い物を選ぶというものです.
HillClimbingクラスのstepメソッドの中身が具体的に何をしているのかが理解できません.どなたか教えていただけると助かります.
###該当のソースコード
Java
1package tsp.impl; 2 3import java.util.ArrayList; 4import java.util.List; 5import java.util.Random; 6 7import tsp.AbstractTSPSolver; 8import tsp.Point; 9 10public class HillClimbing extends AbstractTSPSolver { 11 public HillClimbing(List<Point> points) { 12 super(points); 13 } 14 15 @Override 16 public void run() { 17 if (this.currentState.getPoints().size() <= 3) 18 return; 19 20 while (step()) { 21 System.out.println("crimb."); 22 } 23 } 24 25 // 1 step 進め、解が改ざんされたならば true を返す。 26 // 2つ選んで良くなるものを交換する、ということを繰り返す。 27 // i, j が並んでいる時は、(j == i + 1 とする) 28 // i-1, i, j, j+1 が、i-1, j, i, j + 1 になるので、 29 // -d(i-1, i)-d(i+1,i+2) 30 // +d(i-1, i+1)+d(i,i+2) 31 32 // 並んでいないときは、 33 // i-1, i, i + 1, ..., j - 1, j, j + 1 34 // -d(i-1, i)-d(i, i+1)-d(j-1, j)-d(j, j+1) 35 // +d(i-1, j)+d(j, i+1)+d(j-1, i)+d(i, j+1) 36 37 public boolean step() { 38 final int N = currentState.size(); 39 40 double maxImprove = 0; 41 int iMaxImprove = -1, jMaxImprove = -1; 42 43 // points[0] の位置は固定にする。 44 for (int i = 1; i < N - 1; ++i) { 45 for (int j = i + 1; j < N; ++j) { 46 double improvedScore = scoreImprovementIfSwapped(i, j); 47 if (maxImprove < improvedScore) { 48 maxImprove = improvedScore; 49 iMaxImprove = i; 50 jMaxImprove = j; 51 } 52 } 53 } 54 55 System.out.printf("maxImprove = %f, i = %d, j = %d\n", maxImprove, iMaxImprove, jMaxImprove); 56 57 if (iMaxImprove <= 0) 58 return false; 59 60 currentState.swap(iMaxImprove, jMaxImprove); 61 return true; 62 } 63 64 public double scoreImprovementIfSwapped(int i, int j) { 65 assert (i < j); 66 if (j == i + 1) { 67 double removedDist = currentState.distance(i-1,i) + currentState.distance(i+1,i+2); 68 double addedDist = currentState.distance(i-1, i+1) + currentState.distance(i, i+2); 69 double improvedDist = removedDist - addedDist; 70 return improvedDist; 71 } else { 72 double removedDist = currentState.distance(i-1, i) + currentState.distance(i, i+1) + currentState.distance(j-1, j) + currentState.distance(j, j+1); 73 double addedDist = currentState.distance(i-1, j) + currentState.distance(j, i+1) + currentState.distance(j-1, i) + currentState.distance(i, j+1); 74 double improvedDist = removedDist - addedDist; 75 return improvedDist; 76 } 77 } 78 79 public static void main(String[] args) { 80 81 List<Point> points = new ArrayList<Point>(); 82 83 for (int i = 0; i < 5; i++) { 84 85 //Randomクラスのインスタンス化 86 Random rnd = new Random(); 87 88 double x = rnd.nextDouble() * rnd.nextInt(100); 89 double y = rnd.nextDouble() * rnd.nextInt(100); 90 91 Point p = new Point(x, y); 92 93 points.add(i, p); 94 95 96 } 97 98 HillClimbing hc = new HillClimbing(points); 99 100 hc.run(); 101 hc.showFinalResult(); 102 103 } 104 105} 106 107package tsp; 108 109import java.util.List; 110 111public abstract class AbstractTSPSolver implements TSPSolver { 112 protected TSPState currentState; 113 114 protected AbstractTSPSolver(List<Point> points) { 115 this.currentState = new TSPState(points); 116 } 117 118 @Override 119 public final TSPState getBestState() { 120 return currentState; 121 } 122 123 public final void showFinalResult() { 124 System.out.println("Best found score: " + currentState.getScore()); 125 126 for (Point p : currentState.getPoints()) 127 System.out.println(p); 128 } 129 130 public abstract void run(); 131 public abstract boolean step(); 132 133} 134 135 136package tsp; 137 138import java.util.ArrayList; 139import java.util.Collections; 140import java.util.List; 141 142public class TSPState { 143 private final ArrayList<Point> points; 144 private boolean scoreCalculated = false; 145 private double score; 146 147 public TSPState(List<Point> points) { 148 this.points = new ArrayList<Point>(points); 149 this.scoreCalculated = false; 150 this.score = 0; 151 } 152 153 public TSPState(TSPState s) { 154 this.points = new ArrayList<Point>(s.getPoints()); 155 this.scoreCalculated = s.scoreCalculated; 156 this.score = s.score; 157 } 158 159 public int size() { 160 return points.size(); 161 } 162 163 public List<Point> getPoints() { 164 return Collections.unmodifiableList(points); 165 } 166 167 public List<Point> getMutablePoints() { 168 scoreCalculated = false; 169 return points; 170 } 171 172 public double getScore() { 173 if (!scoreCalculated) { 174 score = calculateScore(); 175 scoreCalculated = true; 176 } 177 178 return score; 179 } 180 181 private double calculateScore() { 182 if (points.size() <= 1) 183 return 0; 184 185 double sumDistance = 0; 186 for (int i = 1; i < points.size(); ++i) { 187 Point p1 = points.get(i - 1); 188 Point p2 = points.get(i); 189 190 sumDistance += p1.attDistance(p2); 191 } 192 193 sumDistance += 194 points.get(0).attDistance(points.get(points.size() - 1)); 195 return sumDistance; 196 197 } 198 199 // 点P_1とP_jの距離を返す 200 public double distance(int i, int j) { 201 Point p1 = points.get(i % points.size()); 202 Point p2 = points.get(j % points.size()); 203 return p1.attDistance(p2); 204 } 205 206 // 点Pi, Pjを入れ替える 207 public void swap(int i, int j) { 208 Point p = points.get(i); 209 points.set(i, points.get(j)); 210 points.set(j, p); 211 212 scoreCalculated = false; 213 } 214 215 216} 217 218 219package tsp; 220 221public interface TSPSolver { 222 // 現在の状態集合の中で最もよいものを得る。1つしかなければそれを返す。 223 public TSPState getBestState(); 224 225 // 計算を 1step 進める 226 public abstract boolean step(); 227} 228 229package tsp; 230 231public class Point { 232 public double x, y; 233 public Point(double x, double y) { 234 this.x = x; 235 this.y = y; 236 } 237 238 public double distance(Point p) { 239 double dx = x - p.x; 240 double dy = y - p.y; 241 return Math.sqrt(dx * dx + dy * dy); 242 } 243 244 public double attDistance(Point p) { 245 double dx = x - p.x; 246 double dy = y - p.y; 247 double r = Math.sqrt((dx * dx + dy * dy) / 10); 248 double t = Math.round(r); 249 if (t < r) 250 return t + 1; 251 else 252 return t; 253 } 254 255@Override 256 public String toString() { 257 return "Point [x=" + x + ", y=" + y + "]"; 258 } 259 260}
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。