38 namespace optimizers {
46 problem::Solution(old_solution),
47 best_solution(old_solution),
51 msg().
log <<
tau(
"bestSol before sort by size");
53 msg().
log <<
tau(
"bestSol after sort by size");
70 msg().
log <<
"\n*************************** CYCLE" << i;
89 <<
"\n" <<
tau(
"before inter swap");
91 auto swapped_f =
false;
97 if (&from == &to)
break;
101 <<
"\n to " << to.id()
102 <<
"from " << from.id();
103 auto swapped =
false;
108 msg().
log <<
"++++++++" << p_swaps;
114 while (!p_swaps.empty()) {
120 <<
"\n" <<
tau(
"after");
136 auto from_truck = from;
139 auto swapped =
false;
145 auto o_to_orders = to_truck.orders_in_vehicle();
147 pgassert((o_from_orders * o_to_orders).empty());
149 for (
auto from_orders = from_truck.orders_in_vehicle();
150 !from_orders.empty();
151 from_orders.pop_front()) {
152 auto from_order = from_truck.orders()[from_orders.front()];
154 pgassert(from_truck.has_order(from_order));
156 if (
move_order(from_order, from_truck, to_truck)) {
157 pgassert(!from_truck.has_order(from_order));
158 pgassert(to_truck.has_order(from_order));
169 pgassert(!from_truck.has_order(from_order));
170 pgassert(to_truck.has_order(from_order));
176 pgassert(from_truck.has_order(from_order));
177 auto curr_from_duration = from_truck.duration();
179 for (
auto to_order_id : o_to_orders) {
180 auto to_order = to.
orders()[to_order_id];
184 if (!to_truck.has_order(to_order))
continue;
187 pgassert(from_truck.has_order(from_order));
188 pgassert(to_truck.has_order(to_order));
190 auto curr_to_duration = to_truck.duration();
195 pgassert(from_truck.has_order(from_order));
196 from_truck.erase(from_order);
197 pgassert(to_truck.has_order(to_order));
198 to_truck.erase(to_order);
204 from_truck.semiLIFO(to_order);
205 to_truck.semiLIFO(from_order);
207 from_truck.hillClimb(to_order);
208 to_truck.hillClimb(from_order);
211 pgassert((from_truck.has_order(to_order) && from_truck.is_feasible()) || !from_truck.has_order(to_order));
212 pgassert((to_truck.has_order(from_order) && to_truck.is_feasible()) || !to_truck.has_order(from_order));
214 if (from_truck.has_order(to_order) && to_truck.has_order(from_order)) {
215 auto new_from_duration = from_truck.duration();
216 auto new_to_duration = to_truck.duration();
218 auto estimated_delta =
219 - (curr_from_duration + curr_to_duration)
220 + (new_to_duration + new_from_duration);
222 auto estimated_duration =
duration() + estimated_delta;
230 if (new_from_duration < curr_from_duration ||
231 estimated_delta < 0 ||
261 return false && swapped;
282 from_truck.
erase(from_order);
283 to_truck.
erase(to_order);
337 return lhs.orders_in_vehicle().size()
338 > rhs.orders_in_vehicle().size();
348 return lhs.orders_in_vehicle().size()
349 > rhs.orders_in_vehicle().size();
358 return lhs.duration() > rhs.duration();
368 return v.orders_in_vehicle().empty();}),
390 auto from_truck = from;
395 if (to_truck.empty())
return false;
400 if (!from_truck.is_phony() && to_truck.is_phony()) {
407 for (
const auto o_id : from_orders) {
411 auto order = from_truck.orders()[o_id];
413 auto curr_duration = from_truck.duration() + to_truck.duration();
417 pgassert(!to_truck.has_order(order));
419 to_truck.semiLIFO(order) :
420 to_truck.hillClimb(order);
421 pgassert((to_truck.has_order(order) && to_truck.is_feasible()) || !to_truck.has_order(order));
423 if (to_truck.has_order(order)) {
424 from_truck.erase(order);
426 auto new_duration = from_truck.duration() + to_truck.duration();
431 if (new_duration < curr_duration
432 || from_truck.empty()
443 to_truck.erase(order);
445 from_truck.semiLIFO(order) :
446 from_truck.hillClimb(order);
476 if (to_truck.
empty())
return false;
486 if (from_truck.size() > to_truck.size())
return false;
496 from_truck.
erase(order);
515 return lhs.total_wait_time() > rhs.total_wait_time();
521 return lhs.orders_size() > rhs.orders_size();
535 bool decreased(
false);
536 for (
size_t i = 1; i <
m_fleet.size(); ++i) {
549 auto position = cycle;
563 for (
size_t i = 0; i < position; ++i) {
566 if (
m_fleet[i].has_order(order)) {
570 m_fleet[position].erase(order);
575 return m_fleet[position].orders_in_vehicle().empty();
582 msg().
log <<
"\n*********** best by duration"
590 msg().
log <<
"\n*********** best by fleet size"