void
Initial_solution::do_while_foo(int kind) {
    invariant();
    pgassert(kind > 0 && kind < 7);

    msg.log << "\nInitial_solution::do_while_foo\n";
    Identifiers<size_t> notused;
#if 0
    bool out_of_trucks(true);
#endif

    while (!unassigned.empty()) {
        msg.log << unassigned.size() << " unassigned: " << unassigned << "\n";
        msg.log << assigned.size() << " assigned:" << assigned << "\n";
        auto current = unassigned.size();
#if 0
        auto truck = out_of_trucks?
            trucks.get_truck(unassigned.front()) :
            trucks.get_truck();
#else
        auto truck = trucks.get_truck(unassigned.front());
#endif
        msg.log << "got truck:" << truck.tau() << "\n";
        /*
         * kind 1 to 7 work with the same code structure
         */
        truck.do_while_feasable(kind, unassigned, assigned);
        msg.log << unassigned.size() << " unassigned: " << unassigned << "\n";
        msg.log << assigned.size() << " assigned:" << assigned << "\n";
        msg.log << "current" << current << " unassigned: " << unassigned.size();
        pgassertwm(current > unassigned.size(), msg.get_log().c_str());

#if 0
        if (truck.orders_in_vehicle().empty()) {
            out_of_trucks = notused.has(truck.idx());
            if (out_of_trucks) {
                for (auto t : notused) {
                    trucks.release_truck(t);
                }
            }
            notused += truck.idx();
            continue;
        }
#endif
        fleet.push_back(truck);
        invariant();
    }

    pgassertwm(true, msg.get_log().c_str());
    pgassert(is_feasable());
    invariant();
}
Example #2
0
/*
 * from_truck trying to make from_truck's duration smaller
 * - maybe all orders can be moved
 *   - if that is the case, the from_truck could be removed
 *
 * Deleting an order on the from_truck
 * - number of truck remains the same
 * - from_truk duration() can not get larger
 * - the overall duration can get larger
 * 
 */
bool
Optimize::move_reduce_cost(size_t from_pos, size_t to_pos) {
    pgassert(to_pos < from_pos);
    auto from_truck = fleet[from_pos];
    auto to_truck = fleet[to_pos];
    auto moved(false);

    auto orders(from_truck.orders_in_vehicle);
    while (!orders.empty()) {
        /*
         * get the order that decreases the duration the most
         * (there is always a worse)
         */
        auto order = from_truck.get_worse_order(orders);
        orders.erase(order.id());

        /*
         * insert it in the next truck
         */
        to_truck.insert(order);
        if (to_truck.is_feasable()) {
            problem->log
                << "\n    Move order " << order.id()
                << " from truck " << from_truck.id()
                << " to truck " << to_truck.id();
#ifndef NDEBUG
            problem->dbg_log << "\nMove before:";
            problem->dbg_log << "\n" << fleet[to_pos].tau();
            problem->dbg_log << "\n" << fleet[from_pos].tau();
#endif

            from_truck.erase(order);
            move_order(order, fleet[from_pos], fleet[to_pos]);
            moved = true;
            save_if_best();

#ifndef NDEBUG
            problem->dbg_log << "\nMove after:";
            problem->dbg_log << "\n" << fleet[to_pos].tau();
            problem->dbg_log << "\n" << fleet[from_pos].tau();
#endif
        }
    }
    return moved;
}
Example #3
0
bool
Optimize::swap_worse(size_t from_pos, size_t to_pos) {
    pgassert(to_pos < from_pos);
    auto from_truck = fleet[from_pos];
    auto to_truck = fleet[to_pos];
    auto swapped(false);
    auto from_orders(from_truck.orders_in_vehicle);
    auto to_orders(to_truck.orders_in_vehicle);
    auto local_limit(from_orders.size() * to_orders.size() + 1);

    while (!from_orders.empty() && --local_limit > 0) {
        auto from_order(from_truck.get_worse_order(from_orders));
        from_orders.erase(from_order.id());

        while (!to_orders.empty()) {
            auto to_order(to_truck.get_worse_order(to_orders));
            to_orders.erase(to_order.id());

            /*
             * delete from_order, and to order from their trucks
             */
            auto curr_from_duration(from_truck.duration());
            auto curr_to_duration(to_truck.duration());

            from_truck.erase(from_order);
            to_truck.erase(to_order);

            /*
             * insert them in the other truck
             */
            from_truck.insert(to_order);
            to_truck.insert(from_order);

            if (from_truck.is_feasable() && to_truck.is_feasable()) {
                /*
                 * Can swap but:
                 *   - only swap when the total duration is reduced
                 *   - or from_truck duration is reduced 
                 */

                if (((from_truck.duration() + to_truck.duration())
                            < (curr_from_duration + curr_to_duration))
                        || (from_truck.duration() < curr_from_duration)) {
                    problem->log
                        << "\n    Swap order " << from_order.id()
                        << " from truck " << from_truck.id()
                        << " with order " << to_order.id() << " of truck " << to_truck.id();
#ifndef NDEBUG
                    problem->dbg_log << "\nswappping before:";
                    problem->dbg_log << "\n" << fleet[to_pos].tau();
                    problem->dbg_log << "\n" << fleet[from_pos].tau();
#endif

                    swap_order(from_order, fleet[from_pos], to_order, fleet[to_pos]);
                    swapped = true;
                    save_if_best();
                    from_orders.insert(to_order.id());
#ifndef NDEBUG
                    problem->dbg_log << "\nswappping after:";
                    problem->dbg_log << "\n" << fleet[to_pos].tau();
                    problem->dbg_log << "\n" << fleet[from_pos].tau();
#endif
                    break;
                }
            }
            /*
             * wasn't swapped
             */
            to_truck = fleet[to_pos];
            from_truck = fleet[from_pos];
        }
    }
    return swapped;
}
Example #4
0
void
Vehicle_pickDeliver::insert(const Order &order) {
    invariant();
    pgassert(!has_order(order));

    auto pick_pos(position_limits(order.pickup()));
    auto deliver_pos(position_limits(order.delivery()));
#ifndef NDEBUG
    std::ostringstream err_log;
    err_log << "\n\tpickup limits (low, high) = ("
        << pick_pos.first << ", "
        << pick_pos.second << ") "
        << "\n\tdeliver limits (low, high) = ("
        << deliver_pos.first << ", "
        << deliver_pos.second << ") "
        << "\noriginal" << tau();
#endif

    if (pick_pos.second < pick_pos.first) {
        /* pickup generates twv evrywhere,
         *  so put the order as last */
        push_back(order);
        return;
    }

    if (deliver_pos.second < deliver_pos.first) {
        /* delivery generates twv evrywhere,
         *  so put the order as last */
        push_back(order);
        return;
    }
    /*
     * Because delivery positions were estimated without
     * the pickup:
     *   - increase the upper limit position estimation
     */
    ++deliver_pos.second;


    auto d_pos_backup(deliver_pos);
    auto best_pick_pos = m_path.size();
    auto best_deliver_pos = m_path.size() + 1;
    auto current_duration(duration());
    auto min_delta_duration = (std::numeric_limits<double>::max)();
    auto found(false);
    pgassertwm(!has_order(order), err_log.str());
    while (pick_pos.first <= pick_pos.second) {
#ifndef NDEBUG
        err_log << "\n\tpickup cycle limits (low, high) = ("
            << pick_pos.first << ", "
            << pick_pos.second << ") ";
#endif
        Vehicle::insert(pick_pos.first, order.pickup());
#ifndef NDEBUG
        err_log << "\npickup inserted: " << tau();
#endif

        while (deliver_pos.first <= deliver_pos.second) {
            Vehicle::insert(deliver_pos.first, order.delivery());
            orders_in_vehicle.insert(order.id());
            pgassertwm(has_order(order), err_log.str());
#ifndef NDEBUG
            err_log << "\ndelivery inserted: " << tau();
#endif
            if (is_feasable()) {
                pgassert(is_feasable());
                auto delta_duration = duration()-current_duration;
                if (delta_duration < min_delta_duration) {
#ifndef NDEBUG
                    err_log << "\nsuccess" << tau();
#endif
                    min_delta_duration = delta_duration;
                    best_pick_pos = pick_pos.first;
                    best_deliver_pos = deliver_pos.first;
                    found = true;
                }
            }
            Vehicle::erase(deliver_pos.first);
#ifndef NDEBUG
            err_log << "\ndelivery erased: " << tau();
#endif
            ++deliver_pos.first;
        }
        Vehicle::erase(pick_pos.first);
#ifndef NDEBUG
        err_log << "\npickup erased: " << tau();
#endif
        orders_in_vehicle.erase(order.id());
        pgassertwm(!has_order(order), err_log.str());

        deliver_pos = d_pos_backup;
#ifndef NDEBUG
        err_log << "\n\trestoring deliver limits (low, high) = ("
            << deliver_pos.first << ", "
            << deliver_pos.second << ") ";
#endif
        ++pick_pos.first;
    }
    pgassertwm(!has_order(order), err_log.str());
    if (!found) {
        /* order causes twv
         *  so put the order as last */
        push_back(order);
        return;
    }
    Vehicle::insert(best_pick_pos, order.pickup());
    Vehicle::insert(best_deliver_pos, order.delivery());

    orders_in_vehicle.insert(order.id());
    pgassertwm(is_feasable(), err_log.str());
    pgassertwm(has_order(order), err_log.str());
    pgassertwm(!has_cv(), err_log.str());
    invariant();
}
Example #5
0
/*
 * from_truck trying to make from_truck's duration smaller
 * - maybe all orders can be moved
 *   - if that is the case, the from_truck could be removed
 *
 * Deleting an order on the from_truck
 * - number of truck remains the same
 * - from_truk duration() can not get larger
 * - the overall duration can get larger
 *
 */
bool
Optimize::move_reduce_cost(
        Vehicle_pickDeliver &from,
        Vehicle_pickDeliver &to) {
    auto from_truck = from;
    auto to_truck = to;

    /*
     * don't move from a real truck to a phoney truck
     */
    if (!from_truck.is_phony() && to_truck.is_phony()) {
        return false;
    }
#if 0
    from.id()  > to.id()
        ?  to : from;
#endif
    size_t from_pos = 0;
    size_t to_pos = 0;

    for (; from_pos < fleet.size()
            && fleet[from_pos].idx() != from_truck.idx()
            ; ++from_pos) {
    }
    pgassert(from_pos < fleet.size());
    for (; to_pos < fleet.size()
            && fleet[to_pos].idx() != to_truck.idx()
            ; ++to_pos) {
    }
    pgassert(to_pos < fleet.size());

    auto moved = false;

    auto from_orders = from_truck.orders_in_vehicle();
    while (!from_orders.empty()) {
        /*
         * removing an order decreases the duration
         */
        auto order = from_truck.orders()[from_orders.front()];
        from_orders -= order.idx();

        /*
         * insert it in the "to" truck
         */
        to_truck.insert(order);
        if (to_truck.is_feasable()) {
            msg.log
                << "\n    Move order " << order.pickup().id()
                << " from truck " << from_truck.idx()
                << " to truck " << to_truck.idx();
#ifndef NDEBUG
            msg.dbg_log << "\nMove before:";
            msg.dbg_log << "\n" << fleet[to_pos].tau();
            msg.dbg_log << "\n" << fleet[from_pos].tau();
#endif

#if 1
            from_truck.erase(order);
#else
            to_truck.insert(order);
            move_order(order, fleet[from_pos], fleet[to_pos]);
#endif
            moved = true;
            save_if_best();

#ifndef NDEBUG
            msg.dbg_log << "\nMove after:";
            msg.dbg_log << "\n" << fleet[to_pos].tau();
            msg.dbg_log << "\n" << fleet[from_pos].tau();
#endif
        } else {
            to_truck.erase(order);
        }
    }
    return moved;
}
Example #6
0
/*
 *   .. to ... from ....
 */
bool
Optimize::swap_worse(Vehicle_pickDeliver &to, Vehicle_pickDeliver &from) {
#if 0
    pgassert(from.orders_in_vehicle().size() <= to.orders_in_vehicle().size());
#endif
    auto from_truck = from;
    auto to_truck = to;

    auto swapped = false;

#if 0
    auto best_from_order = from_truck.orders_in_vehicle().front();
    auto best_to_order = to_truck.orders_in_vehicle().front();
#endif
    for (auto from_orders = from_truck.orders_in_vehicle();
            !from_orders.empty();
            from_orders.pop_front()) {
        auto from_order = from_truck.orders()[from_orders.front()];
#if 0
        pgassert(from_truck.has_order(from_order));
        msg.log << "\n" << from_orders;
        msg.log << "\n from " << from_order.idx()
            << "," << from_order.pickup().original_id();
        pgassert(from_truck.has_order(from_order));
#endif
        auto curr_from_duration = from_truck.duration();
        pgassert(from_truck.has_order(from_order));

        for (auto to_orders = to_truck.orders_in_vehicle();
                !to_orders.empty();
                to_orders.pop_front()) {
            pgassert(from_truck.has_order(from_order));

            auto to_order = to.orders()[to_orders.front()];
#if 0
            msg.log << "\n" << to_orders;
            msg.log << "\n To " << to_order.idx();
#endif
            auto curr_to_duration = to_truck.duration();

            /*
             * delete from_order, and to order from their trucks
             */
#if 0
            pgassert(from_truck.has_order(from_order));
            msg.log << "\n" << from_truck.tau();
            msg.log << "\n" << from_order.idx();
            pgassert(from_truck.has_order(from_order));
#endif
            from_truck.erase(from_order);
            to_truck.erase(to_order);

            /*
             * insert them in the other truck
             */
            from_truck.insert(to_order);
            to_truck.insert(from_order);

            if (from_truck.is_feasable() && to_truck.is_feasable()) {
                /*
                 * Can swap but:
                 *   - only swap when the total duration is reduced
                 *   - or from_truck duration is reduced
                 */
#if 0
                msg.log << "\n Can swap";
                msg.log << "\n Curr_from_duration " << curr_from_duration;
                msg.log << " Curr_to_duration " << curr_to_duration;
                msg.log << "\n  new_from_duration "
                    << from_truck.duration();
                msg.log << "  new_to_duration " << to_truck.duration();
#endif
                auto estimated_delta =
                    - (curr_from_duration + curr_to_duration)
                    + (to_truck.duration() + from_truck.duration());

#if 1
                auto estimated_duration = duration() + estimated_delta;

                if (from_truck.duration() < curr_from_duration ||
                        estimated_delta < 0 ||
                        estimated_duration < best_solution.duration()) {
#endif
                    msg.log
                        << "\n Found Swap order "
                        << from_order.pickup().id()
                        << " from truck " << from_truck.idx()
                        << " with order " << to_order.pickup().id()
                        << " of truck " << to_truck.idx();

                    swapped = true;
#if 0
                    best_to_order = to_order.idx();
                    best_from_order = from_order.idx();
#endif
                    p_swaps.push(
                            Swap_info(
                                from,
                                to,
                                from_order.idx(),
                                to_order.idx(),
                                estimated_delta));
#if 1
                }
#endif
            }
            to_truck = to;
            from_truck = from;
        }
        from_truck = from;
    }

    return false && swapped;
}