コード例 #1
0
void
Optimize::decrease_truck(size_t cycle, bool &decreased) {
    /* end recursion */
    if (cycle == 0) return;

    std::ostringstream err_log;
    err_log << " --- Cycle " << cycle << "\n";

    /* the front truck move to back */
    std::rotate(fleet.begin(), fleet.begin() + 1, fleet.end());
    err_log << "\n after rotate" << tau();

    auto orders(fleet.back().orders_in_vehicle);
    while (!orders.empty()) {
        /* Step 2: grab an order */
        auto order(problem->orders()[*orders.begin()]);
        orders.erase(orders.begin());
        err_log << "\n truck with order: " << fleet.back().tau();
        err_log << "\nOrder" << order << "\n";

        /* Step 3: delete the order from the back of the fleet */
        pgassertwm(fleet.back().has_order(order), err_log.str());
        fleet.back().erase(order);
        pgassertwm(!fleet.back().has_order(order), err_log.str());

        /* Step 3: cycle the fleet & insert in best truck possible */
        /* current truck is tried last */
        err_log << " trying ";
        auto best_truck(fleet.size() - 1);
        auto current_duration(duration());
        auto min_delta_duration = (std::numeric_limits<double>::max)();
        size_t t_i(0);
        for (auto &truck : fleet) {
            truck.insert(order);
            if (!truck.is_feasable()) {
                err_log << "\n" << truck.tau();
            } else {
                err_log << "\n ******* success " << truck.tau() << "\n";
                auto delta_duration = duration()-current_duration;
                if (t_i != fleet.size() - 1
                        && (delta_duration < min_delta_duration)) {
                    min_delta_duration = delta_duration;
                    best_truck = t_i;
                }
            }
            truck.erase(order);
            ++t_i;
        }
        fleet[best_truck].insert(order);
        save_if_best();
    }

    if (fleet.back().empty()) {
        decreased = true;
        fleet.pop_back();
        save_if_best();
    }
    decrease_truck(--cycle, decreased);
}
コード例 #2
0
void
Optimize::delete_empty_truck() {
    while (fleet.back().empty()) {
        problem->log << "\nEmpty truck";
        fleet.pop_back();
        save_if_best();
    }
    save_if_best();
}
コード例 #3
0
ファイル: optimize.cpp プロジェクト: chahidinho/pgrouting
/*
 * Optimize decreasing truck
 *
 * - Objective: try to remove truck with less duration
 * - Secundary objective, acts like a shake operation
 *
 */
void
Optimize::decrease_truck() {
    bool decreased(false);
    for (size_t i = 1; i < fleet.size(); ++i) {
        decreased = decrease_truck(i) || decreased;
    }
    if (decreased) {
        delete_empty_truck();
        save_if_best();
        decrease_truck();
    }
    save_if_best();
}
コード例 #4
0
ファイル: optimize.cpp プロジェクト: chahidinho/pgrouting
void
Optimize::delete_empty_truck() {
    fleet.erase(std::remove_if(
                fleet.begin(),
                fleet.end(),
                [](const Vehicle_pickDeliver &v){
                return v.orders_in_vehicle().empty();}),
            fleet.end());
    save_if_best();
}
コード例 #5
0
ファイル: optimize.cpp プロジェクト: chahidinho/pgrouting
bool
Optimize::swap_order() {
#if 0
    msg.log << "++++++++" << p_swaps;
#endif
    while (!p_swaps.empty()) {
        auto swap_data = p_swaps.top();
        p_swaps.pop();
        size_t from_pos = 0;
        size_t to_pos = 0;

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

        if (swap_order(
                fleet[from_pos].orders()[swap_data.from_order], fleet[from_pos],
                fleet[to_pos].orders()[swap_data.to_order], fleet[to_pos])) {
            save_if_best();
#if 0
            msg.log
                << "\n Swapping order "
                << fleet[from_pos].orders()[
                    swap_data.from_order].pickup().original_id()
                << " from truck " << fleet[from_pos].id()
                << " with order "
                << fleet[to_pos].orders()[
                    swap_data.to_order].pickup().original_id()
                << " of truck " <<  fleet[to_pos].id();
#endif
#if 0
            msg.log << "\nswappping after:";
            msg.log << "\n" <<  fleet[to_pos].tau();
            msg.log << "\n" << fleet[from_pos].tau();
#endif
            return true;
        }
    }
    return false;
}
コード例 #6
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;
}
コード例 #7
0
bool
Optimize::move_reduce_cost() {
    if (fleet.size() < 2) return false;

    size_t from_pos(fleet.size() - 1);
    while (from_pos > 1) {
        for (size_t to_pos = 0; to_pos < from_pos; ++to_pos) {
            // problem->log << "\nmove_reduce_cost (" << fleet[from_pos].id()  << ", " << fleet[to_pos].id() << ")";
            if (move_reduce_cost(from_pos, to_pos)) {
                if (fleet[from_pos].empty()) {
                    fleet.erase(fleet.begin() + from_pos);
                    save_if_best();
                }
                return true;
            }
        }
        --from_pos;
    }
    return false;
}
コード例 #8
0
bool
Optimize::inter_swap(bool reversed) {
//    problem->log << tau("before sort");
    sort_by_duration();
    delete_empty_truck();
    save_if_best();
    if (reversed) {
        std::reverse(fleet.begin(), fleet.end());
    }
//    problem->log << tau("after sort");
    auto swapped = false;
    size_t from_pos(fleet.size()-1);
    while (from_pos > 1) {
        for (size_t to_pos = 0; to_pos < from_pos; ++to_pos) {
            swapped = swap_worse(from_pos, to_pos)? true : swapped;
            swapped = move_reduce_cost(from_pos, to_pos)? true : swapped;
        }
        delete_empty_truck();
        --from_pos;
    }
    return swapped;
}
コード例 #9
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;
}
コード例 #10
0
ファイル: optimize.cpp プロジェクト: chahidinho/pgrouting
/*
 * 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;
}