@@ -263,6 +263,41 @@ cda_rail::sim::RoutingSolver::local_search(
263
263
return {last_result, hist};
264
264
}
265
265
266
+ std::tuple<cda_rail::sim::SolverResult, cda_rail::sim::ScoreHistory>
267
+ cda_rail::sim::RoutingSolver::local_search (
268
+ cda_rail::sim::RoutingSolutionSet starting_solution,
269
+ double start_sampling_range_fraction, double abort_sampling_range_fraction,
270
+ double contr_coeff, const std::function<double (void )>& rng01) {
271
+ std::chrono::steady_clock::time_point initial_time =
272
+ std::chrono::steady_clock::now ();
273
+
274
+ ScoreHistory hist;
275
+ double sampling_range_fraction = start_sampling_range_fraction;
276
+ SolverResult last_result{instance, starting_solution};
277
+ double last_score = last_result.get_score ();
278
+ hist.push_back ({std::chrono::duration_cast<std::chrono::milliseconds>(
279
+ std::chrono::steady_clock::now () - initial_time),
280
+ last_score});
281
+
282
+ while (sampling_range_fraction > abort_sampling_range_fraction) {
283
+ RoutingSolutionSet new_sol = last_result.get_solutions ();
284
+ new_sol.perturb (instance, sampling_range_fraction, rng01);
285
+ SolverResult new_result{instance, new_sol};
286
+
287
+ if (double new_score = new_result.get_score (); new_score < last_score) {
288
+ last_result = new_result;
289
+ last_score = new_score;
290
+ hist.push_back ({std::chrono::duration_cast<std::chrono::milliseconds>(
291
+ std::chrono::steady_clock::now () - initial_time),
292
+ last_score});
293
+ } else {
294
+ sampling_range_fraction = sampling_range_fraction * contr_coeff;
295
+ }
296
+ }
297
+
298
+ return {last_result, hist};
299
+ }
300
+
266
301
std::optional<cda_rail::sim::SolverResult>
267
302
cda_rail::sim::RoutingSolver::greedy_solution (
268
303
std::chrono::milliseconds per_train_stall_time) {
@@ -320,7 +355,8 @@ cda_rail::sim::RoutingSolver::greedy_solution(
320
355
321
356
std::tuple<std::optional<cda_rail::sim::SolverResult>,
322
357
cda_rail::sim::ScoreHistory>
323
- cda_rail::sim::RoutingSolver::genetic_search (GeneticParams params) {
358
+ cda_rail::sim::RoutingSolver::genetic_search (GeneticParams params,
359
+ bool local_improv) {
324
360
/* *
325
361
* Genetic algorithm for entire solution sets
326
362
*/
@@ -342,9 +378,16 @@ cda_rail::sim::RoutingSolver::genetic_search(GeneticParams params) {
342
378
std::placeholders::_2);
343
379
ga_obj.mutate = std::bind (&RoutingSolver::mutate, this , std::placeholders::_1,
344
380
std::placeholders::_2, std::placeholders::_3);
345
- ga_obj.crossover =
346
- std::bind (&RoutingSolver::crossover, this , std::placeholders::_1,
347
- std::placeholders::_2, std::placeholders::_3);
381
+
382
+ if (local_improv) {
383
+ ga_obj.crossover = std::bind (&RoutingSolver::crossover_local_improv, this ,
384
+ std::placeholders::_1, std::placeholders::_2,
385
+ std::placeholders::_3);
386
+ } else {
387
+ ga_obj.crossover =
388
+ std::bind (&RoutingSolver::crossover, this , std::placeholders::_1,
389
+ std::placeholders::_2, std::placeholders::_3);
390
+ }
348
391
349
392
std::chrono::steady_clock::time_point starting_time =
350
393
std::chrono::steady_clock::now ();
@@ -406,6 +449,16 @@ cda_rail::sim::RoutingSolutionSet cda_rail::sim::RoutingSolver::crossover(
406
449
return X_new;
407
450
}
408
451
452
+ cda_rail::sim::RoutingSolutionSet
453
+ cda_rail::sim::RoutingSolver::crossover_local_improv (
454
+ const RoutingSolutionSet& X1, const RoutingSolutionSet& X2,
455
+ const std::function<double (void )>& rnd01) {
456
+ auto X_new = crossover (X1, X2, rnd01);
457
+ auto res = local_search (X_new, 0.05 , 0.01 , 0.95 , rnd01);
458
+
459
+ return std::get<0 >(res).get_solutions ();
460
+ }
461
+
409
462
double cda_rail::sim::RoutingSolver::calculate_SO_total_fitness (
410
463
const GA_Type::thisChromosomeType& X) {
411
464
return X.middle_costs .score ;
0 commit comments