LCOV - code coverage report
Current view: top level - src/microsim/devices - MSDispatch_GreedyShared.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 98.5 % 68 67
Test Date: 2024-11-22 15:46:21 Functions: 100.0 % 1 1

            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_GreedyShared.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_COND2(obj) (obj->getID() == "p0")
      31              : #define DEBUG_COND2(obj) (true)
      32              : 
      33              : 
      34              : // ===========================================================================
      35              : // MSDispatch_GreedyShared methods
      36              : // ===========================================================================
      37              : 
      38              : int
      39          162 : MSDispatch_GreedyShared::dispatch(MSDevice_Taxi* taxi, std::vector<Reservation*>::iterator& resIt, SUMOAbstractRouter<MSEdge, SUMOVehicle>& router, std::vector<Reservation*>& reservations) {
      40          162 :     const Reservation* const res = *resIt;
      41              : #ifdef DEBUG_DISPATCH
      42              :     if (DEBUG_COND2(person)) {
      43              :         std::cout << SIMTIME << " dispatch taxi=" << taxi->getHolder().getID() << " person=" << toString(res->persons) << "\n";
      44              :     }
      45              : #endif
      46          162 :     const bool isPerson = (*res->persons.begin())->isPerson();
      47          162 :     const int capacityLeft = remainingCapacity(taxi, res);
      48          162 :     const SUMOTime now = MSNet::getInstance()->getCurrentTimeStep();
      49              :     // check whether the ride can be shared
      50          162 :     int shareCase = 0;
      51              :     Reservation* res2 = nullptr;
      52          162 :     double absLoss = 0;
      53          162 :     double relLoss = 0;
      54          162 :     double absLoss2 = 0;
      55          162 :     double relLoss2 = 0;
      56          162 :     double directTime = -1; // only computed once for res
      57          162 :     double directTime2 = -1;
      58          248 :     for (auto it2 = resIt + 1; it2 != reservations.end(); it2++) {
      59          182 :         res2 = *it2;
      60          182 :         const bool isPerson2 = (*res2->persons.begin())->isPerson();
      61              : 
      62          182 :         if (capacityLeft < (int)res2->persons.size() || isPerson != isPerson2 || !taxi->compatibleLine(res2)) {
      63              :             // do not try to mix person and container dispatch
      64            0 :             continue;
      65              :         }
      66              :         // res picks up res2 on the way
      67          182 :         directTime2 = -1; // reset for new candidate
      68          182 :         const SUMOTime startPickup = MAX2(now, res->pickupTime);
      69          182 :         const double detourTime = computeDetourTime(startPickup, res2->pickupTime, taxi,
      70          182 :                                   res->from, res->fromPos, res2->from, res2->fromPos, res->to, res->toPos, router, directTime);
      71          182 :         const double absLossPickup = detourTime - directTime;
      72          182 :         const double relLossPickup = absLossPickup / directTime;
      73              : 
      74              : #ifdef DEBUG_DISPATCH
      75              :         if (DEBUG_COND2(person)) std::cout << "  consider sharing ride with " << toString(res2->persons)
      76              :                                                << " absLossPickup=" << absLossPickup
      77              :                                                << " relLossPickup=" << relLossPickup
      78              :                                                << "\n";
      79              : #endif
      80          182 :         if (absLossPickup < myAbsoluteLossThreshold && relLossPickup < myRelativeLossThreshold) {
      81          108 :             const SUMOTime startDropOff = MAX2(now, res2->pickupTime);
      82          108 :             double directTimeTmp = -1; // direct time from picking up res2 to dropping of res
      83              :             // case 1: res2 is dropped off before res (more detour for res)
      84          108 :             double detourTime2 = computeDetourTime(startDropOff, startDropOff, taxi,
      85          108 :                                                    res2->from, res2->fromPos, res2->to, res2->toPos, res->to, res->toPos, router, directTimeTmp);
      86          108 :             const double absLoss_c1 = absLossPickup + (detourTime2 - directTimeTmp);
      87          108 :             const double relLoss_c1 = absLoss_c1 / directTime;
      88              : 
      89              :             // case 2: res2 is dropped off after res (detour for res2)
      90          108 :             double detourTime3 = computeDetourTime(startDropOff, startDropOff, taxi,
      91          108 :                                                    res2->from, res2->fromPos, res->to, res->toPos, res2->to, res2->toPos, router, directTime2);
      92          108 :             const double absLoss_c2 = detourTime3 - directTime2;
      93          108 :             const double relLoss_c2 = absLoss_c2 / directTime2;
      94              : 
      95          108 :             if (absLoss_c2 <= absLoss_c1 && absLoss_c2 < myAbsoluteLossThreshold && relLoss_c2 < myRelativeLossThreshold) {
      96           66 :                 shareCase = 2;
      97           66 :                 taxi->dispatchShared({res, res2, res, res2});
      98           66 :                 absLoss = absLossPickup;
      99           66 :                 relLoss = relLossPickup;
     100           66 :                 absLoss2 = absLoss_c2;
     101           66 :                 relLoss2 = relLoss_c2;
     102           42 :             } else if (absLoss_c1 < myAbsoluteLossThreshold && relLoss_c1 < myRelativeLossThreshold) {
     103           30 :                 shareCase = 1;
     104           30 :                 taxi->dispatchShared({res, res2, res2, res});
     105           30 :                 absLoss = absLoss_c1;
     106           30 :                 relLoss = relLoss_c1;
     107           30 :                 absLoss2 = 0;
     108           30 :                 relLoss2 = 0;
     109              :             }
     110          108 :             if (shareCase != 0) {
     111              :                 reservations.erase(it2); // (it before it2) stays valid
     112           96 :                 break;
     113              :             } else {
     114              : #ifdef DEBUG_DISPATCH
     115              :                 if (DEBUG_COND2(person)) std::cout << "     rejected:"
     116              :                                                        << " absLoss_c1=" << absLoss_c1
     117              :                                                        << " relLoss_c1=" << relLoss_c1
     118              :                                                        << " absLoss_c2=" << absLoss_c2
     119              :                                                        << " relLoss_c2=" << relLoss_c2
     120              :                                                        << "\n";
     121              : #endif
     122              :             }
     123              :         }
     124              :     }
     125          162 :     if (shareCase != 0) {
     126           96 :         if (myOutput != nullptr) {
     127           84 :             myOutput->openTag("dispatchShared");
     128          168 :             myOutput->writeAttr("time", time2string(now));
     129           84 :             myOutput->writeAttr("id", taxi->getHolder().getID());
     130          168 :             myOutput->writeAttr("persons", toString(res->persons));
     131          168 :             myOutput->writeAttr("sharingPersons", toString(res2->persons));
     132           84 :             myOutput->writeAttr("type", shareCase);
     133           84 :             myOutput->writeAttr("absLoss", absLoss);
     134           84 :             myOutput->writeAttr("relLoss", relLoss);
     135           84 :             myOutput->writeAttr("absLoss2", absLoss2);
     136           84 :             myOutput->writeAttr("relLoss2", relLoss2);
     137          168 :             myOutput->closeTag();
     138              :         }
     139              : #ifdef DEBUG_DISPATCH
     140              :         if (DEBUG_COND2(person)) std::cout << "  sharing ride with " << toString(res2->persons)
     141              :                                                << " type=" << shareCase
     142              :                                                << " absLoss=" << absLoss << " relLoss=" << relLoss
     143              :                                                << " absLoss2=" << absLoss2 << " relLoss2=" << relLoss2
     144              :                                                << "\n";
     145              : #endif
     146           96 :         servedReservation(res2); // deleting res2
     147              :     } else {
     148           66 :         taxi->dispatch(*res);
     149              :     }
     150          162 :     servedReservation(res); // deleting res
     151          162 :     resIt = reservations.erase(resIt);
     152          258 :     return shareCase == 0 ? 1 : 2;
     153              : }
     154              : 
     155              : 
     156              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1