Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
AFBuild.h
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2025 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// Class for building the arc flags for (multi-level) arc flag routing
19/****************************************************************************/
20#pragma once
21#include <config.h>
22#include <memory>
23#include <vector>
24#include <unordered_set>
25#include <math.h>
26#include <cmath>
27#include <limits>
28#include <stdexcept>
29#include <string>
30#include <cinttypes>
31#include <utility>
34#include "KDTreePartition.h"
35#include "Node2EdgeRouter.h"
36#include "FlippedEdge.h"
37#include "AFCentralizedSPTree.h"
38
39//#define AFBU_WRITE_QGIS_FILTERS
40#ifdef AFBU_WRITE_QGIS_FILTERS
41#include <fstream>
42#include <sstream>
43#endif
44
45//#define AFBU_DEBUG_LEVEL_0
46//#define AFBU_DEBUG_LEVEL_1
47//#define AFBU_DEBUG_LEVEL_2
48
49#ifdef AFBU_DEBUG_LEVEL_2
50#define AFBU_DEBUG_LEVEL_1
51#endif
52
53#ifdef AFBU_DEBUG_LEVEL_1
54#define AFBU_DEBUG_LEVEL_0
55#endif
56
57// uncomment to disable assert()
58// #define NDEBUG
59#include <cassert>
60
61// ===========================================================================
62// class declarations
63// ===========================================================================
64template<class E, class N, class V, class M>
65class AFRouter;
66
67// ===========================================================================
68// class definitions
69// ===========================================================================
70
81template<class E, class N, class V, class M>
82class AFBuild {
83public:
85 const double EPS = 0.009;
88 typedef typename AFInfo<E>::FlagInfo FlagInfo;
90
103 const std::vector<FlippedEdge<E, N, V>*>& flippedEdges,
104 const KDTreePartition<FlippedEdge<E, N, V>, FlippedNode<E, N, V>, V>* const flippedPartition,
105 int numberOfLevels, bool unbuildIsWarning,
106 typename SUMOAbstractRouter<FlippedEdge<E, N, V>, V>::Operation flippedOperation,
107 const std::shared_ptr<const FlippedLookupTable> flippedLookup = nullptr,
108 const bool havePermissions = false, const bool haveRestrictions = false,
109 const std::map<const FlippedEdge<E, N, V>*, RouterProhibition>* toProhibit = nullptr) :
110 myFlippedEdges(flippedEdges),
111 myFlippedPartition(flippedPartition),
112 myNumberOfLevels(numberOfLevels),
113 myErrorMsgHandler(unbuildIsWarning ? MsgHandler::getWarningInstance() : MsgHandler::getErrorInstance()),
114 myFlippedOperation(flippedOperation),
115 myFlippedLookupTable(flippedLookup),
116 myHavePermissions(havePermissions),
117 myHaveRestrictions(haveRestrictions),
118 myProhibited(toProhibit),
123 if (toProhibit) {
124 myNode2EdgeRouter->prohibit(*toProhibit);
125 }
126 }
127
130 delete myCentralizedSPTree;
131 delete myNode2EdgeRouter;
132 }
133
139 const std::shared_ptr<const FlippedLookupTable> getFlippedLookup() {
141 }
147 void init(SUMOTime time, const V* const vehicle, std::vector<FlagInfo*>& flagInfos);
152 myFlippedPartition = flippedPartition;
153 }
158 int partitionLevel2SHARCLevel(int partitionLevel) {
160 }
168
169protected:
175 void computeArcFlags(SUMOTime msTime, int sHARCLevel, const V* const vehicle);
182 void computeArcFlags(SUMOTime msTime, const int sHARCLevel, const Cell* cell, const V* const vehicle);
189 void computeArcFlagsNaive(SUMOTime msTime, const int sHARCLevel, const Cell* cell, const V* const vehicle);
196 void putArcFlag(ArcInfo* arcInfo, const int sHARCLevel, const bool isLeftOrLowerCell);
198 const std::vector<FlippedEdge<E, N, V>*>& myFlippedEdges;
208 const std::shared_ptr<const FlippedLookupTable> myFlippedLookupTable;
214 const std::map<const FlippedEdge<E, N, V>*, RouterProhibition>* myProhibited;
218 // @note Builds shortest path trees for all boundary nodes at once
219 // @note It operates on a backward graph with flipped edges
222 std::vector<ArcInfo*> myArcInfos;
223
224private:
228 void initBoundaryEdges(const std::unordered_set<const FlippedEdge<E, N, V>*>& boundaryEdges);
234 void initSupercellEdges(const Cell* supercell,
235 const std::unordered_set<const FlippedEdge<E, N, V>*>& boundaryEdges,
236 size_t numberOfBoundaryNodes);
243 void computeArcFlagsAux(SUMOTime msTime, const int sHARCLevel, const Cell* cell, const V* const vehicle);
244}; // end of class AFBuild declaration
245
246// ===========================================================================
247// method definitions
248// ===========================================================================
249
250template<class E, class N, class V, class M>
251void AFBuild<E, N, V, M>::init(SUMOTime msTime, const V* const vehicle, std::vector<FlagInfo*>& flagInfos) {
252 if (myArcInfos.empty()) {
253 for (const FlippedEdge<E, N, V>* const flippedEdge : myFlippedEdges) {
254 myArcInfos.push_back(new ArcInfo(flippedEdge));
255 }
256 }
257 int sHARCLevel;
258 for (sHARCLevel = 0; sHARCLevel < myNumberOfLevels - 1; sHARCLevel++) {
259#ifdef AFBU_DEBUG_LEVEL_0
260 std::cout << "Starting computation of flags of level " << sHARCLevel << " (levels run from 0 to "
261 << myNumberOfLevels - 2 << ")." << std::endl;
262#endif
263#ifdef AFBU_DEBUG_LEVEL_2
264 if (sHARCLevel != 0) {
265 continue;
266 }
267#endif
268 computeArcFlags(msTime, sHARCLevel, vehicle);
269 }
270#ifdef AFBU_DEBUG_LEVEL_0
271 std::cout << "Copying arc flags from the arc infos... " << std::endl;
272#endif
273 int index = 0;
274 for (const ArcInfo* arcInfo : myArcInfos) {
275 flagInfos[index++]->arcFlags = arcInfo->arcFlags;
276 delete arcInfo;
277 }
278#ifdef AFBU_DEBUG_LEVEL_0
279 std::cout << "Arc flags copied from the arc infos. " << std::endl;
280#endif
281 myArcInfos.clear();
282}
283
284template<class E, class N, class V, class M>
285void AFBuild<E, N, V, M>::computeArcFlags(SUMOTime msTime, const int sHARCLevel, const V* const vehicle) {
286 try {
287 assert(myFlippedPartition);
288 const std::vector<const Cell*>& levelCells = myFlippedPartition->getCellsAtLevel(sHARCLevel2PartitionLevel(sHARCLevel));
289#ifdef AFBU_DEBUG_LEVEL_0
290 int i = 0;
291#endif
292 for (const Cell* cell : levelCells) {
293#ifdef AFBU_DEBUG_LEVEL_0
294 std::cout << "Starting to compute core flags of the " << i++ << "th cell..." << std::endl;
295#endif
296#ifdef AFBU_DEBUG_LEVEL_2
297 if (cell->getNumber() == 4) {
298#endif
299 // kept to make comparisons possible
300 //computeArcFlagsNaive(msTime, sHARCLevel, cell, vehicle);
301 computeArcFlags(msTime, sHARCLevel, cell, vehicle);
302 // clean up (all except the computed flags, of course)
303#ifdef AFBU_DEBUG_LEVEL_0
304 std::cout << "Cleaning up after computeArcFlags..." << std::endl;
305#endif
306 for (ArcInfo* arcInfo : myArcInfos) {
307 arcInfo->effortsToBoundaryNodes.clear();
308 arcInfo->touched = false;
309 }
310#ifdef AFBU_DEBUG_LEVEL_0
311 std::cout << "Cleaned up." << std::endl;
312#endif
313#ifdef AFBU_DEBUG_LEVEL_2
314 }
315#endif
316 }
317 } catch (const std::invalid_argument& e) {
318 std::cerr << "Exception: " << e.what() << std::endl;
319 exit(-1);
320 }
321}
322
323template<class E, class N, class V, class M>
324void AFBuild<E, N, V, M>::computeArcFlagsNaive(SUMOTime msTime, const int sHARCLevel, const Cell* cell, const V* const vehicle) {
325 const Cell* supercell = cell->getSupercell();
326 const std::unordered_set<const FlippedEdge<E, N, V>*>& boundaryEdges = cell->getOutgoingBoundaryEdges();
327 const std::vector<const FlippedNode<E, N, V>*>& boundaryNodes = cell->getBoundaryFromNodes();
328#ifdef AFBU_DEBUG_LEVEL_1
329 std::cout << "Number of boundary edges: " << boundaryEdges.size() << std::endl;
330 std::cout << "Number of boundary nodes: " << boundaryNodes.size() << std::endl;
331 std::cout << "Cell number: " << cell->getNumber() << std::endl;
332 std::cout << "Supercell number: " << supercell->getNumber() << std::endl;
333#endif
334 //
335 // initialization of arc flag vectors
336 initBoundaryEdges(boundaryEdges);
337
338#ifdef AFBU_DEBUG_LEVEL_0
339 long long int startTime = SysUtils::getCurrentMillis();
340#endif
341 for (const FlippedNode<E, N, V>* boundaryNode : boundaryNodes) {
342 for (const FlippedEdge<E, N, V>* boundaryEdge : boundaryEdges) {
343 assert(!boundaryEdge->isInternal());
344 ArcInfo* arcInfo = myArcInfos[boundaryEdge->getNumericalID()];
345 if (boundaryNode == boundaryEdge->getFromJunction()) {
346 arcInfo->effortsToBoundaryNodes.push_back(0.);
347 continue;
348 }
349 // compute effort
350 std::vector<const FlippedEdge<E, N, V>*> into;
351#ifdef AFBU_DEBUG_LEVEL_2
352 std::vector<const FlippedEdge<E, N, V>*> into2;
353#endif
354 if (myNode2EdgeRouter->computeNode2Edge(boundaryNode, boundaryEdge, vehicle, msTime, into)) {
355 double recomputedEffort = myNode2EdgeRouter->recomputeCostsNoLastEdge(into, vehicle, msTime);
356 arcInfo->effortsToBoundaryNodes.push_back(recomputedEffort);
357#ifdef AFBU_DEBUG_LEVEL_2
358 if (!into.empty() && myNode2EdgeRouter->compute(into[0], boundaryEdge, vehicle, msTime, into2)) {
359 double recomputedEffort2 = myNode2EdgeRouter->recomputeCosts(into2, vehicle, msTime);
360
361 std::cout << "node2Edge router succeeded, effort: " << recomputedEffort << ", effort incl. last edge: " << recomputedEffort2 << std::endl;
362 assert(recomputedEffort <= recomputedEffort2);
363 }
364#endif
365 } else {
366 arcInfo->effortsToBoundaryNodes.push_back(UNREACHABLE);
367#ifdef AFBU_DEBUG_LEVEL_2
368 std::cout << "UNREACHABLE!" << std::endl;
369#endif
370 }
371 }
372 }
373#ifdef AFBU_DEBUG_LEVEL_0
374 long long int timeSpent = SysUtils::getCurrentMillis() - startTime;
375 std::cout << "Initial distance computation spent " + elapsedMs2string(timeSpent) + "." << std::endl;
376#endif
377
378 // initialize all supercell edges' labels, arc flag vectors for the centralized shortest path tree algorithm / arc flag build
379 initSupercellEdges(supercell, boundaryEdges, boundaryNodes.size());
380#ifdef AFBU_DEBUG_LEVEL_0
381 std::cout << "Initialization of all supercell edges' labels and arc flag vectors done. Starting the centralized shortest path tree algorithm..." << std::endl;
382#endif
383 if (myCentralizedSPTree->computeCentralizedSPTree(msTime, cell, vehicle)) {
384 computeArcFlagsAux(msTime, sHARCLevel, cell, vehicle);
385 }
386#ifdef AFBU_DEBUG_LEVEL_0
387 std::cout << "Centralized shortest path tree algorithm finished." << std::endl;
388#endif
389}
390
391template<class E, class N, class V, class M>
392void AFBuild<E, N, V, M>::computeArcFlags(SUMOTime msTime, const int sHARCLevel, const Cell* cell, const V* const vehicle) {
393 const Cell* supercell = cell->getSupercell();
394 const std::unordered_set<const FlippedEdge<E, N, V>*>& boundaryEdges = cell->getOutgoingBoundaryEdges();
395 const std::vector<const FlippedNode<E, N, V>*>& boundaryNodes = cell->getBoundaryFromNodes();
396#ifdef AFBU_DEBUG_LEVEL_1
397 std::cout << "Number of boundary edges: " << boundaryEdges.size() << std::endl;
398 std::cout << "Number of boundary nodes: " << boundaryNodes.size() << std::endl;
399 std::cout << "Cell number: " << cell->getNumber() << std::endl;
400 std::cout << "Supercell number: " << supercell->getNumber() << std::endl;
401#endif
402 // initialization of arc flag vectors
403 initBoundaryEdges(boundaryEdges);
404#ifdef AFBU_DEBUG_LEVEL_1
405 long long int startTime = SysUtils::getCurrentMillis();
406#endif
407 std::map<const FlippedEdge<E, N, V>*, std::vector<const FlippedEdge<E, N, V>*>> incomingEdgesOfOutgoingBoundaryEdges;
408 size_t numberOfBoundaryNodes = boundaryNodes.size();
409 for (const FlippedEdge<E, N, V>* boundaryEdge : boundaryEdges) {
410 incomingEdgesOfOutgoingBoundaryEdges[boundaryEdge] = std::vector<const FlippedEdge<E, N, V>*>(numberOfBoundaryNodes);
411 }
412 int index = 0; // boundary node index
413 for (const FlippedNode<E, N, V>* boundaryNode : boundaryNodes) {
414 myNode2EdgeRouter->reset(vehicle);
415 if (myNode2EdgeRouter->computeNode2Edges(boundaryNode, boundaryEdges, vehicle, msTime)) {
416#ifdef AFBU_DEBUG_LEVEL_2
417 std::cout << "Node-to-edge router succeeded." << std::endl;
418#endif
419 }
420 for (const FlippedEdge<E, N, V>* boundaryEdge : boundaryEdges) {
421 assert(!boundaryEdge->isInternal());
422 ArcInfo* arcInfo = myArcInfos[boundaryEdge->getNumericalID()];
423 if (boundaryNode == boundaryEdge->getFromJunction()) {
424 arcInfo->effortsToBoundaryNodes.push_back(0.);
425 (incomingEdgesOfOutgoingBoundaryEdges[boundaryEdge])[index] = nullptr;
426 continue;
427 }
428 double effort = (myNode2EdgeRouter->edgeInfo(boundaryEdge))->effort;
429 const FlippedEdge<E, N, V>* incomingEdge
430 = (myNode2EdgeRouter->edgeInfo(boundaryEdge))->prev ?
431 (myNode2EdgeRouter->edgeInfo(boundaryEdge))->prev->edge : nullptr;
432 (incomingEdgesOfOutgoingBoundaryEdges[boundaryEdge])[index] = incomingEdge;
433 arcInfo->effortsToBoundaryNodes.push_back(effort == std::numeric_limits<double>::max() ? UNREACHABLE : effort);
434 }
435 index++;
436 } // end for boundary nodes
437#ifdef AFBU_DEBUG_LEVEL_0
438 long long int timeSpent = SysUtils::getCurrentMillis() - startTime;
439 std::cout << "Initial distance computation spent " + elapsedMs2string(timeSpent) + "." << std::endl;
440#endif
441 // initialize all supercell edges' labels and arc flag vectors for the centralized shortest path DAG algorithm / arc flag build
442 initSupercellEdges(supercell, boundaryEdges, boundaryNodes.size());
443#ifdef AFBU_DEBUG_LEVEL_0
444 std::cout << "Initialization of all supercell edges' labels and arc flag vectors done. Starting the centralized shortest path tree algorithm..." << std::endl;
445#endif
446#ifdef AFBU_DEBUG_LEVEL_0
447 startTime = SysUtils::getCurrentMillis();
448#endif
449 if (myCentralizedSPTree->computeCentralizedSPTree(msTime, cell, vehicle, incomingEdgesOfOutgoingBoundaryEdges)) {
450#ifdef AFBU_DEBUG_LEVEL_0
451 timeSpent = SysUtils::getCurrentMillis() - startTime;
452 std::cout << "Centralized SP tree computation spent " + elapsedMs2string(timeSpent) + "." << std::endl;
453#endif
454 computeArcFlagsAux(msTime, sHARCLevel, cell, vehicle);
455 }
456#ifdef AFBU_DEBUG_LEVEL_0
457 std::cout << "Centralized shortest path tree algorithm finished." << std::endl;
458#endif
459}
460
461template<class E, class N, class V, class M>
462void AFBuild<E, N, V, M>::computeArcFlagsAux(SUMOTime msTime, const int sHARCLevel, const Cell* cell, const V* const vehicle) {
463 const Cell* supercell = cell->getSupercell();
464 std::pair<typename std::vector<const FlippedNode<E, N, V>*>::const_iterator,
465 typename std::vector<const FlippedNode<E, N, V>*>::const_iterator> supercellNodeIterators = supercell->nodeIterators();
466 typename std::vector<const FlippedNode<E, N, V>*>::const_iterator first = supercellNodeIterators.first;
467 typename std::vector<const FlippedNode<E, N, V>*>::const_iterator last = supercellNodeIterators.second;
468 typename std::vector<const FlippedNode<E, N, V>*>::const_iterator iter;
469 std::unordered_set<ArcInfo*> arcInfosOnAShortestPath;
470#ifdef AFBU_DEBUG_LEVEL_1
471 int numberOfSupercellEdges = 0;
472#endif
473 for (iter = first; iter != last; iter++) {
474 const std::vector<const FlippedEdge<E, N, V>*> incomingEdges = (*iter)->getIncoming();
475 for (const FlippedEdge<E, N, V>* supercellEdge : incomingEdges) {
476 if (supercellEdge->isInternal()) {
477 continue;
478 }
479 if (myNode2EdgeRouter->isProhibited(supercellEdge, vehicle, STEPS2TIME(msTime))) {
480 continue;
481 }
482#ifdef AFBU_DEBUG_LEVEL_1
483 numberOfSupercellEdges++;
484#endif
485 ArcInfo* supercellArcInfo = myArcInfos[supercellEdge->getNumericalID()];
486 // start by initializing to set of all supercell edge arc infos
487 arcInfosOnAShortestPath.insert(supercellArcInfo);
488 }
489 }
490#ifdef AFBU_DEBUG_LEVEL_1
491 std::cout << "Number of supercell edges: " << numberOfSupercellEdges << std::endl;
492#endif
493 const SUMOVehicleClass vClass = vehicle == 0 ? SVC_IGNORING : vehicle->getVClass();
494#ifdef AFBU_DEBUG_LEVEL_1
495 std::cout << "Identifying shortest paths..." << std::endl;
496#endif
497#ifdef AFBU_DEBUG_LEVEL_0
498 long long int startTime = SysUtils::getCurrentMillis();
499#endif
500 std::unordered_set<ArcInfo*> erasedEdges;
501 for (auto iter2 = arcInfosOnAShortestPath.begin(); iter2 != arcInfosOnAShortestPath.end();) {
502 const ArcInfo* arcInfo = *iter2;
503 assert(!arcInfo->edge->isInternal());
504 assert(myNode2EdgeRouter);
505 assert(!myNode2EdgeRouter->isProhibited(arcInfo->edge, vehicle, STEPS2TIME(msTime)));
506 size_t numberOfBoundaryNodes = arcInfo->effortsToBoundaryNodes.size();
507 size_t index;
508 bool onShortestPath = false;
509 // attempt to prove that the edge is on a shortest path for at least one boundary node
510 for (index = 0; index < numberOfBoundaryNodes; index++) {
511 double effort1ToBoundaryNode = arcInfo->effortsToBoundaryNodes[index];
512 if (effort1ToBoundaryNode == UNREACHABLE) {
513 continue;
514 }
515 if (effort1ToBoundaryNode == std::numeric_limits<double>::max()) {
516 continue;
517 }
518 double sTime = STEPS2TIME(msTime);
519 double edgeEffort = myNode2EdgeRouter->getEffort(arcInfo->edge, vehicle, sTime);
520 sTime += myNode2EdgeRouter->getTravelTime(arcInfo->edge, vehicle, sTime, edgeEffort);
521 double oldEdgeEffort = edgeEffort;
522 double oldSTime = sTime;
523
524 for (const std::pair<const FlippedEdge<E, N, V>*, const FlippedEdge<E, N, V>*>& follower : arcInfo->edge->getViaSuccessors(vClass)) {
525 assert(!follower.first->isInternal());
526 ArcInfo* followerInfo = myArcInfos[follower.first->getNumericalID()];
527
528 // check whether it can be used
529 if (myNode2EdgeRouter->isProhibited(follower.first, vehicle, sTime)) {
530 myErrorMsgHandler->inform("Vehicle '" + Named::getIDSecure(vehicle) + "' is not allowed on source edge '" + followerInfo->edge->getID() + "'.");
531 continue;
532 }
533 if (followerInfo->effortsToBoundaryNodes.empty()) {
534 continue;
535 }
536 double effort2ToBoundaryNode = followerInfo->effortsToBoundaryNodes[index];
537 if (effort2ToBoundaryNode == UNREACHABLE) {
538 continue;
539 }
540 if (effort2ToBoundaryNode == std::numeric_limits<double>::max()) {
541 continue;
542 }
543
544 // add via efforts to current follower to edge effort
545 double length = 0.; // dummy length for call of updateViaEdgeCost
546 myNode2EdgeRouter->updateViaEdgeCost(follower.second, vehicle,
547 sTime /* has been updated to the time where the edge has been traversed */, edgeEffort, length);
548 // test whether edge is on a shortest path to a boundary node
549 if (effort1ToBoundaryNode + edgeEffort /* edge effort incl. via efforts to current follower of edge */
550 <= effort2ToBoundaryNode /* efforts incl. via efforts to current follower o. e. */
551 + EPS && effort1ToBoundaryNode + edgeEffort >= effort2ToBoundaryNode - EPS) {
552 onShortestPath = true;
553 break; // a shortest path to one boundary node suffices
554 }
555 edgeEffort = oldEdgeEffort;
556 sTime = oldSTime;
557 } // end of loop over outgoing edges
558 } // loop over indexes
559 if (!onShortestPath) {
560 erasedEdges.insert(*iter2);
561 iter2 = arcInfosOnAShortestPath.erase(iter2); // not on a shortest path, remove it
562 } else {
563 ++iter2;
564 }
565 } // loop over edge infos
566
567#ifdef AFBU_DEBUG_LEVEL_0
568 std::cout << "Edges clearly not on a shortest path have been removed. Number of edges on a shortest path is now: "
569 << arcInfosOnAShortestPath.size() << std::endl;
570#endif
571
572 // set arc flags (for level sHARCLevel) for all edges completely inside the cell
573 // (done since these edges all have a to-node inside the cell, i.e. we have to set the own-cell flag for them).
574 std::unordered_set<const FlippedEdge<E, N, V>*>* pEdgesInsideCell = cell->edgeSet(vehicle);
575 std::unordered_set<const FlippedEdge<E, N, V>*> edgesInsideCell = *pEdgesInsideCell;
576#ifdef AFBU_DEBUG_LEVEL_0
577 std::cout << "Adding all edges completely inside the cell to set of edges on a shortest path, cell no:"
578 << cell->getNumber() << std::endl;
579#endif
580 for (const FlippedEdge<E, N, V>* edgeInsideCell : edgesInsideCell) {
581 ArcInfo* arcInfo = myArcInfos[edgeInsideCell->getNumericalID()];
582 if (myNode2EdgeRouter->isProhibited(edgeInsideCell, vehicle, STEPS2TIME(msTime))) {
583 continue;
584 }
585 arcInfosOnAShortestPath.insert(arcInfo);
586 }
587 delete pEdgesInsideCell;
588#ifdef AFBU_DEBUG_LEVEL_0
589 std::cout << "Edges inside cell added." << std::endl;
590 long long int timeSpent = SysUtils::getCurrentMillis() - startTime;
591 std::cout << "Shortest path identification spent " + elapsedMs2string(timeSpent) + "." << std::endl;
592#endif
593
594#ifdef AFBU_WRITE_QGIS_FILTERS
595 std::string qgisFilterString = "id IN (";
596 std::unordered_set<const FlippedNode<E, N, V>*> nodesOnAShortestPath;
597 std::unordered_set<const FlippedNode<E, N, V>*> erasedNodes;
598 for (const ArcInfo* arcInfo : arcInfosOnAShortestPath) {
599 assert(!(myNode2EdgeRouter->edgeInfo(arcInfo->edge))->prohibited
600 && !myNode2EdgeRouter->isProhibited(arcInfo->edge, vehicle));
601 nodesOnAShortestPath.insert(arcInfo->edge->getFromJunction());
602 nodesOnAShortestPath.insert(arcInfo->edge->getToJunction());
603 }
604 for (const ArcInfo* erasedEdgeArcInfo : erasedEdges) {
605 erasedNodes.insert(erasedEdgeArcInfo->edge->getFromJunction());
606 erasedNodes.insert(erasedEdgeArcInfo->edge->getToJunction());
607 }
608 size_t k = 0;
609 // go through the relevant nodes of the supercell
610 size_t numberOfNodesOnAShortestPath = nodesOnAShortestPath.size();
611 for (const FlippedNode<E, N, V>* node : nodesOnAShortestPath) {
612 k++;
613 qgisFilterString += node->getID() + (k < numberOfNodesOnAShortestPath ? ", " : "");
614 }
615 qgisFilterString += ")";
616 std::ostringstream pathAndFileName;
617 pathAndFileName << "./filter_superset_nodes_cell_" << cell->getNumber() << "_supercell_" << supercell->getNumber() << ".qqf";
618 std::ofstream file;
619 file.open(pathAndFileName.str());
620 std::ostringstream content;
621 content << "<Query>" << qgisFilterString << "</Query>";
622 file << content.str();
623 file.close();
624 // erased nodes
625 k = 0;
626 qgisFilterString.clear();
627 qgisFilterString = "id IN (";
628 // go through the erased nodes of the supercell
629 size_t numberOfErasedNodes = erasedNodes.size();
630 for (const FlippedNode<E, N, V>* node : erasedNodes) {
631 k++;
632 qgisFilterString += node->getID() + (k < numberOfErasedNodes ? ", " : "");
633 }
634 qgisFilterString += ")";
635 pathAndFileName.str("");
636 pathAndFileName.clear();
637 pathAndFileName << "./filter_erased_nodes_cell_" << cell->getNumber() << "_supercell_" << supercell->getNumber() << ".qqf";
638 file.clear();
639 file.open(pathAndFileName.str());
640 content.str("");
641 content.clear();
642 content << "<Query>" << qgisFilterString << "</Query>";
643 file << content.str();
644 file.close();
645#endif
646 // put arc flags for level 'sHARCLevel' for all supercell edges which are on a shortest path
647 for (ArcInfo* arcInfo : arcInfosOnAShortestPath) {
648 putArcFlag(arcInfo, sHARCLevel, cell->isLeftOrLowerCell());
649 }
650}
651
652template<class E, class N, class V, class M>
653void AFBuild<E, N, V, M>::putArcFlag(ArcInfo* arcInfo, const int sHARCLevel, const bool isLeftOrLowerCell) {
654 assert(arcInfo);
655 (arcInfo->arcFlags)[sHARCLevel * 2 + (isLeftOrLowerCell ? 0 : 1)] = 1;
656}
657
658template<class E, class N, class V, class M>
659void AFBuild<E, N, V, M>::initBoundaryEdges(const std::unordered_set<const FlippedEdge<E, N, V>*>& boundaryEdges) {
660 // initialization of arc flag vectors
661 for (const FlippedEdge<E, N, V>* boundaryEdge : boundaryEdges) {
662 assert(!boundaryEdge->isInternal());
663 ArcInfo* arcInfo;
664 arcInfo = myArcInfos[boundaryEdge->getNumericalID()];
665 if (arcInfo->arcFlags.empty()) {
666 std::fill_n(std::back_inserter(arcInfo->arcFlags),
667 myFlippedPartition->numberOfArcFlags(), false);
668 }
669 arcInfo->effortsToBoundaryNodes.clear();
670 }
671}
672
673template<class E, class N, class V, class M>
675 const Cell* supercell,
676 const std::unordered_set<const FlippedEdge<E, N, V>*>& boundaryEdges,
677 size_t numberOfBoundaryNodes) {
678 std::pair<typename std::vector<const FlippedNode<E, N, V>*>::const_iterator,
679 typename std::vector<const FlippedNode<E, N, V>*>::const_iterator> supercellNodeIterators = supercell->nodeIterators();
680 typename std::vector<const FlippedNode<E, N, V>*>::const_iterator first = supercellNodeIterators.first;
681 typename std::vector<const FlippedNode<E, N, V>*>::const_iterator last = supercellNodeIterators.second;
682 typename std::vector<const FlippedNode<E, N, V>*>::const_iterator iter;
683 for (iter = first; iter != last; iter++) {
684 const std::vector<const FlippedEdge<E, N, V>*> incomingEdges = (*iter)->getIncoming();
685 for (const FlippedEdge<E, N, V>* supercellEdge : incomingEdges) {
686 if (supercellEdge->isInternal()) {
687 continue;
688 }
689 if (boundaryEdges.count(supercellEdge)) {
690 continue;
691 }
692 ArcInfo* supercellArcInfo;
693 supercellArcInfo = myArcInfos[supercellEdge->getNumericalID()];
694 if (supercellArcInfo->arcFlags.empty()) {
695 std::fill_n(std::back_inserter(supercellArcInfo->arcFlags),
696 myFlippedPartition->numberOfArcFlags(), false);
697 }
698 supercellArcInfo->effortsToBoundaryNodes.clear();
699 std::fill_n(std::back_inserter(supercellArcInfo->effortsToBoundaryNodes),
700 numberOfBoundaryNodes, std::numeric_limits<double>::max());
701 }
702 }
703}
#define UNREACHABLE
Definition AFRouter.h:50
long long int SUMOTime
Definition GUI.h:36
std::string elapsedMs2string(long long int t)
convert ms to string for log output
Definition SUMOTime.cpp:145
#define STEPS2TIME(x)
Definition SUMOTime.h:55
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_IGNORING
vehicles ignoring classes
Builds the flags for (multi-level) arc flag routing (Hilger et al.) in its multi-level variant (also ...
Definition AFBuild.h:82
AFBuild(const std::vector< FlippedEdge< E, N, V > * > &flippedEdges, const KDTreePartition< FlippedEdge< E, N, V >, FlippedNode< E, N, V >, V > *const flippedPartition, int numberOfLevels, bool unbuildIsWarning, typename SUMOAbstractRouter< FlippedEdge< E, N, V >, V >::Operation flippedOperation, const std::shared_ptr< const FlippedLookupTable > flippedLookup=nullptr, const bool havePermissions=false, const bool haveRestrictions=false, const std::map< const FlippedEdge< E, N, V > *, RouterProhibition > *toProhibit=nullptr)
Constructor.
Definition AFBuild.h:102
void initSupercellEdges(const Cell *supercell, const std::unordered_set< const FlippedEdge< E, N, V > * > &boundaryEdges, size_t numberOfBoundaryNodes)
Initialize the supercell edges.
Definition AFBuild.h:674
void init(SUMOTime time, const V *const vehicle, std::vector< FlagInfo * > &flagInfos)
Initialize the arc flag build.
Definition AFBuild.h:251
AFInfo< FlippedEdge< E, N, V > >::ArcInfo ArcInfo
Definition AFBuild.h:87
std::vector< ArcInfo * > myArcInfos
The container of arc informations (for the centralized shortest path tree)
Definition AFBuild.h:222
AFCentralizedSPTree< FlippedEdge< E, N, V >, FlippedNode< E, N, V >, V > * myCentralizedSPTree
A Dijkstra based centralized label-correcting algorithm.
Definition AFBuild.h:220
SUMOAbstractRouter< FlippedEdge< E, N, V >, V >::Operation myFlippedOperation
The object's operation to perform on a backward graph with flipped edges.
Definition AFBuild.h:206
MsgHandler *const myErrorMsgHandler
The handler for routing errors.
Definition AFBuild.h:204
const std::shared_ptr< const FlippedLookupTable > myFlippedLookupTable
The lookup table for travel time heuristics.
Definition AFBuild.h:208
const std::vector< FlippedEdge< E, N, V > * > & myFlippedEdges
The flipped edges.
Definition AFBuild.h:198
~AFBuild()
Destructor.
Definition AFBuild.h:129
SUMOAbstractRouter< FlippedEdge< E, N, V >, V >::Operation getFlippedOperation()
Returns the operation for a backward graph with flipped edges.
Definition AFBuild.h:135
const int myNumberOfLevels
The number of levels.
Definition AFBuild.h:202
AbstractLookupTable< FlippedEdge< E, N, V >, V > FlippedLookupTable
Definition AFBuild.h:89
const std::map< const FlippedEdge< E, N, V > *, RouterProhibition > * myProhibited
The list of explicitly prohibited edges.
Definition AFBuild.h:214
AFInfo< E >::FlagInfo FlagInfo
Definition AFBuild.h:88
void computeArcFlagsAux(SUMOTime msTime, const int sHARCLevel, const Cell *cell, const V *const vehicle)
Helper method for computeArcFlags(), which computes the arc flags for a given cell.
Definition AFBuild.h:462
void initBoundaryEdges(const std::unordered_set< const FlippedEdge< E, N, V > * > &boundaryEdges)
Initialize the boundary edges param[in] boundaryEdges The boundary edges.
Definition AFBuild.h:659
int sHARCLevel2PartitionLevel(int sHARCLevel)
Converts a SHARC level number to a partition level number.
Definition AFBuild.h:165
void setFlippedPartition(const KDTreePartition< FlippedEdge< E, N, V >, FlippedNode< E, N, V >, V > *flippedPartition)
Set the flipped partition param[in] flippedPartition The flipped partition.
Definition AFBuild.h:151
const bool myHaveRestrictions
The boolean flag indicating whether edge restrictions need to be considered or not.
Definition AFBuild.h:212
void putArcFlag(ArcInfo *arcInfo, const int sHARCLevel, const bool isLeftOrLowerCell)
Put the arc flag of the edge in arcInfo.
Definition AFBuild.h:653
const KDTreePartition< FlippedEdge< E, N, V >, FlippedNode< E, N, V >, V > * myFlippedPartition
The partition for the backward graph with flipped edges.
Definition AFBuild.h:200
KDTreePartition< FlippedEdge< E, N, V >, FlippedNode< E, N, V >, V >::Cell Cell
Definition AFBuild.h:86
void computeArcFlagsNaive(SUMOTime msTime, const int sHARCLevel, const Cell *cell, const V *const vehicle)
Computes the arc flags for a given cell (naive version)
Definition AFBuild.h:324
const std::shared_ptr< const FlippedLookupTable > getFlippedLookup()
Returns the lookup table for the backward graph with flipped edges.
Definition AFBuild.h:139
void computeArcFlags(SUMOTime msTime, int sHARCLevel, const V *const vehicle)
Computes the arc flags for all cells at a given level.
Definition AFBuild.h:285
const bool myHavePermissions
The boolean flag indicating whether edge permissions need to be considered or not.
Definition AFBuild.h:210
const double EPS
Maximum difference of two path lengths considered to be equal.
Definition AFBuild.h:85
int partitionLevel2SHARCLevel(int partitionLevel)
Converts a partition level number to a SHARC level number.
Definition AFBuild.h:158
Node2EdgeRouter< FlippedEdge< E, N, V >, FlippedNode< E, N, V >, V, M > * myNode2EdgeRouter
The node-to-edge router (for a backward graph with flipped edges)
Definition AFBuild.h:216
std::vector< bool > arcFlags
The arc flags.
Definition AFInfo.h:107
std::vector< double > effortsToBoundaryNodes
The efforts to boundary nodes.
Definition AFInfo.h:151
const E *const edge
The current edge.
Definition AFInfo.h:65
static int sHARCLevel2PartitionLevel(int sHARCLevel, int numberOfPartitionLevels)
Converts a SHARC level number to a partition level number.
Definition AFRouter.h:317
static int partitionLevel2SHARCLevel(int partitionLevel, int numberOfPartitionLevels)
Converts a partition level number to a SHARC level number.
Definition AFRouter.h:299
The edge type representing backward edges with flipped nodes.
Definition FlippedEdge.h:43
the node type representing nodes used for backward search
Definition FlippedNode.h:32
Partitions the router's network wrt a k-d tree subdivision scheme.
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
Definition Named.h:67
virtual void prohibit(const Prohibitions &toProhibit)
static long getCurrentMillis()
Returns the current time in milliseconds.
Definition SysUtils.cpp:44
Prohibitions and their estimated end time.