1 /****************************************************************************/ 2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo 3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others. 4 // This program and the accompanying materials 5 // are made available under the terms of the Eclipse Public License v2.0 6 // which accompanies this distribution, and is available at 7 // http://www.eclipse.org/legal/epl-v20.html 8 // SPDX-License-Identifier: EPL-2.0 9 /****************************************************************************/ 10 /// @file CHRouterWrapper.h 11 /// @author Jakob Erdmann 12 /// @author Laura Bieker 13 /// @author Michael Behrisch 14 /// @date March 2012 15 /// @version $Id$ 16 /// 17 // Wraps multiple CHRouters for different vehicle types 18 /****************************************************************************/ 19 #ifndef CHRouterWrapper_h 20 #define CHRouterWrapper_h 21 22 23 // =========================================================================== 24 // included modules 25 // =========================================================================== 26 #include <config.h> 27 28 #include <string> 29 #include <functional> 30 #include <vector> 31 #include <set> 32 #include <limits> 33 #include <algorithm> 34 #include <iterator> 35 #include <utils/common/SysUtils.h> 36 #include <utils/common/MsgHandler.h> 37 #include <utils/common/StdDefs.h> 38 #include <utils/router/SUMOAbstractRouter.h> 39 #include <utils/common/SUMOVehicleClass.h> 40 #include "CHRouter.h" 41 42 #ifdef HAVE_FOX 43 #include <utils/foxtools/FXWorkerThread.h> 44 #endif 45 46 47 // =========================================================================== 48 // class definitions 49 // =========================================================================== 50 /** 51 * @class CHRouterWrapper 52 * @brief Computes the shortest path through a contracted network 53 * 54 * The template parameters are: 55 * @param E The edge class to use (MSEdge/ROEdge) 56 * @param V The vehicle class to use (MSVehicle/ROVehicle) 57 * @param PF The prohibition function to use (prohibited_withPermissions/noProhibitions) 58 * 59 * The router is edge-based. It must know the number of edges for internal reasons 60 * and whether a missing connection between two given edges (unbuild route) shall 61 * be reported as an error or as a warning. 62 * 63 */ 64 template<class E, class V, class BASE> 65 class CHRouterWrapper: public BASE { 66 67 public: 68 /// Type of the function that is used to retrieve the edge effort. 69 typedef double(* Operation)(const E* const, const V* const, double); 70 71 /** @brief Constructor 72 */ CHRouterWrapper(const std::vector<E * > & edges,const bool ignoreErrors,typename BASE::Operation operation,const SUMOTime begin,const SUMOTime end,const SUMOTime weightPeriod,const int numThreads)73 CHRouterWrapper(const std::vector<E*>& edges, const bool ignoreErrors, typename BASE::Operation operation, 74 const SUMOTime begin, const SUMOTime end, const SUMOTime weightPeriod, const int numThreads) : 75 BASE("CHRouterWrapper", ignoreErrors, operation), 76 myEdges(edges), 77 myIgnoreErrors(ignoreErrors), 78 myBegin(begin), 79 myEnd(end), 80 myWeightPeriod(weightPeriod), 81 myMaxNumInstances(numThreads) { 82 } 83 ~CHRouterWrapper()84 ~CHRouterWrapper() { 85 for (typename RouterMap::iterator i = myRouters.begin(); i != myRouters.end(); ++i) { 86 for (typename std::vector<CHRouterType*>::iterator j = i->second.begin(); j != i->second.end(); ++j) { 87 delete *j; 88 } 89 } 90 } 91 92 clone()93 virtual SUMOAbstractRouter<E, V>* clone() { 94 CHRouterWrapper<E, V, BASE>* clone = new CHRouterWrapper<E, V, BASE>(myEdges, myIgnoreErrors, this->myOperation, myBegin, myEnd, myWeightPeriod, myMaxNumInstances); 95 for (typename RouterMap::iterator i = myRouters.begin(); i != myRouters.end(); ++i) { 96 for (typename std::vector<CHRouterType*>::iterator j = i->second.begin(); j != i->second.end(); ++j) { 97 clone->myRouters[i->first].push_back(static_cast<CHRouterType*>((*j)->clone())); 98 } 99 } 100 return clone; 101 } 102 103 104 bool compute(const E* from, const E* to, const V* const vehicle, 105 SUMOTime msTime, std::vector<const E*>& into, bool silent = false) { 106 const std::pair<const SUMOVehicleClass, const double> svc = std::make_pair(vehicle->getVClass(), vehicle->getMaxSpeed()); 107 int index = 0; 108 int numIntervals = 1; 109 #ifdef HAVE_FOX 110 if (myMaxNumInstances >= 2 && myEnd < std::numeric_limits<int>::max()) { 111 index = (int)((msTime - myBegin) / myWeightPeriod); 112 numIntervals = (int)((myEnd - myBegin) / myWeightPeriod); 113 if (numIntervals > 0) { 114 while ((int)myThreadPool.size() < myMaxNumInstances) { 115 new FXWorkerThread(myThreadPool); 116 } 117 } else { 118 // this covers the cases of negative (unset) end time and unset weight period (no weight file) 119 numIntervals = 1; 120 } 121 } 122 #endif 123 if (myRouters.count(svc) == 0) { 124 // create new router for the given permissions and maximum speed 125 // XXX a new router may also be needed if vehicles differ in speed factor 126 for (int i = 0; i < numIntervals; i++) { 127 myRouters[svc].push_back(new CHRouterType( 128 myEdges, myIgnoreErrors, &E::getTravelTimeStatic, svc.first, myWeightPeriod, false)); 129 #ifdef HAVE_FOX 130 if (myThreadPool.size() > 0) { 131 myThreadPool.add(new ComputeHierarchyTask(myRouters[svc].back(), vehicle, myBegin + i * myWeightPeriod)); 132 } 133 #endif 134 } 135 #ifdef HAVE_FOX 136 if (myThreadPool.size() > 0) { 137 myThreadPool.waitAll(); 138 } 139 #endif 140 } 141 return myRouters[svc][index]->compute(from, to, vehicle, msTime, into, silent); 142 } 143 144 145 private: 146 typedef CHRouter<E, V, SUMOAbstractRouter<E, V> > CHRouterType; 147 148 #ifdef HAVE_FOX 149 private: 150 class ComputeHierarchyTask : public FXWorkerThread::Task { 151 public: ComputeHierarchyTask(CHRouterType * router,const V * const vehicle,const SUMOTime msTime)152 ComputeHierarchyTask(CHRouterType* router, const V* const vehicle, const SUMOTime msTime) 153 : myRouter(router), myVehicle(vehicle), myStartTime(msTime) {} run(FXWorkerThread *)154 void run(FXWorkerThread* /* context */) { 155 myRouter->buildContractionHierarchy(myStartTime, myVehicle); 156 } 157 private: 158 CHRouterType* myRouter; 159 const V* const myVehicle; 160 const SUMOTime myStartTime; 161 private: 162 /// @brief Invalidated assignment operator. 163 ComputeHierarchyTask& operator=(const ComputeHierarchyTask&); 164 }; 165 166 167 private: 168 /// @brief for multi threaded routing 169 FXWorkerThread::Pool myThreadPool; 170 #endif 171 172 private: 173 typedef std::map<std::pair<const SUMOVehicleClass, const double>, std::vector<CHRouterType*> > RouterMap; 174 175 RouterMap myRouters; 176 177 /// @brief all edges with numerical ids 178 const std::vector<E*>& myEdges; 179 180 const bool myIgnoreErrors; 181 182 const SUMOTime myBegin; 183 const SUMOTime myEnd; 184 const SUMOTime myWeightPeriod; 185 const int myMaxNumInstances; 186 }; 187 188 189 #endif 190 191 /****************************************************************************/ 192 193