Пример #1
0
void CVRPSolver::attemptVehicleExchange(CSolutionInfo& solutionInfo) {
    ++m_iGeneratedSolutionCount;
    ++m_iStepsSinceLastSolution;
    CMoveInfo curMove;
    CMoveInfo bestMove;

    int bestFreeCapacity = 0;
    std::pair<int, int> bestSwapIndex;
    int totalTour = static_cast<int>(solutionInfo.getTourCount());

    for (int i = 0; i < totalTour; ++i) {
        CTourInfo firstTour = solutionInfo.getTour(i);
        int firstTourLoad = firstTour.getVehicleInfo().getCurrentLoad();
        int firstVehicleCapacity = firstTour.getVehicleInfo().getCapacity();

        for (int j = i + 1; j < totalTour; ++j) {
            CTourInfo secondTour = solutionInfo.getTour(j);
            curMove.setInitialTour(firstTour, secondTour);

            int FirstTourRemainingCapacity = firstVehicleCapacity - secondTour.getVehicleInfo().getCurrentLoad();

            int SecondTourRemainingCapacity = secondTour.getVehicleInfo().getCapacity() - firstTourLoad;

            // int prevFreeCapacity = max(secondTour.getRemainingCapacity(), firstTour.getRemainingCapacity() );

            int curFreeCapacity = (std::max)(FirstTourRemainingCapacity, SecondTourRemainingCapacity);

            if ((FirstTourRemainingCapacity > 0) &&  (SecondTourRemainingCapacity > 0) &&
                    // curFreeCapacity > curFreeCapacity autological compare evaluates to false (error on MAC)
                    (curFreeCapacity > bestFreeCapacity)) {
                CVehicleInfo tempVehicle = m_vVehicleInfos[firstTour.getVehicleId()];
                firstTour.setVehicleInfo(m_vVehicleInfos[secondTour.getVehicleId()]);
                secondTour.setVehicleInfo(tempVehicle);

                curMove.setModifiedTour(firstTour, secondTour);

                if (!isTabuMove(curMove)) {
                    bestMove = curMove;
                    bestFreeCapacity = curFreeCapacity;
                    bestSwapIndex = std::make_pair(i, j);
                }

                curMove.getInitialTour(firstTour, secondTour);
            }
        }
    }
    if (bestFreeCapacity > 0) {
        CTourInfo tempTour;
        bestMove.getModifiedTourAt(0, tempTour);
        solutionInfo.replaceTourAt(bestSwapIndex.first, tempTour);
        bestMove.getModifiedTourAt(1, tempTour);
        solutionInfo.replaceTourAt(bestSwapIndex.second, tempTour);
        updateTabuCount(bestMove);
        updateFinalSolution(solutionInfo);
    }
}
Пример #2
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;
}
Пример #3
0
bool CVRPSolver::updateFinalSolution(CSolutionInfo& curSolution) {
    bool callUpdate = false;
    if (curSolution.getOrderServed() > m_solutionFinal.getOrderServed()) {
        callUpdate = true;
    } else if (curSolution.getOrderServed() == m_solutionFinal.getOrderServed()) {
        if (curSolution.getTotalCost() < m_solutionFinal.getTotalCost()) {
            callUpdate = true;
        } else if (curSolution.getTotalCost() == m_solutionFinal.getTotalCost()) {
            if (curSolution.getTotalTravelTime() < m_solutionFinal.getTotalTravelTime()) {
                callUpdate = true;
            } else if (curSolution.getTotalTravelTime() == m_solutionFinal.getTotalTravelTime()) {
                if (curSolution.getTotalDistance() < m_solutionFinal.getTotalDistance()) {
                    callUpdate = true;
                }
            }
        }
    }
    if (callUpdate) {
        // m_iStepsSinceLastSolution = 0;
        m_solutionFinal = curSolution;

        // clear map and delete objects
        // m_mpTabuCount.clear();
        // for (std::map< CVRPTWMove*, int >::iterator it = m_mpMoveFrequency.begin();it!= m_mpMoveFrequency.end();++it)
        // {
        //  delete (*it).first;
        // }
        // m_mpMoveFrequency.clear();
        return true;
    }
    return false;
}
Пример #4
0
void CVRPSolver::applyBestMoveInCurrentSolution(CSolutionInfo& curSolution, CMoveInfo& bestMove) {
    ++m_iGeneratedSolutionCount;
    ++m_iStepsSinceLastSolution;

    updateTabuCount(bestMove);

    int totalTour = static_cast<int>(bestMove.getModifiedTourCount());
    for (int i = 0; i < totalTour; ++i) {
        CTourInfo tourInfo;
        bool bIsValid = bestMove.getModifiedTourAt(i, tourInfo);

        if (bIsValid)
            curSolution.replaceTour(tourInfo);
    }
    updateFinalSolution(curSolution);
}
Пример #5
0
void CVRPSolver::insertUnservedOrders(CSolutionInfo& curSolution) {
    ++m_iGeneratedSolutionCount;
    ++m_iStepsSinceLastSolution;
    bool insertAvailable = true;
    CMoveInfo curMove;
    int totalUnservedOrder = static_cast<int>(m_vOrderInfos.size() - curSolution.getOrderServed());

    while (insertAvailable &&  totalUnservedOrder > 0) {
        int insertTourId = -1;
        insertAvailable = false;
        int totalTour = static_cast<int>(curSolution.getTourInfoVector().size());
        std::pair<int, int> PotentialInsert;  //  first = insert_index, second = removed_customer_index;
        std::pair<int, double> bestInsert = std::make_pair(-1, DOUBLE_MAX);  // first = customer_insert_index, second = cost;

        for (int j = 0; j < totalTour; ++j) {
            CTourInfo curTour = curSolution.getTour(j);
            curMove.setInitialTour(curTour);

            for (int i = 0; i < totalUnservedOrder; ++i) {
                int ordIndex = m_mapOrderIdToIndex[curSolution.getUnservedOrderAt(i)];
                COrderInfo curOrder = m_vOrderInfos[ordIndex];
                std::pair<int, double> curInsert = getPotentialInsert(curTour, curOrder);

                insertOrder(curTour, i, curInsert.first);
                curMove.setModifiedTour(curTour);
                curMove.getInitialTour(curTour);

                // check if current move is tabu.
                if (isTabuMove(curMove)) {
                    continue;
                }

                if (curInsert.second < bestInsert.second) {
                    insertTourId = j;
                    insertAvailable = true;
                    bestInsert = curInsert;
                    PotentialInsert = std::make_pair(curInsert.first, i);
                }
            }
        }
        if (insertAvailable) {
            totalUnservedOrder--;
            curMove.setInitialTour(curSolution.getTour(insertTourId));

            addOrderAtTour(curSolution, insertTourId,
                    PotentialInsert.first,
                    PotentialInsert.second);

            curMove.setModifiedTour(curSolution.getTour(insertTourId));
            this->updateTabuCount(curMove);
            this->updateFinalSolution(curSolution);  // this->evaluateCurrentSolution();
        }
    }
}
Пример #6
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;
}
Пример #7
0
bool CVRPSolver::addOrderAtTour(CSolutionInfo &solutionInfo, int tourIndex, int insertIndex, int orderIndex) {
    return(insertOrder(solutionInfo.getTour(tourIndex), m_vOrderInfos[orderIndex].getOrderId(), insertIndex));
}
Пример #8
0
CSolutionInfo CVRPSolver::generateInitialSolution() {
    CSolutionInfo initialSolution;
    PGR_LOG("Inside gen ini sol");
    std::vector<int> vecOrders, vecVehicles;
    for (unsigned int i = 0; i < m_vOrderInfos.size(); i++) {
        vecOrders.push_back(m_vOrderInfos[i].getOrderId());
    }

    for (unsigned int i = 0; i < m_vVehicleInfos.size(); i++) {
        vecVehicles.push_back(m_vVehicleInfos[i].getId());
    }

    initialSolution.init(vecOrders, static_cast<int>(vecOrders.size()), vecVehicles);

    int iUnusedVehicles = static_cast<int>(initialSolution.getUnusedVehicleCount());
    int iUnservedOrders = static_cast<int>(initialSolution.getUnservedOrderCount());  // m_viUnservedOrderIndex.size();
    PGR_LOG("before while");
    while (iUnusedVehicles &&  iUnservedOrders) {
        CTourInfo curTour;

        int vehicleIndex = rand() % iUnusedVehicles--;
        int vehicleInd = m_mapVehicleIdToIndex[initialSolution.getUnusedVehicleAt(vehicleIndex)];
        curTour.setVehicleInfo(m_vVehicleInfos[vehicleInd]);  // m_viUnusedVehicleIndex[vehicleIndex]
        initialSolution.removeVehicle(vehicleIndex);

        curTour.setStartDepot(m_vDepotInfos[0].getDepotId());
        curTour.setEndDepot(m_vDepotInfos[0].getDepotId());

        // use a random seed to start to tour. (we can use better approach in future)

        bool insertAvailable = true;

        while (insertAvailable) {
            insertAvailable = false;
            std::pair<int, int> PotentialInsert;  //  first = insert_index, second = removed_order_index;
            std::pair<int, double> bestInsert = std::make_pair(-1, DOUBLE_MAX);  // first = order_insert_index, second = cost;

            for (int i = 0; i < iUnservedOrders; ++i) {
                int orderInd = m_mapOrderIdToIndex[initialSolution.getUnservedOrderAt(i)];
                COrderInfo curOrder = m_vOrderInfos[orderInd];
                std::pair<int, double> curInsert = getPotentialInsert(curTour, curOrder);

                if (curInsert.second < bestInsert.second) {
                    insertAvailable = true;
                    bestInsert = curInsert;
                    PotentialInsert = std::make_pair(curInsert.first, i);
                }
            }
            if (insertAvailable) {
                if (insertOrder(curTour, initialSolution.getUnservedOrderAt(PotentialInsert.second), PotentialInsert.first)) {
                    iUnservedOrders--;
                    initialSolution.removeOrder(PotentialInsert.second);
                }
            }
        }

        initialSolution.addTour(curTour);
    }

    return initialSolution;
}