Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
MSDispatch_GreedyShared.cpp
Go to the documentation of this file.
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/****************************************************************************/
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>
26#include "MSRoutingEngine.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
38int
39MSDispatch_GreedyShared::dispatch(MSDevice_Taxi* taxi, std::vector<Reservation*>::iterator& resIt, SUMOAbstractRouter<MSEdge, SUMOVehicle>& router, std::vector<Reservation*>& reservations) {
40 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 const bool isPerson = (*res->persons.begin())->isPerson();
47 const int capacityLeft = remainingCapacity(taxi, res);
49 // check whether the ride can be shared
50 int shareCase = 0;
51 Reservation* res2 = nullptr;
52 double absLoss = 0;
53 double relLoss = 0;
54 double absLoss2 = 0;
55 double relLoss2 = 0;
56 double directTime = -1; // only computed once for res
57 double directTime2 = -1;
58 for (auto it2 = resIt + 1; it2 != reservations.end(); it2++) {
59 res2 = *it2;
60 const bool isPerson2 = (*res2->persons.begin())->isPerson();
61
62 if (capacityLeft < (int)res2->persons.size() || isPerson != isPerson2 || !taxi->compatibleLine(res2)) {
63 // do not try to mix person and container dispatch
64 continue;
65 }
66 // res picks up res2 on the way
67 directTime2 = -1; // reset for new candidate
68 const SUMOTime startPickup = MAX2(now, res->pickupTime);
69 const double detourTime = computeDetourTime(startPickup, res2->pickupTime, taxi,
70 res->from, res->fromPos, res2->from, res2->fromPos, res->to, res->toPos, router, directTime);
71 const double absLossPickup = detourTime - directTime;
72 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 if (absLossPickup < myAbsoluteLossThreshold && relLossPickup < myRelativeLossThreshold) {
81 const SUMOTime startDropOff = MAX2(now, res2->pickupTime);
82 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 double detourTime2 = computeDetourTime(startDropOff, startDropOff, taxi,
85 res2->from, res2->fromPos, res2->to, res2->toPos, res->to, res->toPos, router, directTimeTmp);
86 const double absLoss_c1 = absLossPickup + (detourTime2 - directTimeTmp);
87 const double relLoss_c1 = absLoss_c1 / directTime;
88
89 // case 2: res2 is dropped off after res (detour for res2)
90 double detourTime3 = computeDetourTime(startDropOff, startDropOff, taxi,
91 res2->from, res2->fromPos, res->to, res->toPos, res2->to, res2->toPos, router, directTime2);
92 const double absLoss_c2 = detourTime3 - directTime2;
93 const double relLoss_c2 = absLoss_c2 / directTime2;
94
95 if (absLoss_c2 <= absLoss_c1 && absLoss_c2 < myAbsoluteLossThreshold && relLoss_c2 < myRelativeLossThreshold) {
96 shareCase = 2;
97 taxi->dispatchShared({res, res2, res, res2});
98 absLoss = absLossPickup;
99 relLoss = relLossPickup;
100 absLoss2 = absLoss_c2;
101 relLoss2 = relLoss_c2;
102 } else if (absLoss_c1 < myAbsoluteLossThreshold && relLoss_c1 < myRelativeLossThreshold) {
103 shareCase = 1;
104 taxi->dispatchShared({res, res2, res2, res});
105 absLoss = absLoss_c1;
106 relLoss = relLoss_c1;
107 absLoss2 = 0;
108 relLoss2 = 0;
109 }
110 if (shareCase != 0) {
111 reservations.erase(it2); // (it before it2) stays valid
112 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 if (shareCase != 0) {
126 if (myOutput != nullptr) {
127 myOutput->openTag("dispatchShared");
128 myOutput->writeAttr("time", time2string(now));
129 myOutput->writeAttr("id", taxi->getHolder().getID());
130 myOutput->writeAttr("persons", toString(res->persons));
131 myOutput->writeAttr("sharingPersons", toString(res2->persons));
132 myOutput->writeAttr("type", shareCase);
133 myOutput->writeAttr("absLoss", absLoss);
134 myOutput->writeAttr("relLoss", relLoss);
135 myOutput->writeAttr("absLoss2", absLoss2);
136 myOutput->writeAttr("relLoss2", relLoss2);
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 servedReservation(res2); // deleting res2
147 } else {
148 taxi->dispatch(*res);
149 }
150 servedReservation(res); // deleting res
151 resIt = reservations.erase(resIt);
152 return shareCase == 0 ? 1 : 2;
153}
154
155
156/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
#define DEBUG_COND2(obj)
Definition MESegment.cpp:52
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition SUMOTime.cpp:69
#define SIMTIME
Definition SUMOTime.h:62
T MAX2(T a, T b)
Definition StdDefs.h:82
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
A device which collects info on the vehicle trip (mainly on departure and arrival)
void dispatch(const Reservation &res)
service the given reservation
void dispatchShared(std::vector< const Reservation * > reservations)
service the given reservations
bool compatibleLine(const Reservation *res)
whether the given reservation is compatible with the taxi line
const double myRelativeLossThreshold
relative time threshold for declining shared ride
const double myAbsoluteLossThreshold
absolute time threshold for declining shared ride in s
virtual int dispatch(MSDevice_Taxi *taxi, std::vector< Reservation * >::iterator &resIt, SUMOAbstractRouter< MSEdge, SUMOVehicle > &router, std::vector< Reservation * > &reservations)
trigger taxi dispatch.
OutputDevice * myOutput
optional file output for dispatch information
Definition MSDispatch.h:203
int remainingCapacity(const MSDevice_Taxi *taxi, const Reservation *res)
whether the given taxi has sufficient capacity to serve the reservation
static double computeDetourTime(SUMOTime t, SUMOTime viaTime, const MSDevice_Taxi *taxi, const MSEdge *from, double fromPos, const MSEdge *via, double viaPos, const MSEdge *to, double toPos, SUMOAbstractRouter< MSEdge, SUMOVehicle > &router, double &timeDirect)
compute directTime and detourTime
void servedReservation(const Reservation *res)
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition MSNet.cpp:186
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition MSNet.h:320
SUMOVehicle & getHolder() const
Returns the vehicle that holds this device.
const std::string & getID() const
Returns the id.
Definition Named.h:74
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
SUMOTime pickupTime
Definition MSDispatch.h:79
const MSEdge * to
Definition MSDispatch.h:84
double fromPos
Definition MSDispatch.h:82
const MSEdge * from
Definition MSDispatch.h:81
std::set< const MSTransportable * > persons
Definition MSDispatch.h:77
double toPos
Definition MSDispatch.h:85