-
Notifications
You must be signed in to change notification settings - Fork 340
/
pd_shift.cpp
106 lines (93 loc) · 3.35 KB
/
pd_shift.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
/*
This file is part of VROOM.
Copyright (c) 2015-2022, Julien Coupey.
All rights reserved (see LICENSE).
*/
#include "problems/vrptw/operators/pd_shift.h"
#include "algorithms/local_search/insertion_search.h"
#include "utils/helpers.h"
namespace vroom {
namespace vrptw {
PDShift::PDShift(const Input& input,
const utils::SolutionState& sol_state,
TWRoute& tw_s_route,
Index s_vehicle,
Index s_p_rank,
Index s_d_rank,
TWRoute& tw_t_route,
Index t_vehicle,
const Eval& gain_threshold)
: cvrp::PDShift(input,
sol_state,
static_cast<RawRoute&>(tw_s_route),
s_vehicle,
s_p_rank,
s_d_rank,
static_cast<RawRoute&>(tw_t_route),
t_vehicle,
gain_threshold),
_source_without_pd(s_route.begin() + _s_p_rank + 1,
s_route.begin() + _s_d_rank),
_tw_s_route(tw_s_route),
_tw_t_route(tw_t_route) {
}
void PDShift::compute_gain() {
// Check for valid removal wrt TW constraints.
bool is_valid_removal =
_tw_s_route.is_valid_addition_for_tw(_input,
_input.zero_amount(),
_source_without_pd.begin(),
_source_without_pd.end(),
_s_p_rank,
_s_d_rank + 1);
if (!is_valid_removal) {
return;
}
ls::RouteInsertion rs = ls::compute_best_insertion_pd(_input,
_sol_state,
s_route[_s_p_rank],
t_vehicle,
_tw_t_route,
s_gain - stored_gain);
if (rs.eval != NO_EVAL) {
_valid = true;
t_gain = -rs.eval;
stored_gain = s_gain + t_gain;
_best_t_p_rank = rs.pickup_rank;
_best_t_d_rank = rs.delivery_rank;
_best_t_delivery = rs.delivery;
}
gain_computed = true;
}
void PDShift::apply() {
std::vector<Index> target_with_pd({s_route[_s_p_rank]});
std::copy(t_route.begin() + _best_t_p_rank,
t_route.begin() + _best_t_d_rank,
std::back_inserter(target_with_pd));
target_with_pd.push_back(s_route[_s_d_rank]);
_tw_t_route.replace(_input,
_best_t_delivery,
target_with_pd.begin(),
target_with_pd.end(),
_best_t_p_rank,
_best_t_d_rank);
if (_s_d_rank == _s_p_rank + 1) {
_tw_s_route.remove(_input, _s_p_rank, 2);
} else {
Amount delivery = _input.zero_amount();
for (unsigned i = _s_p_rank + 1; i < _s_d_rank; ++i) {
const auto& job = _input.jobs[s_route[i]];
if (job.type == JOB_TYPE::SINGLE) {
delivery += job.delivery;
}
}
_tw_s_route.replace(_input,
delivery,
_source_without_pd.begin(),
_source_without_pd.end(),
_s_p_rank,
_s_d_rank + 1);
}
}
} // namespace vrptw
} // namespace vroom