99 auto pick_itr = rbegin();
100 while (pick_itr != rend() && !pick_itr->is_pickup()) {
106 auto deleted_pick_idx = pick_itr->idx();
108 for (
const auto &o : this->
orders()) {
109 if (o.pickup().idx() == deleted_pick_idx) {
125 auto pick_itr = begin();
126 while (pick_itr != end() && !pick_itr->is_pickup()) {
132 auto deleted_pick_idx = pick_itr->idx();
134 for (
const auto &o : this->
orders()) {
135 if (o.pickup().idx() == deleted_pick_idx) {
187 std::vector<size_t> stops;
189 msg().
log <<
"\n******\n" << this->
id() <<
"\t stops(o_id) -> ";
190 for (
const auto &s :
m_stops) {
201 for (
const auto o_id :
m_stops) {
205 auto order = std::find_if(
orders.begin(),
orders.end(), [o_id]
206 (
const Order& o) ->
bool {
207 return o.id() == o_id;
212 if (assigned.
has(order->idx())) {
213 pgassertwm(
false,
"Assigning an order twice");
216 stops.push_back(order->idx());
217 if (picked_orders.
has(order->idx())) {
221 insert(i + 1, order->delivery());
222 picked_orders -= order->idx();
224 assigned += order->idx();
225 unassigned -= order->idx();
230 insert(i + 1, order->pickup());
231 picked_orders += order->idx();
239 msg().
log <<
"\n" << this->
id() <<
"\t (idx,id) -> ";
240 for (
const auto &s : stops) {
249 msg().
log <<
"\n**********************************Vehicle is not feasible with initial orders";
252 msg().
log <<
"\nVehicle: " << this->
id() <<
"Orders: ";
255 msg().
log <<
"\n" << *
this;
264 for (
const auto o : orders_to_remove) {
265 auto order = this->
orders();
294 msg().
log <<
"\nVehicle: " << this->
id() <<
"unmovable: {";
296 for (
const auto &s : *
this) {
297 auto order = this->
orders()[o];
299 if (s.order() == order.id() && s.is_pickup()) {
300 if (s.opens() < execution_date) {
302 msg().
log << order.id() <<
",";
335 auto test_truck = *
this;
336 test_truck.push_back(order);
337 return test_truck.is_feasible();
375 if (deliver_pos.second < deliver_pos.first) {
385 while (deliver_pos.first <= deliver_pos.second) {
388 if (
is_feasible() && !at(deliver_pos.second + 1).is_pickup()) {
411 erase(deliver_pos.second);
416 --deliver_pos.second;
454 if (pick_pos.second < pick_pos.first) {
461 if (deliver_pos.second < deliver_pos.first) {
472 ++deliver_pos.second;
475 auto best_pick_pos = size();
476 auto best_deliver_pos = size() + 1;
478 auto min_delta_objective = (std::numeric_limits<double>::max)();
486 while (pick_pos.first <= pick_pos.second) {
487 auto deliver_range = deliver_pos;
488 if (deliver_range.first <= pick_pos.first) deliver_range.first = pick_pos.first + 1;
496 while (deliver_range.first <= deliver_range.second) {
498 auto delta_objective =
objective() - current_objective;
499 if (delta_objective < min_delta_objective) {
500 min_delta_objective = delta_objective;
501 best_pick_pos = pick_pos.first;
502 best_deliver_pos = deliver_range.first;
506 if (at(deliver_range.first + 1).is_end())
break;
507 swap(deliver_range.first, deliver_range.first + 1);
508 ++deliver_range.first;
511 pgassert(at(deliver_range.first).order() == order.
id());
512 pgassert(at(pick_pos.first).order() == order.
id());
515 if (at(pick_pos.first + 1).is_end())
break;
517 swap(pick_pos.first, pick_pos.first + 1);
521 erase(pick_pos.first);