-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathant_way_finder.cpp
137 lines (127 loc) · 4.4 KB
/
ant_way_finder.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
136
137
#include <iostream>
#include "graph.hpp"
#include "ant.hpp"
#include "chooser.hpp"
#include <exception>
#include <cmath>
#include <thread>
#include <future>
#include <algorithm>
#include <ctime>
#include <boost/program_options.hpp>
namespace po = boost::program_options;
inline void print_way(const std::vector < edge >& way) {
std::cout << "way weight = " << std::accumulate(way.begin(), way.end(), 0.0,
[&](const double old, const edge& e) { return old + e.weight; }) << std::endl;
if (way.empty()) {
return;
}
std::cout << way[0].from + 1;
for (auto it : way) {
std::cout << "->" << it.to + 1;
}
std::cout << std::endl;
}
void print_graph_edges(const graph& gr) {
for (size_t v = 0; v < static_cast<size_t>(gr.size()); ++v) {
for (const edge& e : gr.get_edges_from_vertex(v)) {
if (e.from > e.to) {
continue;
}
std::cout << e.from + 1 << "->" << e.to + 1 << " index: "
<< e.index << " sweetness: " << gr.get_sweetness(e.index)
<< " weight: " << e.weight << std::endl;
}
}
}
const int DEF_GREEDY_NUM = -1;
const int DEF_GREEDY_DENOM = 1;
const int DEF_SWEET_TOOTH_NUM = 1;
const int DEF_SWEET_TOOTH_DENUM = 1;
inline void command_line_parsing(int argc, char** argv, size_t &ants, size_t& steps, double &sweetness_decreasing,
double &add_param, bool &verbose, int &greedy_num, int &greedy_denom, int &sweet_tooth_num,
int &sweet_tooth_denom) {
const int DEF_WORKING_ANTS = 20;
const int DEF_STEPS = 100;
const double DEF_SWEETNESS_DECREASING = 0.1;
const double DEF_ADD_PARAM = 1.0;
po::options_description desc("Allowed options:");
desc.add_options()
("help,h", "produce help message")
("verbose,v", "count steps")
("ants", po::value<size_t>(&ants)->default_value(DEF_WORKING_ANTS), "number of ants")
("steps", po::value<size_t>(&steps)->default_value(DEF_STEPS), "number of steps")
("sweetdec", po::value<double>(&sweetness_decreasing)->default_value(DEF_SWEETNESS_DECREASING),
"percent of sweetness decreasing")
("addp", po::value<double>(&add_param)->default_value(DEF_ADD_PARAM), "adding coefficient")
/*
These parameters are set in compile time:
("greednum", po::value<int>(&greedy_num)->default_value(DEF_GREEDY_NUM), "numerator of greed (must be negative!)")
("greeddenom", po::value<int>(&greedy_denom)->default_value(DEF_GREEDY_DENOM), "denominator of greed")
("sweetnum", po::value<int>(&sweet_tooth_num)->default_value(DEF_SWEET_TOOTH_NUM), "numirator of sweet toothing")
("sweetdenom", po::value<int>(&sweet_tooth_denom)->default_value(DEF_SWEET_TOOTH_DENUM),
"denominator of sweet toothing")
*/
;
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
if (vm.count("help")) {
std::cout << desc << std::endl;
exit(EXIT_SUCCESS);
}
if (vm.count("verbose")) {
verbose = true;
}
}
int main(int argc, char** argv) {
size_t ants, steps;
double sweetness_decreasing, add_param;
bool verbose = false;
int greedy_num, greedy_denom, sweet_tooth_num, sweet_tooth_denom;
command_line_parsing(argc, argv, ants, steps, sweetness_decreasing, add_param, verbose, greedy_num,
greedy_denom, sweet_tooth_num, sweet_tooth_denom);
int n, m, start, finish;
srand(time(NULL));
std::cin >> n >> m >> start >> finish;
std::vector < edge > edges(m);
for (int i = 0; i < m; ++i) {
int a, b; double w;
std::cin >> a >> b >> w;
edges[i] = edge(a - 1, b - 1, i, w);
}
graph gr(n, edges.begin(), edges.end());
std::vector< Ant > workers(ants, Ant(go_ant<-1, 1, 1, 1>));
std::vector < bool > results(ants);
for (size_t step = 0; step < steps; ++step) {
#ifndef ANT_PARALLEL
for (size_t i = 0; i < ants; ++i) {
results[i] = workers[i].start(gr, start - 1, finish - 1);
}
#else
std::vector < std::future < bool > > fut_results(ants);
for (size_t i = 0; i < ants; ++i) {
fut_results[i] = std::async(std::launch::async,
&Ant::start, &(workers[i]), std::cref(gr), start - 1, finish - 1);
}
for (size_t i = 0; i < ants; ++i) {
results[i] = fut_results[i].get();
}
#endif
for (size_t i = 0; i < ants; ++i) {
if (results[i]) {
gr.update_way(workers[i].get_way(), add_param / workers[i].get_way().size());
}
}
gr.decrease_sweetness(1.0 - sweetness_decreasing);
if (verbose) {
std::cout << "Step " << step + 1 << " has done" << std::endl;
}
}
Ant final_ant(sweet_tooth_ant);
if (final_ant.start(gr, start - 1, finish - 1)) {
std::cout << "Found way: ";
print_way(final_ant.get_way());
}
return 0;
}