44 best_solution(old_solution) {
54 best_solution(old_solution) {
58 msg().
log <<
tau(
"bestSol before sort by size");
60 msg().
log <<
tau(
"bestSol after sort by size");
77 msg().
log <<
"\n*************************** CYCLE" << i;
96 <<
"\n" <<
tau(
"before inter swap");
98 auto swapped_f =
false;
102 for (
auto &from :
fleet) {
103 for (
auto &to :
fleet) {
104 if (&from == &to)
break;
108 <<
"\n to " << to.id()
109 <<
"from " << from.id();
110 auto swapped =
false;
115 msg().
log <<
"++++++++" << p_swaps;
121 <<
"\n" <<
tau(
"after");
137 auto from_truck = from;
140 auto swapped =
false;
146 auto o_to_orders = to_truck.orders_in_vehicle();
148 pgassert((o_from_orders * o_to_orders).empty());
150 for (
auto from_orders = from_truck.orders_in_vehicle();
151 !from_orders.empty();
152 from_orders.pop_front()) {
153 auto from_order = from_truck.orders()[from_orders.front()];
155 pgassert(from_truck.has_order(from_order));
157 if (
move_order(from_order, from_truck, to_truck)) {
158 pgassert(!from_truck.has_order(from_order));
159 pgassert(to_truck.has_order(from_order));
170 pgassert(!from_truck.has_order(from_order));
171 pgassert(to_truck.has_order(from_order));
177 pgassert(from_truck.has_order(from_order));
178 auto curr_from_duration = from_truck.duration();
180 for (
auto to_order_id : o_to_orders) {
181 auto to_order = to.
orders()[to_order_id];
185 if (!to_truck.has_order(to_order))
continue;
188 pgassert(from_truck.has_order(from_order));
189 pgassert(to_truck.has_order(to_order));
191 auto curr_to_duration = to_truck.duration();
196 pgassert(from_truck.has_order(from_order));
197 from_truck.erase(from_order);
198 pgassert(to_truck.has_order(to_order));
199 to_truck.erase(to_order);
205 from_truck.semiLIFO(to_order);
206 to_truck.semiLIFO(from_order);
208 from_truck.insert(to_order);
209 to_truck.insert(from_order);
212 pgassert((from_truck.has_order(to_order) && from_truck.is_feasable()) || !from_truck.has_order(to_order));
213 pgassert((to_truck.has_order(from_order) && to_truck.is_feasable()) || !to_truck.has_order(from_order));
215 if (from_truck.has_order(to_order) && to_truck.has_order(from_order)) {
216 auto new_from_duration = from_truck.duration();
217 auto new_to_duration = to_truck.duration();
219 auto estimated_delta =
220 - (curr_from_duration + curr_to_duration)
221 + (new_to_duration + new_from_duration);
223 auto estimated_duration =
duration() + estimated_delta;
231 if (new_from_duration < curr_from_duration ||
232 estimated_delta < 0 ||
262 return false && swapped;
270 std::stable_sort(
fleet.begin(),
fleet.end(), []
273 return lhs.orders_in_vehicle().size()
274 > rhs.orders_in_vehicle().size();
283 return lhs.duration() > rhs.duration();
289 fleet.erase(std::remove_if(
293 return v.orders_in_vehicle().empty();}),
316 auto from_truck = from;
321 if (to_truck.empty())
return false;
326 if (!from_truck.is_phony() && to_truck.is_phony()) {
333 for (
const auto o_id : from_orders) {
337 auto order = from_truck.orders()[o_id];
339 auto curr_duration = from_truck.duration() + to_truck.duration();
343 pgassert(!to_truck.has_order(order));
345 to_truck.semiLIFO(order) :
346 to_truck.insert(order);
347 pgassert((to_truck.has_order(order) && to_truck.is_feasable()) || !to_truck.has_order(order));
349 if (to_truck.has_order(order)) {
350 from_truck.erase(order);
352 auto new_duration = from_truck.duration() + to_truck.duration();
357 if (new_duration < curr_duration
358 || from_truck.empty()
369 to_truck.erase(order);
371 from_truck.semiLIFO(order) :
372 from_truck.insert(order);
402 if (to_truck.
empty())
return false;
412 if (from_truck.
size() > to_truck.
size())
return false;
422 from_truck.
erase(order);
447 bool decreased(
false);
448 for (
size_t i = 1; i <
fleet.size(); ++i) {
461 auto position = cycle;
462 for (
auto orders =
fleet[position].orders_in_vehicle();
464 orders.pop_front()) {
466 auto order =
fleet[position].orders()[orders.front()];
467 pgassert(order.idx() == orders.front());
475 for (
size_t i = 0; i < position; ++i) {
476 fleet[i].insert(order);
478 if (
fleet[i].has_order(order)) {
482 fleet[position].erase(order);
487 return fleet[position].orders_in_vehicle().empty();
494 msg().
log <<
"\n*********** best by duration"
502 msg().
log <<
"\n*********** best by fleet size"