61template<
class E,
class V>
89 CHBuilder(
const std::vector<E*>& edges,
bool unbuildIsWarning,
91 bool validatePermissions):
97 for (
const E*
const e : edges) {
110 const int numEdges = (int)
myCHInfos.size();
111 const std::string vClass = (
mySPTree->validatePermissions() ?
117 std::vector<CHInfo*> queue;
119 for (
int i = 0; i < numEdges; i++) {
126 for (
int i = 0; i < numEdges; i++) {
130 for (
int i = 0; i < numEdges; i++) {
134 std::make_heap(queue.begin(), queue.end(),
myCmp);
135 int contractionRank = 0;
137 while (!queue.empty()) {
139 CHInfo* max = queue.front();
140 max->
rank = contractionRank;
141#ifdef CHRouter_DEBUG_CONTRACTION
142 std::cout <<
"contracting '" << max->
edge->getID() <<
"' with prio: " << max->
priority <<
" (rank " << contractionRank <<
")\n";
144 const E*
const edge = max->
edge;
146 const int edgeID = edge->getNumericalID();
148 result->
forwardUplinks[edgeID].push_back(
Connection(con.target->edge->getNumericalID(), con.cost, con.permissions));
150 con.target->updatePriority(0);
156 con.target->updatePriority(0);
170 std::pop_heap(queue.begin(), queue.end(),
myCmp);
243 if (spTree !=
nullptr) {
249 const double oldPriority =
priority;
259#ifdef CHRouter_DEBUG_CONTRACTION_DEGREE
261 std::cout <<
"computing shortcuts for '" +
edge->getID() +
"' with degree " +
toString(degree) +
"\n";
269 const double viaCost = aInfo.cost + fInfo.cost;
270 const SVCPermissions viaPermissions = (aInfo.permissions & fInfo.permissions);
271 if (fInfo.target->traveltime > viaCost) {
273#ifdef CHRouter_DEBUG_CONTRACTION_WITNESSES
276 const int underlying = aInfo.underlying + fInfo.underlying;
279 viaCost, underlying, viaPermissions));
281 }
else if (validatePermissions) {
282 if ((fInfo.target->permissions & viaPermissions) != viaPermissions) {
286#ifdef CHRouter_DEBUG_CONTRACTION_WITNESSES
291#ifdef CHRouter_DEBUG_CONTRACTION_WITNESSES
298 if (validatePermissions) {
302 const double viaCost = aInfo->
cost + fInfo->
cost;
307 viaCost, underlying, viaPermissions));
315 int maxLower = std::numeric_limits<int>::min();
317 if (con.target->rank <
rank) {
322 if (con.target->rank <
rank) {
326 if (maxLower == std::numeric_limits<int>::min()) {
329 level = maxLower + 1;
378 traveltime = std::numeric_limits<double>::max();
388 std::cout <<
"adding shortcut between " << aInfo.
target->
edge->getID() <<
", " << fInfo.
target->
edge->getID() <<
" via " <<
edge->getID() <<
"\n";
392 const double viaCost = aInfo.
cost + fInfo.
cost;
393 std::cout <<
"found witness with length " << fInfo.
target->
traveltime <<
" against via " <<
edge->getID() <<
" (length " << viaCost <<
") for " << aInfo.
target->
edge->getID() <<
", " << fInfo.
target->
edge->getID() <<
"\n";
408 return a->
edge->getNumericalID() > b->
edge->getNumericalID();
417 return &(
myCHInfos[edge->getNumericalID()]);
425 const bool prune = !
mySPTree->validatePermissions();
426 const E*
const edge = info.
edge;
427 if (prune && ((edge->getPermissions() &
mySVC) !=
mySVC)) {
430 const double baseCost = effortProvider->
getEffort(edge, vehicle, time);
432 for (
const std::pair<const E*, const E*>& successor : edge->getViaSuccessors(
mySVC)) {
433 const E* fEdge = successor.first;
434 if (prune && ((fEdge->getPermissions() &
mySVC) !=
mySVC)) {
438 const SVCPermissions permissions = (edge->getPermissions() & fEdge->getPermissions());
439 double cost = baseCost;
440 const E* viaEdge = successor.second;
441 while (viaEdge !=
nullptr && viaEdge->isInternal()) {
442 cost += effortProvider->
getEffort(viaEdge, vehicle, time);
443 viaEdge = viaEdge->getViaSuccessors().front().first;
448#ifdef CHRouter_DEBUG_WEIGHTS
449 std::cout << time <<
": " << edge->getID() <<
" baseCost: " << baseCost <<
"\n";
457 for (
typename CHConnections::iterator it = connections.begin(); it != connections.end(); it++) {
458 if (it->target == other) {
459 connections.erase(it);
471 CHInfo* max = queue.front();
472#ifdef CHRouter_DEBUG_CONTRACTION_QUEUE
473 std::cout <<
"updating '" << max->
edge->getID() <<
"'\n";
474 debugPrintQueue(queue);
477 std::pop_heap(queue.begin(), queue.end(),
myCmp);
478 std::push_heap(queue.begin(), queue.end(),
myCmp);
485#ifdef CHRouter_DEBUG_CONTRACTION_QUEUE
487 void debugPrintQueue(std::vector<CHInfo*>& queue) {
488 for (
const CHInfo*
const chInfo : queue) {
489 std::cout <<
"(" << chInfo->edge->getID() <<
"," << chInfo->priority <<
") ";
#define WRITE_MESSAGE(msg)
#define PROGRESS_DONE_MESSAGE()
#define PROGRESS_BEGIN_MESSAGE(msg)
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
StringBijection< SUMOVehicleClass > SumoVehicleClassStrings(sumoVehicleClassStringInitializer, SVC_CUSTOM2, false)
long long int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_IGNORING
vehicles ignoring classes
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Forward/backward connection with associated FORWARD cost.
int underlying
the number of connections underlying this connection
SVCPermissions permissions
CHConnection(CHInfo *t, double c, SVCPermissions p, int u)
bool operator()(const CHInfo *a, const CHInfo *b) const
Comparing method.
void updateShortcuts(SPTree< CHInfo, CHConnection > *spTree)
compute needed shortcuts when contracting this edge
void resetContractionState()
double traveltime
Effort to reach the edge.
void debugWitness(const CHConnection &aInfo, const CHConnection &fInfo)
CHInfo(const E *const e)
Constructor.
int contractedNeighbors
priority subterms
bool visited
whether the edge has been visited during shortest path search
double priority
The contraction priority.
const E *const edge
The current edge.
bool updatePriority(SPTree< CHInfo, CHConnection > *spTree)
recompute the contraction priority and report whether it changed
SVCPermissions permissions
the permissions when reaching this edge on the fastest path
std::vector< Shortcut > shortcuts
The needed shortcuts.
int depth
number of edges from start
CHConnections followers
connections (only valid after synchronization)
CHConnections approaching
void debugNoWitness(const CHConnection &aInfo, const CHConnection &fInfo)
debugging methods
Forward/backward connection with associated forward/backward cost.
SVCPermissions permissions
Connection(int t, double c, SVCPermissions p)
bool tryUpdateFront(std::vector< CHInfo * > &queue)
tries to update the priority of the first edge
CHBuilder & operator=(const CHBuilder &s)
Invalidated assignment operator.
virtual ~CHBuilder()
Destructor.
std::pair< const CHConnection *, const CHConnection * > CHConnectionPair
std::map< ConstEdgePair, const E * > ShortcutVia
CHInfo * getCHInfo(const E *const edge)
SPTree< CHInfo, CHConnection > * mySPTree
the shortest path tree to use when searching for shortcuts
CHInfoComparator myCmp
Comparator for contraction priority.
const std::vector< E * > & myEdges
all edges with numerical ids
std::vector< CHConnection > CHConnections
std::pair< const E *, const E * > ConstEdgePair
CHBuilder(const std::vector< E * > &edges, bool unbuildIsWarning, const SUMOVehicleClass svc, bool validatePermissions)
Constructor.
std::vector< CHConnectionPair > CHConnectionPairs
std::vector< CHInfo > myCHInfos
static vector for lookup
void synchronize(CHInfo &info, double time, const V *const vehicle, const SUMOAbstractRouter< E, V > *effortProvider)
copy connections from the original net (modified destructively during contraction)
Hierarchy * buildContractionHierarchy(SUMOTime time, const V *const vehicle, const SUMOAbstractRouter< E, V > *effortProvider)
const SUMOVehicleClass mySVC
the permissions for which the hierarchy was constructed
void disconnect(CHConnections &connections, CHInfo *other)
remove all connections to/from the given edge (assume it exists only once)
MsgHandler *const myErrorMsgHandler
the handler for routing errors
int myUpdateCount
counters for performance logging
virtual void endProcessMsg(std::string msg)
Ends a process information.
static MsgHandler * getMessageInstance()
Returns the instance to add normal messages to.
void rebuildFrom(E *start, const E *excluded)
build a shortest path tree from start to a depth of myMaxdepth. The given edge is excluded from this ...
bool validatePermissions()
whether permissions should be validated;
const CHConnectionPairs & getNeededShortcuts(const E *excluded)
void registerForValidation(const C *aInfo, const C *fInfo)
save source/target pair for later validation
double getEffort(const E *const e, const V *const v, double t) const
static long getCurrentMillis()
Returns the current time in milliseconds.
std::vector< std::vector< Connection > > backwardUplinks
std::vector< std::vector< Connection > > forwardUplinks
SVCPermissions permissions
Shortcut(ConstEdgePair e, double c, int u, SVCPermissions p)