-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathAcoCPU.cpp
135 lines (112 loc) · 3.83 KB
/
AcoCPU.cpp
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
#ifndef __ACO_CPU_CPP__
#define __ACO_CPU_CPP__
#include <stdint.h>
#include <vector>
#include <algorithm>
#include "Environment.cpp"
#include "Parameters.cpp"
#include "Ant.cpp"
#include "common.hpp"
template <typename T, typename D>
class AcoCPU {
private:
const Parameters<T> & params;
Environment<T, D> & env;
std::vector< Ant<T> > ants;
void initEta(std::vector<T> & eta,
const std::vector<T> & edges)
{
auto bEta = eta.begin();
auto bEdges = edges.begin();
while ( bEta != eta.end() ) {
T & etaVal = *(bEta++);
const T & edgeVal = *(bEdges++);
etaVal = (edgeVal == 0.0 ? 0.0 : 1.0 / edgeVal);
}
}
void calcFitness(std::vector<T> & fitness,
const std::vector<T> & pheromone,
const std::vector<T> & eta,
const T alpha,
const T beta)
{
auto bFitness = fitness.begin();
auto bPheromone = pheromone.begin();
auto bEta = eta.begin();
while ( bFitness != fitness.end() ) {
T & fitVal = *(bFitness++);
const T & pheromoneVal = *(bPheromone++);
const T & etaVal = *(bEta++);
fitVal = pow(pheromoneVal, alpha) * pow(etaVal, beta);
}
}
void calcTour(const std::vector<T> & fitness,
const std::vector<T> & edges)
{
for (Ant<T> & ant : ants) {
ant.constructTour(fitness, edges);
}
}
void updateBestTour(std::vector<uint32_t> & bestTour,
T & bestTourLength)
{
const Ant<T> & bestAnt = *std::min_element(ants.begin(), ants.end());
std::copy ( bestAnt.getTabu().begin(), bestAnt.getTabu().end(), bestTour.begin() );
bestTourLength = bestAnt.getTourLength();
}
void updateDelta(std::vector<D> & delta,
const uint32_t nCities,
const T q)
{
for (T & d : delta) {
d = 0.0;
}
for (Ant<T> & ant : ants) {
const T tau = q / ant.getTourLength();
auto bTabu = ant.getTabu().begin();
const auto constbTabu = bTabu;
while ( bTabu != ant.getTabu().end() - 1) {
const uint32_t from = *(bTabu++);
const uint32_t to = *(bTabu);
delta[from * nCities + to] += tau;
delta[to * nCities + from] += tau;
}
const uint32_t from = *(bTabu);
const uint32_t to = *(constbTabu);
delta[from * nCities + to] += tau;
delta[to * nCities + from] += tau;
}
}
void updatePheromone(std::vector<T> & pheromone,
const std::vector<D> & delta,
const T rho)
{
auto bPheromone = pheromone.begin();
auto bDelta = delta.begin();
while ( bPheromone != pheromone.end() ) {
T & pheromoneVal = *(bPheromone++);
const T & deltaVal = *(bDelta++);
pheromoneVal = pheromoneVal * rho + deltaVal;
}
}
public:
AcoCPU(const Parameters<T> & params, Environment<T, D> & env):
params(params),
env (env),
ants (env.nAnts, Ant<T>(env.nCities))
{
initEta(env.eta, env.edges);
}
void solve() {
uint32_t epoch = 0;
do {
calcFitness (env.fitness, env.pheromone, env.eta, params.alpha, params.beta);
calcTour (env.fitness, env.edges);
updateBestTour (env.bestTour, env.bestTourLength);
updateDelta (env.delta, env.nCities, params.q);
updatePheromone(env.pheromone, env.delta, params.rho);
} while ( ++epoch < params.maxEpoch );
}
~AcoCPU(){}
};
#endif