Skip to content

Commit 03afb60

Browse files
committed
Save individual scores in history
1 parent 2a63d95 commit 03afb60

File tree

5 files changed

+98
-45
lines changed

5 files changed

+98
-45
lines changed

include/simulation/RoutingSolver.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
namespace cda_rail::sim {
1414

1515
struct ScoreHistory
16-
: public std::vector<std::tuple<std::chrono::milliseconds, double>> {
16+
: public std::vector<std::tuple<std::chrono::milliseconds, ScoreSet>> {
1717
void export_csv(const std::filesystem::path& p) const;
1818
};
1919

include/simulation/SolverResult.hpp

+13-5
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,21 @@
66

77
namespace cda_rail::sim {
88

9+
struct ScoreSet {
10+
std::unordered_map<std::string, double> stop_scores;
11+
std::unordered_map<std::string, double> destination_scores;
12+
double collision_score = 0;
13+
14+
double get_score() const;
15+
double get_collision_score() const;
16+
double get_stop_score() const;
17+
double get_destination_score() const;
18+
};
19+
920
class SolverResult {
1021
RoutingSolutionSet solutions;
1122
TrainTrajectorySet trajectories;
12-
13-
std::unordered_map<std::string, double> stop_scores;
14-
std::unordered_map<std::string, double> destination_scores;
15-
double collision_score;
23+
ScoreSet scores;
1624

1725
public:
1826
SolverResult(const SimulationInstance& instance);
@@ -24,7 +32,7 @@ class SolverResult {
2432

2533
const RoutingSolutionSet& get_solutions() const;
2634
const TrainTrajectorySet& get_trajectories() const;
27-
double get_score() const;
35+
const ScoreSet& get_score_set() const;
2836
};
2937

3038
}; // namespace cda_rail::sim

src/simulation/RoutingSolver.cpp

+48-25
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@
33
void cda_rail::sim::ScoreHistory::export_csv(
44
const std::filesystem::path& p) const {
55
std::ofstream csvfile(p);
6-
csvfile << "time,score" << std::endl;
6+
csvfile << "time,overall_score,collision_score,destination_score,stop_score"
7+
<< std::endl;
78

89
for (auto it = begin(); it != end(); it++) {
9-
csvfile << std::get<0>(*it).count() << "," << std::get<1>(*it) << std::endl;
10+
const ScoreSet& set = std::get<1>(*it);
11+
csvfile << std::get<0>(*it).count() << "," << set.get_score() << ","
12+
<< set.get_collision_score() << "," << set.get_destination_score()
13+
<< "," << set.get_stop_score() << "," << std::endl;
1014
}
1115

1216
csvfile.close();
@@ -15,12 +19,15 @@ void cda_rail::sim::ScoreHistory::export_csv(
1519
void cda_rail::sim::ScoreHistoryCollection::export_csv(
1620
const std::filesystem::path& p) const {
1721
std::ofstream csvfile(p);
18-
csvfile << "time,score" << std::endl;
22+
csvfile << "time,overall_score,collision_score,destination_score,stop_score"
23+
<< std::endl;
1924

2025
for (auto hist_it = begin(); hist_it != end(); hist_it++) {
2126
for (auto it = (*hist_it).begin(); it != (*hist_it).end(); it++) {
22-
csvfile << std::get<0>(*it).count() << "," << std::get<1>(*it)
23-
<< std::endl;
27+
const ScoreSet& set = std::get<1>(*it);
28+
csvfile << std::get<0>(*it).count() << "," << set.get_score() << ","
29+
<< set.get_collision_score() << "," << set.get_destination_score()
30+
<< "," << set.get_stop_score() << "," << std::endl;
2431
}
2532
}
2633

@@ -46,8 +53,9 @@ cda_rail::sim::RoutingSolver::random_local_search(
4653
std::chrono::steady_clock::now();
4754

4855
for (;;) {
49-
auto res = local_search(RoutingSolutionSet{instance, rng_engine}, params);
50-
double round_score = std::get<0>(res).get_score();
56+
auto res = local_search(RoutingSolutionSet{instance, rng_engine}, params);
57+
ScoreSet round_score_set = std::get<0>(res).get_score_set();
58+
double round_score = round_score_set.get_score();
5159

5260
std::chrono::steady_clock::time_point round_time =
5361
std::chrono::steady_clock::now();
@@ -58,7 +66,7 @@ cda_rail::sim::RoutingSolver::random_local_search(
5866
best_result.emplace(std::get<0>(res));
5967
hist.push_back({std::chrono::duration_cast<std::chrono::milliseconds>(
6068
round_time - initial_time),
61-
best_score});
69+
round_score_set});
6270
}
6371

6472
if (std::chrono::duration_cast<std::chrono::seconds>(
@@ -89,7 +97,8 @@ cda_rail::sim::RoutingSolver::grasp_search(std::chrono::seconds max_search_time,
8997

9098
auto res =
9199
local_search(RoutingSolutionSet{instance, rng_engine}, loc_params);
92-
double round_score = std::get<0>(res).get_score();
100+
ScoreSet round_score_set = std::get<0>(res).get_score_set();
101+
double round_score = round_score_set.get_score();
93102

94103
std::chrono::steady_clock::time_point round_time =
95104
std::chrono::steady_clock::now();
@@ -100,7 +109,7 @@ cda_rail::sim::RoutingSolver::grasp_search(std::chrono::seconds max_search_time,
100109
best_result.emplace(std::get<0>(res));
101110
hist.push_back({std::chrono::duration_cast<std::chrono::milliseconds>(
102111
round_time - initial_time),
103-
best_score});
112+
round_score_set});
104113
}
105114

106115
if (std::chrono::duration_cast<std::chrono::seconds>(
@@ -131,7 +140,8 @@ cda_rail::sim::RoutingSolver::random_search(
131140
for (;;) {
132141
SolverResult round_result{instance,
133142
RoutingSolutionSet{instance, rng_engine}};
134-
double round_score = round_result.get_score();
143+
ScoreSet round_score_set = round_result.get_score_set();
144+
double round_score = round_score_set.get_score();
135145

136146
std::chrono::steady_clock::time_point round_time =
137147
std::chrono::steady_clock::now();
@@ -147,7 +157,7 @@ cda_rail::sim::RoutingSolver::random_search(
147157
best_result.emplace(round_result);
148158
hist.push_back({std::chrono::duration_cast<std::chrono::milliseconds>(
149159
round_time - initial_time),
150-
best_score});
160+
round_score_set});
151161
}
152162

153163
if (max_stall_time.has_value()) {
@@ -184,7 +194,12 @@ cda_rail::sim::RoutingSolver::greedy_search(
184194
for (;;) {
185195
std::optional<cda_rail::sim::SolverResult> round_result_opt =
186196
greedy_solution(params);
187-
double round_score = round_result_opt.value().get_score();
197+
198+
if (!round_result_opt.has_value())
199+
continue;
200+
201+
ScoreSet round_score_set = round_result_opt.value().get_score_set();
202+
double round_score = round_score_set.get_score();
188203

189204
std::chrono::steady_clock::time_point round_time =
190205
std::chrono::steady_clock::now();
@@ -201,7 +216,7 @@ cda_rail::sim::RoutingSolver::greedy_search(
201216
auto total_time_spent =
202217
std::chrono::duration_cast<std::chrono::milliseconds>(round_time -
203218
initial_time);
204-
hist.push_back({total_time_spent, best_score});
219+
hist.push_back({total_time_spent, round_score_set});
205220
}
206221

207222
if (max_stall_time.has_value()) {
@@ -233,22 +248,24 @@ cda_rail::sim::RoutingSolver::local_search(
233248
ScoreHistory hist;
234249
double sampling_range_fraction = params.start_sampling_range_fraction;
235250
SolverResult last_result{instance, starting_solution};
236-
double last_score = last_result.get_score();
251+
ScoreSet last_score_set = last_result.get_score_set();
252+
double last_score = last_score_set.get_score();
237253
hist.push_back({std::chrono::duration_cast<std::chrono::milliseconds>(
238254
std::chrono::steady_clock::now() - initial_time),
239-
last_score});
255+
last_score_set});
240256

241257
while (sampling_range_fraction > params.abort_sampling_range_fraction) {
242258
RoutingSolutionSet new_sol = last_result.get_solutions();
243259
new_sol.perturb(instance, sampling_range_fraction, rng_engine);
244260
SolverResult new_result{instance, new_sol};
261+
ScoreSet new_score_set = new_result.get_score_set();
245262

246-
if (double new_score = new_result.get_score(); new_score < last_score) {
263+
if (double new_score = new_score_set.get_score(); new_score < last_score) {
247264
last_result = new_result;
248265
last_score = new_score;
249266
hist.push_back({std::chrono::duration_cast<std::chrono::milliseconds>(
250267
std::chrono::steady_clock::now() - initial_time),
251-
last_score});
268+
new_score_set});
252269
} else {
253270
sampling_range_fraction =
254271
sampling_range_fraction * params.contraction_coeff;
@@ -268,22 +285,24 @@ cda_rail::sim::RoutingSolver::local_search(
268285
ScoreHistory hist;
269286
double sampling_range_fraction = params.start_sampling_range_fraction;
270287
SolverResult last_result{instance, starting_solution};
271-
double last_score = last_result.get_score();
288+
ScoreSet last_score_set = last_result.get_score_set();
289+
double last_score = last_score_set.get_score();
272290
hist.push_back({std::chrono::duration_cast<std::chrono::milliseconds>(
273291
std::chrono::steady_clock::now() - initial_time),
274-
last_score});
292+
last_score_set});
275293

276294
while (sampling_range_fraction > params.abort_sampling_range_fraction) {
277295
RoutingSolutionSet new_sol = last_result.get_solutions();
278296
new_sol.perturb(instance, sampling_range_fraction, rng01);
279297
SolverResult new_result{instance, new_sol};
298+
ScoreSet new_score_set = new_result.get_score_set();
280299

281-
if (double new_score = new_result.get_score(); new_score < last_score) {
300+
if (double new_score = new_score_set.get_score(); new_score < last_score) {
282301
last_result = new_result;
283302
last_score = new_score;
284303
hist.push_back({std::chrono::duration_cast<std::chrono::milliseconds>(
285304
std::chrono::steady_clock::now() - initial_time),
286-
last_score});
305+
new_score_set});
287306
} else {
288307
sampling_range_fraction =
289308
sampling_range_fraction * params.contraction_coeff;
@@ -320,7 +339,8 @@ cda_rail::sim::RoutingSolver::greedy_solution(GreedyParams params) {
320339
RoutingSolution round_sol{instance, train, rng_engine};
321340
TrainTrajectory round_traj{instance, train, round_sol};
322341
result.insert_or_assign(round_sol, round_traj);
323-
double round_score = result.get_score();
342+
ScoreSet round_score_set = result.get_score_set();
343+
double round_score = round_score_set.get_score();
324344

325345
std::chrono::steady_clock::time_point round_time =
326346
std::chrono::steady_clock::now();
@@ -411,7 +431,7 @@ void cda_rail::sim::RoutingSolver::init_genes(
411431
bool cda_rail::sim::RoutingSolver::eval_solution(const RoutingSolutionSet& p,
412432
MiddleCost& c) {
413433
SolverResult round_result{instance, p};
414-
c.score = round_result.get_score();
434+
c.score = round_result.get_score_set().get_score();
415435
return true;
416436
}
417437

@@ -474,5 +494,8 @@ void cda_rail::sim::RoutingSolver::SO_report_generation(
474494
std::chrono::milliseconds past_time =
475495
std::chrono::duration_cast<std::chrono::milliseconds>(round_time -
476496
starting_time);
477-
hist.push_back({past_time, last_generation.best_total_cost});
497+
auto best_individual =
498+
last_generation.chromosomes[last_generation.best_chromosome_index];
499+
SolverResult best_result{instance, best_individual.genes};
500+
hist.push_back({past_time, best_result.get_score_set()});
478501
}

src/simulation/SolverResult.cpp

+34-12
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
cda_rail::sim::SolverResult::SolverResult(const SimulationInstance& instance)
55
: solutions(RoutingSolutionSet{}),
6-
trajectories(TrainTrajectorySet(instance)), collision_score(0) {}
6+
trajectories(TrainTrajectorySet(instance)) {}
77

88
cda_rail::sim::SolverResult::SolverResult(const SimulationInstance& instance,
99
const RoutingSolutionSet& solutions)
@@ -14,28 +14,29 @@ cda_rail::sim::SolverResult::SolverResult(const SimulationInstance& instance,
1414
"Solutions and Trajectories are not the same size");
1515

1616
for (auto const& [train_name, traj] : trajectories.get_map()) {
17-
stop_scores.insert_or_assign(train_name, stop_penalty(traj));
17+
scores.stop_scores.insert_or_assign(train_name, stop_penalty(traj));
1818
}
1919

2020
for (auto const& [train_name, traj] : trajectories.get_map()) {
21-
destination_scores.insert_or_assign(train_name, destination_penalty(traj));
21+
scores.destination_scores.insert_or_assign(train_name,
22+
destination_penalty(traj));
2223
}
2324

24-
collision_score = collision_penalty(trajectories);
25+
scores.collision_score = collision_penalty(trajectories);
2526
}
2627

2728
void cda_rail::sim::SolverResult::insert_or_assign(
2829
const RoutingSolution& solution, const TrainTrajectory& trajectory) {
2930
solutions.solutions.insert_or_assign(trajectory.get_train().name, solution);
3031
trajectories.insert_or_assign(trajectory.get_train().name, trajectory);
3132

32-
stop_scores.insert_or_assign(trajectory.get_train().name,
33-
stop_penalty(trajectory));
34-
destination_scores.insert_or_assign(trajectory.get_train().name,
35-
destination_penalty(trajectory));
33+
scores.stop_scores.insert_or_assign(trajectory.get_train().name,
34+
stop_penalty(trajectory));
35+
scores.destination_scores.insert_or_assign(trajectory.get_train().name,
36+
destination_penalty(trajectory));
3637

3738
// TODO: don't need to recompute all pairs for new train
38-
collision_score = collision_penalty(trajectories);
39+
scores.collision_score = collision_penalty(trajectories);
3940
}
4041

4142
const cda_rail::sim::RoutingSolutionSet&
@@ -48,18 +49,39 @@ cda_rail::sim::SolverResult::get_trajectories() const {
4849
return trajectories;
4950
}
5051

51-
double cda_rail::sim::SolverResult::get_score() const {
52+
double cda_rail::sim::ScoreSet::get_score() const {
5253
double score_sum = 0;
5354

55+
score_sum += get_collision_score();
56+
score_sum += get_destination_score();
57+
score_sum += get_stop_score();
58+
59+
return score_sum;
60+
}
61+
62+
double cda_rail::sim::ScoreSet::get_collision_score() const {
63+
return collision_score;
64+
}
65+
66+
double cda_rail::sim::ScoreSet::get_stop_score() const {
67+
double score_sum = 0;
5468
for (auto const& [train_name, score] : stop_scores) {
5569
score_sum = score_sum + score;
5670
}
5771

72+
return score_sum;
73+
}
74+
75+
double cda_rail::sim::ScoreSet::get_destination_score() const {
76+
double score_sum = 0;
5877
for (auto const& [train_name, score] : destination_scores) {
5978
score_sum = score_sum + score;
6079
}
6180

62-
score_sum = score_sum + collision_score;
63-
6481
return score_sum;
6582
}
83+
84+
const cda_rail::sim::ScoreSet&
85+
cda_rail::sim::SolverResult::get_score_set() const {
86+
return scores;
87+
}

test/test_simulation.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -259,11 +259,11 @@ TEST(Simulation, SolverResult) {
259259
for (auto train_idx = train_idxs.begin(); train_idx != train_idxs.end();
260260
train_idx++) {
261261
const auto train = train_list.get_train(*train_idx);
262-
double previous_score = result.get_score();
262+
double previous_score = result.get_score_set().get_score();
263263
sim::RoutingSolution round_sol{instance, train, rng_engine};
264264
sim::TrainTrajectory round_traj{instance, train, round_sol};
265265
result.insert_or_assign(round_sol, round_traj);
266-
ASSERT_GE(result.get_score(), previous_score);
266+
ASSERT_GE(result.get_score_set().get_score(), previous_score);
267267
}
268268
}
269269
}

0 commit comments

Comments
 (0)