Line data Source code
1 : /****************************************************************************/ 2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo 3 : // Copyright (C) 2004-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 ROJTREdge.cpp 15 : /// @author Daniel Krajzewicz 16 : /// @author Jakob Erdmann 17 : /// @author Michael Behrisch 18 : /// @author Yun-Pang Floetteroed 19 : /// @date Tue, 20 Jan 2004 20 : /// 21 : // An edge the jtr-router may route through 22 : /****************************************************************************/ 23 : #include <config.h> 24 : 25 : #include <algorithm> 26 : #include <cassert> 27 : #include <utils/common/MsgHandler.h> 28 : #include <utils/common/RandHelper.h> 29 : #include "ROJTREdge.h" 30 : #include <utils/distribution/RandomDistributor.h> 31 : 32 : 33 : // =========================================================================== 34 : // method definitions 35 : // =========================================================================== 36 7736 : ROJTREdge::ROJTREdge(const std::string& id, RONode* from, RONode* to, int index, const int priority) : 37 : ROEdge(id, from, to, index, priority), 38 7736 : mySourceFlows(0) 39 7736 : {} 40 : 41 : 42 15472 : ROJTREdge::~ROJTREdge() { 43 18880 : for (FollowerUsageCont::iterator i = myFollowingDefs.begin(); i != myFollowingDefs.end(); ++i) { 44 22288 : delete (*i).second; 45 : } 46 15472 : } 47 : 48 : 49 : void 50 12010 : ROJTREdge::addSuccessor(ROEdge* s, ROEdge* via, std::string dir) { 51 12010 : ROEdge::addSuccessor(s, via, dir); 52 12010 : ROJTREdge* js = static_cast<ROJTREdge*>(s); 53 12010 : if (myFollowingDefs.find(js) == myFollowingDefs.end()) { 54 11144 : myFollowingDefs[js] = new ValueTimeLine<double>(); 55 : } 56 12010 : } 57 : 58 : 59 : void 60 1793 : ROJTREdge::addFollowerProbability(ROJTREdge* follower, double begTime, 61 : double endTime, double probability) { 62 : FollowerUsageCont::iterator i = myFollowingDefs.find(follower); 63 1793 : if (i == myFollowingDefs.end()) { 64 0 : WRITE_ERRORF(TL("The edges '%' and '%' are not connected."), getID(), follower->getID()); 65 : return; 66 : } 67 1793 : (*i).second->add(begTime, endTime, probability); 68 : } 69 : 70 : 71 : ROJTREdge* 72 645505 : ROJTREdge::chooseNext(const ROVehicle* const veh, double time, const std::set<const ROEdge*>& avoid) const { 73 : // if no usable follower exist, return 0 74 : // their probabilities are not yet regarded 75 645505 : if (myFollowingEdges.size() == 0 || (veh != nullptr && allFollowersProhibit(veh))) { 76 1110 : return nullptr; 77 : } 78 : // gather information about the probabilities at this time 79 : RandomDistributor<ROJTREdge*> dist; 80 : // use the loaded definitions, first 81 2357170 : for (FollowerUsageCont::const_iterator i = myFollowingDefs.begin(); i != myFollowingDefs.end(); ++i) { 82 1712775 : if (avoid.count(i->first) == 0) { 83 3399356 : if ((veh == nullptr || !(*i).first->prohibits(veh)) && (*i).second->describesTime(time)) { 84 48206 : dist.add((*i).first, (*i).second->getValue(time)); 85 : } 86 : } 87 : } 88 : // if no loaded definitions are valid for this time, try to use the defaults 89 644395 : if (dist.getOverallProb() == 0) { 90 2274690 : for (int i = 0; i < (int)myParsedTurnings.size(); ++i) { 91 1655623 : if (avoid.count(myFollowingEdges[i]) == 0) { 92 3292536 : if (veh == nullptr || !myFollowingEdges[i]->prohibits(veh)) { 93 1646366 : dist.add(static_cast<ROJTREdge*>(myFollowingEdges[i]), myParsedTurnings[i]); 94 : } 95 : } 96 : } 97 : } 98 : // if still no valid follower exists, return null 99 644395 : if (dist.getOverallProb() == 0) { 100 : return nullptr; 101 : } 102 : // return one of the possible followers 103 643345 : return dist.get(); 104 644395 : } 105 : 106 : 107 : void 108 6926 : ROJTREdge::setTurnDefaults(const std::vector<double>& defs) { 109 : // I hope, we'll find a less ridiculous solution for this 110 6926 : std::vector<double> tmp(defs.size()*myFollowingEdges.size(), 0); 111 : // store in less common multiple 112 28370 : for (int i = 0; i < (int)defs.size(); ++i) { 113 56060 : for (int j = 0; j < (int)myFollowingEdges.size(); ++j) { 114 34616 : tmp[i * myFollowingEdges.size() + j] = defs[i] / 100. / (double)myFollowingEdges.size(); 115 : } 116 : } 117 : // parse from less common multiple 118 17848 : for (int i = 0; i < (int)myFollowingEdges.size(); ++i) { 119 : double value = 0; 120 45538 : for (int j = 0; j < (int)defs.size(); ++j) { 121 34616 : value += tmp[i * defs.size() + j]; 122 : } 123 10922 : myParsedTurnings.push_back((double) value); 124 : } 125 6926 : } 126 : 127 : 128 : /****************************************************************************/