-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSSPInstance.java
More file actions
224 lines (199 loc) · 6.58 KB
/
Copy pathSSPInstance.java
File metadata and controls
224 lines (199 loc) · 6.58 KB
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
package com.aim.project.ssp.instance;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Random;
import com.aim.project.ssp.SSPObjectiveFunction;
import com.aim.project.ssp.interfaces.ObjectiveFunctionInterface;
import com.aim.project.ssp.interfaces.SSPInstanceInterface;
import com.aim.project.ssp.interfaces.SSPSolutionInterface;
import com.aim.project.ssp.interfaces.SolutionRepresentationInterface;
import com.aim.project.ssp.solution.SSPSolution;
import com.aim.project.ssp.solution.SolutionRepresentation;
/**
* Represents an SSP instance with various locations, including a hotel, an airport,
* and points of interest. The instance can generate solutions using different initialization modes.
*
* @author Sushant Nepal
* @since 17/03/2025
*/
public class SSPInstance implements SSPInstanceInterface {
private final Location[] aoLocations;
private final Location oHotelLocation;
private final Location oAirportLocation;
private final int iNumberOfLocations;
private final Random oRandom;
private final ObjectiveFunctionInterface f;
/**
* Constructs an SSPInstance with the given data.
*
* @param iNumberOfLocations The number of sightseeing locations.
* @param aoLocations An array of all the locations.
* @param oHotelLocation The location of the hotel.
* @param oAirportLocation The location of the airport.
* @param random A Random instance for generating random values.
*/
public SSPInstance(int iNumberOfLocations, Location[] aoLocations, Location oHotelLocation, Location oAirportLocation, Random random) {
this.iNumberOfLocations = iNumberOfLocations;
this.oRandom = random;
this.aoLocations = aoLocations;
this.oHotelLocation = oHotelLocation;
this.oAirportLocation = oAirportLocation;
this.f = new SSPObjectiveFunction(this);
}
/**
* Creates a solution based on the specified initialization mode.
*
* @param mode The mode for solution initialization (Random or Constructive).
* @return A new SSPSolution instance representing the solution.
* @throws IllegalArgumentException If an unsupported initialization mode is provided.
*/
@Override
public SSPSolution createSolution(InitialisationMode mode) {
int[] tour;
if (mode == InitialisationMode.RANDOM) {
tour = generateRandomTour();
} else if (mode == InitialisationMode.CONSTRUCTIVE) {
tour = generateGreedyTour();
} else {
throw new IllegalArgumentException("Unsupported InitialisationMode: " + mode);
}
// Create solution representation and calculate the cost
SolutionRepresentationInterface solution = new SolutionRepresentation(tour);
double cost = f.getObjectiveFunctionValue(solution);
return new SSPSolution(solution, cost);
}
/**
* Generates a random tour by shuffling the sightseeing locations.
*
* @return An array representing a random sightseeing tour.
*/
private int[] generateRandomTour() {
ArrayList<Integer> sightseeingIndices = new ArrayList<>();
for (int i = 0; i < iNumberOfLocations; i++) {
sightseeingIndices.add(i);
}
Collections.shuffle(sightseeingIndices, oRandom);
// Convert the shuffled list into an array
int[] tour = new int[iNumberOfLocations];
for (int i = 0; i < iNumberOfLocations; i++) {
tour[i] = sightseeingIndices.get(i);
}
return tour;
}
/**
* Generates a greedy tour by iteratively choosing the nearest unvisited location.
*
* @return An array representing a greedy sightseeing tour.
*/
private int[] generateGreedyTour() {
int[] tour = new int[iNumberOfLocations];
boolean[] visited = new boolean[iNumberOfLocations];
Arrays.fill(visited, false);
// Start with the nearest location to the hotel
int currentIndex = findNearestLocationToHotel();
tour[0] = currentIndex;
visited[currentIndex] = true;
// Find the nearest unvisited locations to form the rest of the tour
for (int i = 1; i < iNumberOfLocations; i++) {
int nearestIndex = -1;
double nearestDistance = Double.MAX_VALUE;
// Find the closest unvisited location
for (int j = 0; j < iNumberOfLocations; j++) {
if (!visited[j]) {
double distance = f.getCost(currentIndex, j);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestIndex = j;
}
}
}
tour[i] = nearestIndex;
visited[nearestIndex] = true;
currentIndex = nearestIndex;
}
return tour;
}
/**
* Finds the nearest sightseeing location to the hotel.
*
* @return The index of the nearest sightseeing location to the hotel.
*/
private int findNearestLocationToHotel() {
double nearestHotel = Double.MAX_VALUE;
int nearestLocation = -1;
for (int i = 0; i < iNumberOfLocations; i++) {
double distance = f.getCostBetweenHotelAnd(i);
if (distance < nearestHotel) {
nearestHotel = distance;
nearestLocation = i;
}
}
return nearestLocation;
}
/**
* Retrieves the objective function associated with this SSP instance.
*
* @return The objective function.
*/
@Override
public ObjectiveFunctionInterface getSSPObjectiveFunction() {
return f;
}
/**
* Returns the total number of locations, including the hotel and airport.
*
* @return The total number of locations.
*/
@Override
public int getNumberOfLocations() {
return iNumberOfLocations + 2; // Including hotel and airport
}
/**
* Retrieves a specific sightseeing location by its ID.
*
* @param iLocationId The ID of the location to retrieve.
* @return The corresponding Location object.
* @throws IllegalArgumentException If the location ID is invalid.
*/
@Override
public Location getSightseeingLocation(int iLocationId) {
if (iLocationId < 0 || iLocationId >= iNumberOfLocations) {
throw new IllegalArgumentException("Invalid sightseeing location ID: " + iLocationId);
}
return aoLocations[iLocationId];
}
/**
* Retrieves the hotel location.
*
* @return The hotel location.
*/
@Override
public Location getHotelLocation() {
return oHotelLocation;
}
/**
* Retrieves the airport location.
*
* @return The airport location.
*/
@Override
public Location getAirportLocation() {
return oAirportLocation;
}
/**
* Converts a solution representation to a list of locations.
*
* @param oSolution The solution to convert.
* @return A list of locations representing the solution.
*/
@Override
public ArrayList<Location> getSolutionAsListOfLocations(SSPSolutionInterface oSolution) {
int[] representation = oSolution.getSolutionRepresentation().getSolutionRepresentation();
ArrayList<Location> tourLocations = new ArrayList<>();
for (int locationId : representation) {
tourLocations.add(aoLocations[locationId]);
}
return tourLocations;
}
}