/
TSP2OptHeuristic.java
78 lines (69 loc) · 2.48 KB
/
TSP2OptHeuristic.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/* Copyright 2009-2024 David Hadka
*
* This file is part of the MOEA Framework.
*
* The MOEA Framework is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* The MOEA Framework is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the MOEA Framework. If not, see <http://www.gnu.org/licenses/>.
*/
package org.moeaframework.examples.ga.tsplib;
/**
* Implementation of the 2-opt heuristic for the traveling salesman problem.
* The 2-opt heuristic searches for any two edges in a tour that can be
* rearranged to produce a shorter tour. For example, a tour with any edges
* that intersect can be shortened by removing the intersection.
*/
public class TSP2OptHeuristic {
/**
* The traveling salesman problem instance.
*/
private final TSPInstance instance;
/**
* Constructs a new 2-opt heuristic for the specified traveling salesman
* problem instance.
*
* @param instance the traveling salesman problem instance
*/
public TSP2OptHeuristic(TSPInstance instance) {
super();
this.instance = instance;
}
/**
* Applies the 2-opt heuristic to the specified tour.
*
* @param tour the tour that is modified by the 2-opt heuristic
*/
public void apply(Tour tour) {
DistanceTable distanceTable = instance.getDistanceTable();
boolean modified = true;
// tours with 3 or fewer nodes are already optimal
if (tour.size() < 4) {
return;
}
while (modified) {
modified = false;
for (int i = 0; i < tour.size(); i++) {
for (int j = i+2; j < tour.size(); j++) {
double d1 = distanceTable.getDistanceBetween(tour.get(i), tour.get(i+1)) +
distanceTable.getDistanceBetween(tour.get(j), tour.get(j+1));
double d2 = distanceTable.getDistanceBetween(tour.get(i), tour.get(j)) +
distanceTable.getDistanceBetween(tour.get(i+1), tour.get(j+1));
// if distance can be shortened, adjust the tour
if (d2 < d1) {
tour.reverse(i+1, j);
modified = true;
}
}
}
}
}
}