-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtraveling_salesman.h
334 lines (286 loc) · 10.9 KB
/
traveling_salesman.h
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
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
/**
* Hannah B, Ashton C, Kelechi E
* traveling_salesman.h
* Header file for Traveling Salesman Project library
*/
#ifndef TRAVELLING_SALESMAN_H
#define TRAVELLING_SALESMAN_H
#include <vector>
#include <string>
using std::string;
namespace TravelingSalesman {
/**
* @brief Returns current time as string for use in file names.
* @returns string in format YYYYMMDDHHMMSS
*/
string get_now();
/**
* @class Address
* @brief Represents a single destination along a traveling salesman's route.
*/
class Address {
private:
int i, j, deliver_by;
public:
/**
* @brief Constructor for Address class.
* @param i horizontal coordinate of address in arbitrary units
* @param j vertical coordinate of address in arbitrary units
* @param deliver_by (WIP) number of days after day 0 by which the order must be fulfilled
*/
Address(int i, int j, int deliver_by);
/**
* @brief Destructor for Address class.
*/
~Address();
/**
* @brief Calculates the distance from this Address to other.
*
* Note that this function could be implemented to return the Cartesian birds-eye distance or Manhattan distance, depending on what best suits the road layout in your hypothetical region.
*
* @param other address to which distance is computed
* @returns magnitude of Cartesian or Manhattan distance
*/
double distance(const Address& other);
/**
* @brief equality operator of Address Objects
* @param rhs "right-hand side" address Object to be compared
* @returns True the Addresses have the same coordinates. It does not consider the deliver_by date.
*/
bool operator==(const Address& rhs);
/**
* @brief accessor method to retrieve i,j coordinates of an Address
* @returns vector with i,j coordinates (in respective order)
*/
std::vector<int> get_coords();
/**
* @brief Accessor method to retrieve deliver_by of an Address
* @returns deliver_by
*/
int get_deliver_by();
/**
* @brief Setter method to change deliver_by of an Address
* @param deliver_by new deliver_by date
*/
void set_deliver_by(int deliver_by);
/**
* @brief displays the cartesian coordinates of an Address point
*/
void display();
/**
* @brief Represents the attributes of Address as a single string.
* @returns i, j, and deliver_by attributes on a single line, separated by spaces
*/
string to_string();
};
/**
* @class AddressList
* @brief Holds a vector of Addresses
*/
class AddressList{
protected:
std::vector<Address> address_vec;
public:
/**
* @brief Default constructor for AddressList class
*/
AddressList();
/**
* @brief Parameterized constructor for AddressList class
* @param address_vec vector of Object type "Address"
*/
AddressList(std::vector<Address> address_vec);
/**
* @brief Destructor for AddressList class.
*/
~AddressList();
/**
* @brief Appends a new Address object. If the Address is already in the AddressList, it takes the earlier deliver_by date of the two.
* @param new_address New Address object to be appended
* @returns None
*/
void add_address(Address new_address);
/**
* @brief Removes the first occurring last due Address.
*
* Of whatever set of Addresses in the list have the greatest deliver_by date, the one which occurs first in the AddressList is removed.
*
* @note SHOULD THIS BE RETURN BY REFERENCE????
*
* @returns a pointer to the removed Address
*/
Address remove_least_priority();
/**
* @brief Calculates distance one has to visit all addresses in order
* @returns Total distance
*/
double length();
/**
* @brief accessor method for address_vec vector length
* @returns length of vector address_vec
*/
int size();
/**
* @brief accessor method for address_vec (0-indexed)
* @param i index of address
* @returns address Object corresponding to index
*/
Address at(int i);
/**
* @brief Locates closest Address nearby
* @param main Address (relative origin point) from which the closest address is determined
* @returns index of Address closest to "main" Addresss
*/
int index_closest_to(Address main);
/**
* @brief removes ith Address from address_vec
* @param i 0-based index at which the Address is located
* @returns Address removed from address_vec
*/
Address pop(int i);
/**
* @brief Displays a row of all cartesian points in an AddressList object
*/
void display();
/**
* @brief Returns vector of AddressList.
* @returns Address vector of addresses in AddressList, in order.
*/
std::vector<Address> get_vec();
/**
* @brief Reverse order of given range of elements in a vector
* @param i starting 0-based index of reverse range
* @param j ending 0-based index of reverse range
* @param byref if true, the modified vector will take the place current address_vec,
* otherwise the current_vec will not be updated to the modified vector
* @returns Modified Address vector (byref=false) or empty vector (byref=true)
*/
std::vector<Address> reverse(int i, int j, bool byref=false);
/**
* @brief Reads in an AddressList from a .dat file.
* @param fname name of the file
* @returns new AddressList
*/
static AddressList from_dat(string fname);
/**
* @brief Writes the AddressList to a .dat file.
*
* Creates a matrix with rows corresponding to each Address and columns representing the i and j coordinates and deliver_by, separated by spaces.
*
* @param fname name of the file
*/
void to_dat(string fname);
};
/**
* @class Route
* @brief AddressList with a hub Address.
*/
class Route : public AddressList {
private:
Address hub;
public:
/**
* @brief Paramaterized constructor for Route class.
* @param address_vec Address vector of delivery addresses.
* @param hub Address of base station.
*/
Route(std::vector<Address> address_vec, Address hub);
/**
* @brief Paramaterized constructor for Route class.
* @param address_list AddressList of delivery addresses.
* @param hub Address of base station.
*/
Route(const AddressList& address_list, Address hub);
/**
* @brief Destructor for Route class.
*/
~Route();
/**
* @brief Accessor method for Route hub
* @returns The hub (Address Object) of the Route
*/
Address get_hub();
/**
* @brief Constructs new route based on greedy method algorithm.
*
* Iteratively caculates the next shortest address until all addresses have been reached starting at the hub.
*
* @returns newly constructed Route with same starting hub
*/
Route greedy_route();
/**
* @brief Uses the opt-2 heuristic to construct a new (shorter) route.
*
* See https://en.wikipedia.org/wiki/2-opt for more on the heuristic.
*
* @returns Route Object.
*/
Route opt2();
void opti_opt2();
/**
* @brief Swaps segment of Route with the segments of another Route
* @param route2 Route to be swapped with
* @param i Starting index of route 1 segment
* @param j Ending index of route 1 segment
* @param n Starting index of route 2 segment
* @param m Ending index of route 2 segment
* @see https://en.wikipedia.org/wiki/2-opt for more on the heuristic.
*
* @returns None
*/
void swap(Route& route2, int i, int j, int n, int m);
/**
* @brief Uses the opt-2 heuristic to optimize TWO Route Objects simeltaneously
*
* @see https://en.wikipedia.org/wiki/2-opt for more on the heuristic.
*
*/
void multi_opt2(Route& path2);
/**
* @brief Displays a row of Address Objects within a given Route
*/
void display();
/**
* @brief Calculates distance needed starting from hub to reach all addresses and return back to hub.
* @returns Total distance
*/
double length();
/**
* @brief Writes the Route to a .dat file.
*
* Creates a matrix with rows corresponding to each Address and columns representing the i and j coordinates. The first and last row are the hub, while the coordinates in between are the Address objects in the AddressList, in order.
*
* @param fname name of the file
*/
void to_dat(string fname);
/**
* @brief Writes the Route to a .dat file.
*
* Creates a matrix with rows corresponding to each Address and columns representing the i and j coordinates. The first and last row are the hub, while the coordinates in between are the Address objects in the AddressList, in order. By default, the file name is in the format yyyymmddhhmmss.dat
*/
void to_dat();
/**
* @brief Writes the Route to a .txt file to TikZ specification, for use in LaTeX.
* @param fname name of the file
* @param hub_color color of hub, red by default
* @param address_color color of addresses, black by default
* @param route_color color of lines, black by default
* @param route_arrow TikZ arrow specification, none by default
*/
void to_tikz(string fname, string hub_color = "red", string address_color = "black", string route_color = "black", string route_arrow = "");
/**
* @brief Writes the Route to a .txt file to TikZ specification, for use in LaTeX.
*
* By default, file name is in the format yyyymmddhhmmss.tikz
*/
void to_tikz();
/**
* @brief Writes the route to a .txt file readable by a delivery druver.
*/
void to_job(string fname);
};
/**
* @todo use opt2 heuristic for multipath problem
*/
}
#endif