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 4475 : ROJTREdge::ROJTREdge(const std::string& id, RONode* from, RONode* to, int index, const int priority) :
37 : ROEdge(id, from, to, index, priority),
38 4475 : mySourceFlows(0)
39 4475 : {}
40 :
41 :
42 8950 : ROJTREdge::~ROJTREdge() {
43 11664 : for (FollowerUsageCont::iterator i = myFollowingDefs.begin(); i != myFollowingDefs.end(); ++i) {
44 14378 : delete (*i).second;
45 : }
46 13425 : }
47 :
48 :
49 : void
50 7656 : ROJTREdge::addSuccessor(ROEdge* s, ROEdge* via, std::string dir) {
51 7656 : ROEdge::addSuccessor(s, via, dir);
52 7656 : ROJTREdge* js = static_cast<ROJTREdge*>(s);
53 7656 : if (myFollowingDefs.find(js) == myFollowingDefs.end()) {
54 7189 : myFollowingDefs[js] = new ValueTimeLine<double>();
55 : }
56 7656 : }
57 :
58 :
59 : void
60 1185 : ROJTREdge::addFollowerProbability(ROJTREdge* follower, double begTime,
61 : double endTime, double probability) {
62 : FollowerUsageCont::iterator i = myFollowingDefs.find(follower);
63 1185 : if (i == myFollowingDefs.end()) {
64 0 : WRITE_ERRORF(TL("The edges '%' and '%' are not connected."), getID(), follower->getID());
65 : return;
66 : }
67 1185 : (*i).second->add(begTime, endTime, probability);
68 : }
69 :
70 :
71 : ROJTREdge*
72 327731 : 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 327731 : if (myFollowingEdges.size() == 0 || (veh != nullptr && allFollowersProhibit(veh))) {
76 555 : return nullptr;
77 : }
78 : // gather information about the probabilities at this time
79 : RandomDistributor<ROJTREdge*> dist;
80 : // use the loaded definitions, first
81 1198054 : for (FollowerUsageCont::const_iterator i = myFollowingDefs.begin(); i != myFollowingDefs.end(); ++i) {
82 870878 : if (avoid.count(i->first) == 0) {
83 1724962 : if ((veh == nullptr || !(*i).first->prohibits(veh)) && (*i).second->describesTime(time)) {
84 27433 : 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 327176 : if (dist.getOverallProb() == 0) {
90 1151774 : for (int i = 0; i < (int)myParsedTurnings.size(); ++i) {
91 838484 : if (avoid.count(myFollowingEdges[i]) == 0) {
92 1664680 : if (veh == nullptr || !myFollowingEdges[i]->prohibits(veh)) {
93 832438 : dist.add(static_cast<ROJTREdge*>(myFollowingEdges[i]), myParsedTurnings[i]);
94 : }
95 : }
96 : }
97 : }
98 : // if still no valid follower exists, return null
99 327176 : if (dist.getOverallProb() == 0) {
100 : return nullptr;
101 : }
102 : // return one of the possible followers
103 326348 : return dist.get();
104 : }
105 :
106 :
107 : void
108 4070 : ROJTREdge::setTurnDefaults(const std::vector<double>& defs) {
109 : // I hope, we'll find a less ridiculous solution for this
110 4070 : std::vector<double> tmp(defs.size()*myFollowingEdges.size(), 0);
111 : // store in less common multiple
112 16946 : for (int i = 0; i < (int)defs.size(); ++i) {
113 35960 : for (int j = 0; j < (int)myFollowingEdges.size(); ++j) {
114 23084 : tmp[i * myFollowingEdges.size() + j] = defs[i] / 100. / (double)myFollowingEdges.size();
115 : }
116 : }
117 : // parse from less common multiple
118 11148 : for (int i = 0; i < (int)myFollowingEdges.size(); ++i) {
119 : double value = 0;
120 30162 : for (int j = 0; j < (int)defs.size(); ++j) {
121 23084 : value += tmp[i * defs.size() + j];
122 : }
123 7078 : myParsedTurnings.push_back((double) value);
124 : }
125 4070 : }
126 :
127 :
128 : /****************************************************************************/
|