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); } }
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; }