-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTour.cpp
More file actions
137 lines (126 loc) · 3.55 KB
/
Tour.cpp
File metadata and controls
137 lines (126 loc) · 3.55 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
//
// Created by danny on 2018-11-08.
//
#include "Tour.hpp"
/**
* Default constructor, initializes fitness and distance to 0, and fills
* vector of cities if it is not constructed as a child.
* If it is constructed as a child, it is initialized with an empty vector
* @param child boolean determining if tour is a child or not
*/
Tour::Tour(bool child) : fitness{0}, distance{0} {
if (!child) {
for (int i = 0; i < CITIES_IN_TOUR; ++i) {
cities.emplace_back();
}
determineFitness();
getTourDistance();
}
}
/**
* Gets the city at given index in the tour
* @param position index position
* @return City at index
*/
inline City & Tour::getCity(int position) {
return cities.at(static_cast<unsigned long>(position));
}
/**
* Shuffles cities in the tour 'SHUFFLES' number of times
*/
void Tour::shuffleCities() {
for (int i = 0; i < SHUFFLES; ++i) {
swapCities();
}
}
/**
* Swaps two cities in a tour from random indexes
*/
void Tour::swapCities() {
auto tourPosition1 = RandomNumGenerator::getInstance().
getIntegerInRange(0, CITIES_IN_TOUR - 1);
auto tourPosition2 = RandomNumGenerator::getInstance().
getIntegerInRange(0, CITIES_IN_TOUR - 1);
swap(cities.at((unsigned long) tourPosition1), cities.at((unsigned long) tourPosition2));
}
/**
* Calculates entire distance of the tour based on city order
* @return total tour distance
*/
int Tour::getTourDistance() {
if (distance == 0) {
int tourDistance = 0;
for (unsigned long cityIndex = 0; cityIndex < cities.size(); cityIndex++) {
City originCity = getCity((int) cityIndex);
City toCity;
// Check we're not on our tour's last city
if (cityIndex + 1 < cities.size()) {
toCity = getCity((int) cityIndex + 1);
}
// if we are on our tour's final destination city, set it to our starting city
// so we get the distance between the first and last city
else {
toCity = getCity(0);
}
// Get the distance between the two cities
tourDistance += (int) originCity.getDistanceBetweenCities(toCity);
}
distance = tourDistance;
}
return distance;
}
/**
* Calculates fitness of the tour, multiplied by a scalar (1 million)
* for a more readable value
* @return fitness value
*/
double Tour::determineFitness() {
if (fitness == 0) {
fitness = (1/(double) getTourDistance()) * 1000000;
}
return fitness;
}
/**
* Checks if a tour contains a given city
* @param city1 city being searched for
* @return boolean true if tour contains city
*/
bool Tour::containsCity(City city1) {
auto it = find(cities.begin(), cities.end(), city1);
return it != cities.end();
}
/**
* Getter for tour vector
* @return cities vector
*/
vector<City> &Tour::getTour() {
return cities;
}
/**
* Overloaded insertion operator
* @param os output stream
* @param t tour being output
* @return output to console
*/
ostream &operator<<(ostream &os, Tour &t) {
for (City &c : t.getTour()) {
os << c;
}
return os;
}
/**
* Overloaded equals operator to determine if tours are equal
* @param t tour being compared
* @return true if tours are equal
*/
bool Tour::operator==(Tour &t) {
return (fitness == t.fitness);
}
/**
* Overloaded comparison operator used in sorting tours
* @param t tour being compared
* @return true or false
*/
bool Tour::operator<(const Tour &t) const {
return fitness > t.fitness;
}