예제 #1
0
bool CSolutionInfo::addTour(CTourInfo& tour) {
    m_vtourAll.push_back(tour);
    int vid = tour.getVehicleId();
    std::vector<int>::iterator it;
    it = std::find(m_vUnusedVehicles.begin(), m_vUnusedVehicles.end(), vid);
    if (it != m_vUnusedVehicles.end()) {
        m_vUnusedVehicles.erase(it);
    }
    m_iVehicleUsed++;
    m_dTotalDistance += tour.getDistance();
    m_dTotalTravelTime += tour.getTravelTime();
    m_dTotalCost += tour.getCost();

    std::vector<int> vecOrders = tour.getOrderVector();

    m_iOrdersServed += static_cast<int>(vecOrders.size());

    for (const auto &order : vecOrders) {
        int oid = order;
        it = std::find(m_vUnservedOrderId.begin(), m_vUnservedOrderId.end(), oid);
        if (it != m_vUnservedOrderId.end()) {
            m_vUnservedOrderId.erase(it);
        }
    }

    return true;
}
예제 #2
0
CostPack CVRPSolver::getCostForInsert(CTourInfo& curTour, COrderInfo& curOrder, int pos) {
    std::vector<int> vecOrderId = curTour.getOrderVector();

    vecOrderId.insert(vecOrderId.begin() + pos, curOrder.getOrderId());
    double dCost, dDistance, dTravelTime;
    dCost = dDistance = dTravelTime = 0.0;
    CostPack costRet;

    costRet.cost = INF;
    costRet.distance = INF;
    costRet.traveltime = INF;

    CostPack cPack = getDepotToOrderCost(curTour.getStartDepot(), vecOrderId[0]);

    dCost += cPack.cost;
    dDistance += cPack.distance;

    int ind = m_mapOrderIdToIndex[vecOrderId[0]];

    if (dTravelTime + cPack.traveltime > m_vOrderInfos[ind].getCloseTime())
        return costRet;

    dTravelTime = (std::max)(dTravelTime + cPack.traveltime + m_vOrderInfos[ind].getServiceTime(),
            static_cast<double>(m_vOrderInfos[ind].getOpenTime() + m_vOrderInfos[ind].getServiceTime()));

    unsigned int i;
    for (i = 1; i < vecOrderId.size(); i++) {
        cPack = getOrderToOrderCost(vecOrderId[i - 1], vecOrderId[i]);
        dCost += cPack.cost;
        dDistance += cPack.distance;

        ind = m_mapOrderIdToIndex[vecOrderId[i]];

        if (dTravelTime + cPack.traveltime > m_vOrderInfos[ind].getCloseTime())
            return costRet;

        dTravelTime = (std::max)(dTravelTime + cPack.traveltime + m_vOrderInfos[ind].getServiceTime(),
                static_cast<double>(m_vOrderInfos[ind].getOpenTime() + m_vOrderInfos[ind].getServiceTime()));
    }

    cPack = getOrderToDepotCost(vecOrderId[i - 1], curTour.getEndDepot());
    dCost += cPack.cost;
    dDistance += cPack.distance;

    dTravelTime += cPack.traveltime;

    ind = m_mapDepotIdToIndex[curTour.getEndDepot()];
    if (dTravelTime > m_vDepotInfos[ind].getCloseTime())
        return costRet;

    costRet.cost = dCost - curTour.getCost();
    costRet.distance = dDistance - curTour.getDistance();
    costRet.traveltime = dTravelTime - curTour.getTravelTime();

    return costRet;
}
예제 #3
0
bool CVRPSolver::updateTourCosts(CTourInfo& tourInfo) {
    std::vector<int> vecOrderId = tourInfo.getOrderVector();
    std::vector<int> vecStartTimes;

    double dCost, dDistance, dTravelTime;
    dCost = dDistance = dTravelTime = 0.0;

    CostPack cPack = getDepotToOrderCost(tourInfo.getStartDepot(), vecOrderId[0]);

    dCost += cPack.cost;
    dDistance += cPack.distance;

    int ind = m_mapOrderIdToIndex[vecOrderId[0]];
    vecStartTimes.push_back(0);

    if (dTravelTime + cPack.traveltime > m_vOrderInfos[ind].getCloseTime())
        return false;

    dTravelTime = (std::max)(dTravelTime + cPack.traveltime + m_vOrderInfos[ind].getServiceTime(),
            static_cast<double>(m_vOrderInfos[ind].getOpenTime() + m_vOrderInfos[ind].getServiceTime()));
    vecStartTimes.push_back(static_cast<int>(ceil(dTravelTime)));

    unsigned int i;
    for (i = 1; i < vecOrderId.size(); i++) {
        cPack = getOrderToOrderCost(vecOrderId[i - 1], vecOrderId[i]);
        dCost += cPack.cost;
        dDistance += cPack.distance;

        ind = m_mapOrderIdToIndex[vecOrderId[i]];

        if (dTravelTime + cPack.traveltime > m_vOrderInfos[ind].getCloseTime())
            return false;

        dTravelTime = (std::max)(dTravelTime + cPack.traveltime + m_vOrderInfos[ind].getServiceTime(),
                static_cast<double>(m_vOrderInfos[ind].getOpenTime() + m_vOrderInfos[ind].getServiceTime()));

        vecStartTimes.push_back(static_cast<int>(ceil(dTravelTime)));
    }

    cPack = getOrderToDepotCost(vecOrderId[i - 1], tourInfo.getEndDepot());
    dCost += cPack.cost;
    dDistance += cPack.distance;

    dTravelTime += cPack.traveltime;

    vecStartTimes.push_back(static_cast<int>(ceil(dTravelTime)));
    ind = m_mapDepotIdToIndex[tourInfo.getEndDepot()];
    if (dTravelTime > m_vDepotInfos[ind].getCloseTime())
        return false;

    tourInfo.updateCost(dCost, dDistance, dTravelTime);

    tourInfo.setStartTime(vecStartTimes);

    return true;
}
예제 #4
0
void CVRPSolver::attemptFeasibleNodeExchange(CSolutionInfo& solutionInfo) {
    ++m_iGeneratedSolutionCount;
    ++m_iStepsSinceLastSolution;
    CMoveInfo bestMove, curMove;

    int totalTour = solutionInfo.getTourCount();

    for (int i = 0; i < totalTour; ++i) {
        CTourInfo curTour = solutionInfo.getTour(i);
        std::vector<int> vecOrderId = curTour.getOrderVector();
        curMove.setInitialTour(curTour);
        int totalCustomer = curTour.getServedOrderCount();
        std::pair<int, int> bestSwapIndex;
        double lowestCost = DOUBLE_MAX;

        for (int j = 0; j < totalCustomer; ++j) {
            for (int k = j + 1; k < totalCustomer; ++k) {
                COrderInfo firstCustomer = m_vOrderInfos[m_mapOrderIdToIndex[vecOrderId[j]]];
                COrderInfo secondCustomer = m_vOrderInfos[m_mapOrderIdToIndex[vecOrderId[k]]];

                if (curTour->isFeasibleReplace(j, pSecondCustomer) &&  pCurTour->isFeasibleReplace(k, pFirstCustomer)) {
                    pCurTour->removeCustomer(j, false);
                    pCurTour->addCustomer(pSecondCustomer, j);

                    pCurTour->removeCustomer(k, false);
                    pCurTour->addCustomer(pFirstCustomer, k);

                    pCurMove->setModifiedTour(pCurTour);
                    if (isTabuMove(pCurMove)) {
                        pCurMove->getInitialTour(pCurTour);
                        continue;
                    }

                    double curTourCost = pCurTour->getTourData()->calcCost(pCurTour->getAssignedVehicle());
                    if (curTourCost < lowestCost) {
                        *pBestMove = *pCurMove;
                        lowestCost = curTourCost;
                        bestSwapIndex = std::make_pair(j, k);
                    }
                    pCurMove->getInitialTour(pCurTour);
                }
            }
        }

        if (lowestCost!= DOUBLE_MAX) {
            m_pCurrentSolution->replaceTourAt(i, pBestMove->getModifiedTourAt(0));
            this->updateTabuCount(pBestMove);
            this->evaluateCurrentSolution();
        }
    }
    delete pCurMove;
    delete pBestMove;
}
예제 #5
0
bool CVRPSolver::insertOrder(CTourInfo& tourInfo, int orderId, int pos) {
    if (pos < 0 ||  (unsigned int) pos > tourInfo.getOrderVector().size())
        return false;

    int orderIndex = m_mapOrderIdToIndex[orderId];
    if (!tourInfo.getVehicleInfo().loadUnit(m_vOrderInfos[orderIndex].getOrderUnit()))
        return false;
    tourInfo.insertOrder(orderId, pos);

    if (!updateTourCosts(tourInfo)) {
        tourInfo.removeOrder(pos);
        return false;
    }

    return true;
}
예제 #6
0
std::pair<int, double> CVRPSolver::getPotentialInsert(CTourInfo& curTour, COrderInfo& curOrder) {
    std::pair<int, double> bestInsert = std::make_pair(-1, DOUBLE_MAX);
    if (curOrder.getOrderUnit() > curTour.getRemainingCapacity()) {
        return bestInsert;
    }
    // check if ith position insert is fisible.
    std::vector<int> vecOrderId = curTour.getOrderVector();
    for (unsigned int i = 0; i <= vecOrderId.size(); ++i) {
        CostPack costToOrder, costFromOrder;

        if (!i) {
            costToOrder = getDepotToOrderCost(curTour.getStartDepot(), curOrder.getOrderId());
        } else {
            costToOrder = getOrderToOrderCost(vecOrderId[i-1], curOrder.getOrderId());
        }

        double dArrivalTime = costToOrder.traveltime + curTour.getStartTime(i);

        if (dArrivalTime > curOrder.getCloseTime()) {
            continue;
        }

        if (i == vecOrderId.size()) {
            costFromOrder = getOrderToDepotCost(curOrder.getOrderId(), curTour.getEndDepot());
        } else {
            costFromOrder = getOrderToOrderCost(curOrder.getOrderId(), vecOrderId[i]);
        }

        dArrivalTime += curOrder.getServiceTime() + costFromOrder.traveltime;

        if (i < vecOrderId.size() &&  dArrivalTime > m_vOrderInfos[m_mapOrderIdToIndex[vecOrderId[i]]].getCloseTime()) {
            continue;
        }

        CostPack totalCost = getCostForInsert(curTour, curOrder, i);

        if (totalCost.cost < bestInsert.second) {
            bestInsert = std::make_pair(i, totalCost.cost);
        }
    }
    return bestInsert;
}
예제 #7
0
int find_vrp_solution(vrp_vehicles_t *vehicles, size_t vehicle_count,
                      vrp_orders_t *orders, size_t order_count,
                      vrp_cost_element_t *costmatrix, size_t cost_count,
                      int depot_id,
                      vrp_result_element_t **results, size_t *result_count, char **err_msg) {
    int res;

    std::string strError;
    try {
        PGR_LOG("Before load order");
        loadOrders(orders, static_cast<int>(order_count), depot_id);
        PGR_LOG("After load order");
        loadVehicles(vehicles, static_cast<int>(vehicle_count));
        PGR_LOG("After load vehicles");
        loadDistanceMatrix(costmatrix, static_cast<int>(cost_count), depot_id);
        PGR_LOG("After load distance matrix");
        res = solver.solveVRP(strError);
        PGR_LOG("After VRP Solve");
    }
    catch(std::exception& e) {
        *err_msg = (char *) e.what();
        return -1;
    }
    catch(...) {
        *err_msg = (char *) "Caught unknown exception!";
        return -1;
    }


    if (res < 0) {
        return res;
    } else {
        try {
        CSolutionInfo solution;
        CTourInfo ctour;
        // bool bOK =
                solver.getSolution(solution, strError);
        auto totalRoute = solution.getTourInfoVector().size();
        size_t totRows = 0;
        for (size_t i = 0; i < totalRoute; i++) {
            totRows += (solution.getTour(static_cast<int>(i)).getServedOrderCount() + 2);
        }
        *results = (vrp_result_element_t *) malloc(totRows * sizeof(vrp_result_element_t));
        *result_count = totRows;
        int cnt = 0;
        for (size_t i = 0; i < totalRoute; i++) {
            ctour = solution.getTour(static_cast<int>(i));
            std::vector<int> vecOrder = ctour.getOrderVector();
            auto totalOrder = vecOrder.size();

            // For start depot
            (*results)[cnt].order_id = ctour.getStartDepot();
            (*results)[cnt].order_pos = 0;
            (*results)[cnt].vehicle_id = ctour.getVehicleId();
            (*results)[cnt].arrival_time = -1;
            (*results)[cnt].depart_time = ctour.getStartTime(0);
            cnt++;

            // For each order
            for (size_t j = 0; j < totalOrder; j++) {
                (*results)[cnt].order_id = vecOrder[j];
                (*results)[cnt].order_pos = static_cast<int>(j) + 1;
                (*results)[cnt].vehicle_id = ctour.getVehicleId();
                (*results)[cnt].depart_time = ctour.getStartTime(static_cast<int>(j) + 1);
                (*results)[cnt].arrival_time = ctour.getStartTime(static_cast<int>(j) + 1) - solver.getServiceTime(vecOrder[j]);
                cnt++;
            }

            // For return depot
            (*results)[cnt].order_id = ctour.getEndDepot();
            (*results)[cnt].order_pos = static_cast<int>(totalOrder) + 1;
            (*results)[cnt].vehicle_id = ctour.getVehicleId();
            (*results)[cnt].arrival_time = ctour.getStartTime(static_cast<int>(totalOrder) + 1);
            (*results)[cnt].depart_time = -1;
            cnt++;
        }
        }
        catch(std::exception& e) {
        *err_msg = (char *) e.what();
        return -1;
        }
        catch(...) {
        *err_msg = (char *) "Caught unknown exception!";
        return -1;
        }
    }
    return EXIT_SUCCESS;
}