LCOV - code coverage report
Current view: top level - src/microsim/devices - MSDispatch_Greedy.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 94.9 % 59 56
Test Date: 2024-11-22 15:46:21 Functions: 100.0 % 3 3

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2007-2024 German Aerospace Center (DLR) and others.
       4              : // This program and the accompanying materials are made available under the
       5              : // terms of the Eclipse Public License 2.0 which is available at
       6              : // https://www.eclipse.org/legal/epl-2.0/
       7              : // This Source Code may also be made available under the following Secondary
       8              : // Licenses when the conditions for such availability set forth in the Eclipse
       9              : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10              : // or later which is available at
      11              : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12              : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13              : /****************************************************************************/
      14              : /// @file    MSDispatch_Greedy.cpp
      15              : /// @author  Jakob Erdmann
      16              : /// @date    16.12.2019
      17              : ///
      18              : // An algorithm that performs dispatch for the taxi device
      19              : /****************************************************************************/
      20              : #include <config.h>
      21              : 
      22              : #include <limits>
      23              : #include <microsim/MSNet.h>
      24              : #include <microsim/MSEdge.h>
      25              : #include <microsim/transportables/MSTransportable.h>
      26              : #include "MSRoutingEngine.h"
      27              : #include "MSDispatch_GreedyShared.h"
      28              : 
      29              : //#define DEBUG_DISPATCH
      30              : //#define DEBUG_SERVABLE
      31              : //#define DEBUG_TRAVELTIME
      32              : //#define DEBUG_COND2(obj) (obj->getID() == "p0")
      33              : #define DEBUG_COND2(obj) (true)
      34              : 
      35              : // ===========================================================================
      36              : // MSDispatch_Greedy methods
      37              : // ===========================================================================
      38              : 
      39              : void
      40         6244 : MSDispatch_Greedy::computeDispatch(SUMOTime now, const std::vector<MSDevice_Taxi*>& fleet) {
      41              :     int numDispatched = 0;
      42              :     int numPostponed = 0;
      43              :     // find available vehicles
      44              :     std::set<MSDevice_Taxi*, MSVehicleDevice::ComparatorNumericalVehicleIdLess> available;
      45        14245 :     for (auto* taxi : fleet) {
      46         8001 :         if (taxi->isEmpty()) {
      47              :             available.insert(taxi);
      48              :         }
      49              :     }
      50              :     // greedy assign closest vehicle in reservation order
      51         6246 :     SUMOAbstractRouter<MSEdge, SUMOVehicle>& router = myRoutingMode == 1 ? MSRoutingEngine::getRouterTT(0, SVC_TAXI) : MSNet::getInstance()->getRouterTT(0);
      52         6244 :     std::vector<Reservation*> reservations = getReservations();
      53         6244 :     std::sort(reservations.begin(), reservations.end(), time_sorter());
      54              : #ifdef DEBUG_DISPATCH
      55              :     std::cout << SIMTIME << " computeDispatch fleet=" << fleet.size() << " available=" << available.size() << " reservations=" << toString(reservations) << "\n";
      56              : #endif
      57         7290 :     for (auto it = reservations.begin(); it != reservations.end();) {
      58         2119 :         if (available.size() == 0) {
      59              :             break;
      60              :         }
      61         1048 :         Reservation* res = *it;
      62         1048 :         if (res->recheck > now) {
      63              :             it++;
      64            0 :             numPostponed++;
      65            0 :             continue;
      66              :         }
      67              :         //Position pos = res.from->getLanes().front()->geometryPositionAtOffset(res.fromPos);
      68         1048 :         MSDevice_Taxi* closest = nullptr;
      69              :         SUMOTime closestTime = SUMOTime_MAX;
      70              :         bool tooEarly = false;
      71         2407 :         for (auto* taxi : available) {
      72         1359 :             if (remainingCapacity(taxi, res) < 0 || !taxi->compatibleLine(res)) {
      73           68 :                 continue;
      74              :             }
      75         1291 :             SUMOTime travelTime = computePickupTime(now, taxi, *res, router);
      76              : #ifdef DEBUG_TRAVELTIME
      77              :             if (DEBUG_COND2(person)) {
      78              :                 std::cout << SIMTIME << " taxi=" << taxi->getHolder().getID() << " person=" << toString(res->persons) << " traveltime=" << time2string(travelTime) << "\n";
      79              :             }
      80              : #endif
      81         1291 :             if (travelTime < closestTime) {
      82              :                 closestTime = travelTime;
      83         1196 :                 closest = taxi;
      84         1196 :                 SUMOTime taxiWait = res->pickupTime - (now + closestTime);
      85         1196 :                 if (taxiWait > myMaximumWaitingTime) {
      86              :                     // no need to service this customer now
      87              :                     tooEarly = true;
      88            0 :                     res->recheck += MAX2(now + myRecheckTime, res->pickupTime - closestTime - myRecheckSafety);
      89              :                     break;
      90              :                 }
      91              :             }
      92              :         }
      93         1048 :         if (tooEarly || closest == nullptr) {
      94              :             // too early or all taxis are too small
      95              :             it++;
      96           38 :             numPostponed++;
      97              :         } else {
      98         1010 :             numDispatched += dispatch(closest, it, router, reservations);
      99              :             available.erase(closest);
     100              :         }
     101              :     }
     102              :     // check if any taxis are able to service the remaining requests
     103         6242 :     myHasServableReservations = reservations.size() > 0 && (available.size() < fleet.size() || numPostponed > 0 || numDispatched > 0);
     104              : #ifdef DEBUG_SERVABLE
     105              :     std::cout << SIMTIME << " reservations=" << reservations.size() << " avail=" << available.size()
     106              :               << " fleet=" << fleet.size() << " postponed=" << numPostponed << " dispatched=" << numDispatched << "\n";
     107              : #endif
     108        12486 : }
     109              : 
     110              : 
     111              : int
     112          819 : MSDispatch_Greedy::dispatch(MSDevice_Taxi* taxi, std::vector<Reservation*>::iterator& resIt, SUMOAbstractRouter<MSEdge, SUMOVehicle>& /*router*/, std::vector<Reservation*>& reservations) {
     113              : #ifdef DEBUG_DISPATCH
     114              :     if (DEBUG_COND2(person)) {
     115              :         std::cout << SIMTIME << " dispatch taxi=" << taxi->getHolder().getID() << " person=" << toString((*resIt)->persons) << "\n";
     116              :     }
     117              : #endif
     118          819 :     taxi->dispatch(**resIt);
     119          817 :     servedReservation(*resIt); // deleting res
     120          817 :     resIt = reservations.erase(resIt);
     121          817 :     return 1;
     122              : }
     123              : 
     124              : 
     125              : // ===========================================================================
     126              : // MSDispatch_GreedyClosest methods
     127              : // ===========================================================================
     128              : 
     129              : void
     130          196 : MSDispatch_GreedyClosest::computeDispatch(SUMOTime now, const std::vector<MSDevice_Taxi*>& fleet) {
     131              :     bool havePostponed = false;
     132              :     int numDispatched = 0;
     133              :     // find available vehicles
     134              :     std::set<MSDevice_Taxi*, MSVehicleDevice::ComparatorNumericalVehicleIdLess> available;
     135          576 :     for (auto* taxi : fleet) {
     136          380 :         if (taxi->isEmpty()) {
     137              :             available.insert(taxi);
     138              :         }
     139              :     }
     140              : #ifdef DEBUG_DISPATCH
     141              :     std::cout << SIMTIME << " computeDispatch fleet=" << fleet.size() << " available=" << available.size() << "\n";
     142              : #endif
     143              :     // greedy assign closest vehicle
     144          196 :     SUMOAbstractRouter<MSEdge, SUMOVehicle>& router = myRoutingMode == 1 ? MSRoutingEngine::getRouterTT(0, SVC_TAXI) : MSNet::getInstance()->getRouterTT(0);
     145              :     std::vector<Reservation*> activeReservations;
     146          636 :     for (Reservation* res : getReservations()) {
     147          440 :         if (res->recheck <= now) {
     148          440 :             activeReservations.push_back(res);
     149              :         }
     150          196 :     }
     151          274 :     while (available.size() > 0 && activeReservations.size() > 0) {
     152          112 :         Reservation* closest = nullptr;
     153          112 :         MSDevice_Taxi* closestTaxi = nullptr;
     154              :         SUMOTime closestTime = SUMOTime_MAX;
     155          428 :         for (Reservation* res : activeReservations) {
     156              :             SUMOTime recheck = SUMOTime_MAX;
     157          734 :             for (auto* taxi : available) {
     158          418 :                 if (remainingCapacity(taxi, res) < 0 || !taxi->compatibleLine(res)) {
     159           58 :                     continue;
     160              :                 }
     161          360 :                 SUMOTime travelTime = computePickupTime(now, taxi, *res, router);
     162          360 :                 SUMOTime taxiWait = res->pickupTime - (now + travelTime);
     163              : #ifdef DEBUG_TRAVELTIME
     164              :                 if (DEBUG_COND2(person)) std::cout << SIMTIME << " taxi=" << taxi->getHolder().getID() << " person=" << toString(res->persons)
     165              :                                                        << " traveltime=" << time2string(travelTime)
     166              :                                                        << " pickupTime=" << time2string(res->pickupTime)
     167              :                                                        << " taxiWait=" << time2string(taxiWait) << "\n";
     168              : #endif
     169          360 :                 if (travelTime < closestTime) {
     170          128 :                     if (taxiWait < myMaximumWaitingTime) {
     171              :                         closestTime = travelTime;
     172          128 :                         closest = res;
     173          128 :                         closestTaxi = taxi;
     174              : #ifdef DEBUG_DISPATCH
     175              :                         if (DEBUG_COND2(person)) std::cout << SIMTIME << " bestTaxi=" << taxi->getHolder().getID() << " bestRes=" << toString(res->persons)
     176              :                                                                << " taxiPos=" << taxi->getHolder().getPositionOnLane() << " resFromPos=" << res->fromPos << " traveltime=" << time2string(travelTime) << " taxiWait=" << time2string(taxiWait) << "\n";
     177              : #endif
     178              :                     } else {
     179              :                         recheck = MIN2(recheck,
     180              :                                        MAX2(now + myRecheckTime, res->pickupTime - closestTime - myRecheckSafety));
     181              :                     }
     182              :                 }
     183              :             }
     184              :             /*
     185              :             if (closestTaxi == nullptr) {
     186              :                 // all taxis would arrive to early. postpone recheck
     187              :                 res.recheck = recheck;
     188              :             }
     189              :             */
     190              :         }
     191          112 :         if (closestTaxi != nullptr) {
     192           78 :             auto closeIt = std::find(activeReservations.begin(), activeReservations.end(), closest);
     193           78 :             numDispatched += dispatch(closestTaxi, closeIt, router, activeReservations);
     194              :             available.erase(closestTaxi);
     195              :         } else {
     196              :             // all current reservations are too early or too big
     197              :             havePostponed = true;
     198           34 :             break;
     199              :         }
     200              :     }
     201              :     // check if any taxis are able to service the remaining requests
     202          196 :     myHasServableReservations = getReservations().size() > 0 && (available.size() < fleet.size() || havePostponed || numDispatched > 0);
     203              : #ifdef DEBUG_SERVABLE
     204              :     std::cout << SIMTIME << " reservations=" << getReservations().size() << " avail=" << available.size()
     205              :               << " fleet=" << fleet.size() << " postponed=" << havePostponed << " dispatched=" << numDispatched << "\n";
     206              : #endif
     207          392 : }
     208              : 
     209              : 
     210              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1