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-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/****************************************************************************/
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>
65class AFRouter;
66
67// ===========================================================================
68// class definitions
69// ===========================================================================
70
81template<class E, class N, class V>
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::vector<FlippedEdge<E, N, V>*>* 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::vector<FlippedEdge<E, N, V>*>* 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>
251void AFBuild<E, N, V>::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>
285void AFBuild<E, N, V>::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>
324void AFBuild<E, N, V>::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>
392void AFBuild<E, N, V>::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>
462void AFBuild<E, N, V>::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->edgeInfo(supercellEdge))->prohibited
480 || myNode2EdgeRouter->isProhibited(supercellEdge, vehicle)) {
481 continue;
482 }
483#ifdef AFBU_DEBUG_LEVEL_1
484 numberOfSupercellEdges++;
485#endif
486 ArcInfo* supercellArcInfo = myArcInfos[supercellEdge->getNumericalID()];
487 // start by initializing to set of all supercell edge arc infos
488 arcInfosOnAShortestPath.insert(supercellArcInfo);
489 }
490 }
491#ifdef AFBU_DEBUG_LEVEL_1
492 std::cout << "Number of supercell edges: " << numberOfSupercellEdges << std::endl;
493#endif
494 const SUMOVehicleClass vClass = vehicle == 0 ? SVC_IGNORING : vehicle->getVClass();
495#ifdef AFBU_DEBUG_LEVEL_1
496 std::cout << "Identifying shortest paths..." << std::endl;
497#endif
498#ifdef AFBU_DEBUG_LEVEL_0
499 long long int startTime = SysUtils::getCurrentMillis();
500#endif
501 std::unordered_set<ArcInfo*> erasedEdges;
502 for (auto iter2 = arcInfosOnAShortestPath.begin(); iter2 != arcInfosOnAShortestPath.end();) {
503 const ArcInfo* arcInfo = *iter2;
504 assert(!arcInfo->edge->isInternal());
505 assert(myNode2EdgeRouter);
506 assert(!(myNode2EdgeRouter->edgeInfo(arcInfo->edge))->prohibited
507 && !myNode2EdgeRouter->isProhibited(arcInfo->edge, vehicle));
508 size_t numberOfBoundaryNodes = arcInfo->effortsToBoundaryNodes.size();
509 size_t index;
510 bool onShortestPath = false;
511 // attempt to prove that the edge is on a shortest path for at least one boundary node
512 for (index = 0; index < numberOfBoundaryNodes; index++) {
513 double effort1ToBoundaryNode = arcInfo->effortsToBoundaryNodes[index];
514 if (effort1ToBoundaryNode == UNREACHABLE) {
515 continue;
516 }
517 if (effort1ToBoundaryNode == std::numeric_limits<double>::max()) {
518 continue;
519 }
520 double sTime = STEPS2TIME(msTime);
521 double edgeEffort = myNode2EdgeRouter->getEffort(arcInfo->edge, vehicle, sTime);
522 sTime += myNode2EdgeRouter->getTravelTime(arcInfo->edge, vehicle, sTime, edgeEffort);
523 double oldEdgeEffort = edgeEffort;
524 double oldSTime = sTime;
525
526 for (const std::pair<const FlippedEdge<E, N, V>*, const FlippedEdge<E, N, V>*>& follower : arcInfo->edge->getViaSuccessors(vClass)) {
527 assert(!follower.first->isInternal());
528 ArcInfo* followerInfo = myArcInfos[follower.first->getNumericalID()];
529
530 // check whether it can be used
531 if ((myNode2EdgeRouter->edgeInfo(follower.first))->prohibited
532 || myNode2EdgeRouter->isProhibited(follower.first, vehicle)) {
533 myErrorMsgHandler->inform("Vehicle '" + Named::getIDSecure(vehicle) + "' is not allowed on source edge '" + followerInfo->edge->getID() + "'.");
534 continue;
535 }
536 if (followerInfo->effortsToBoundaryNodes.empty()) {
537 continue;
538 }
539 double effort2ToBoundaryNode = followerInfo->effortsToBoundaryNodes[index];
540 if (effort2ToBoundaryNode == UNREACHABLE) {
541 continue;
542 }
543 if (effort2ToBoundaryNode == std::numeric_limits<double>::max()) {
544 continue;
545 }
546
547 // add via efforts to current follower to edge effort
548 double length = 0.; // dummy length for call of updateViaEdgeCost
549 myNode2EdgeRouter->updateViaEdgeCost(follower.second, vehicle,
550 sTime /* has been updated to the time where the edge has been traversed */, edgeEffort, length);
551 // test whether edge is on a shortest path to a boundary node
552 if (effort1ToBoundaryNode + edgeEffort /* edge effort incl. via efforts to current follower of edge */
553 <= effort2ToBoundaryNode /* efforts incl. via efforts to current follower o. e. */
554 + EPS && effort1ToBoundaryNode + edgeEffort >= effort2ToBoundaryNode - EPS) {
555 onShortestPath = true;
556 break; // a shortest path to one boundary node suffices
557 }
558 edgeEffort = oldEdgeEffort;
559 sTime = oldSTime;
560 } // end of loop over outgoing edges
561 } // loop over indexes
562 if (!onShortestPath) {
563 erasedEdges.insert(*iter2);
564 iter2 = arcInfosOnAShortestPath.erase(iter2); // not on a shortest path, remove it
565 } else {
566 ++iter2;
567 }
568 } // loop over edge infos
569
570#ifdef AFBU_DEBUG_LEVEL_0
571 std::cout << "Edges clearly not on a shortest path have been removed. Number of edges on a shortest path is now: "
572 << arcInfosOnAShortestPath.size() << std::endl;
573#endif
574
575 // set arc flags (for level sHARCLevel) for all edges completely inside the cell
576 // (done since these edges all have a to-node inside the cell, i.e. we have to set the own-cell flag for them).
577 std::unordered_set<const FlippedEdge<E, N, V>*>* pEdgesInsideCell = cell->edgeSet(vehicle);
578 std::unordered_set<const FlippedEdge<E, N, V>*> edgesInsideCell = *pEdgesInsideCell;
579#ifdef AFBU_DEBUG_LEVEL_0
580 std::cout << "Adding all edges completely inside the cell to set of edges on a shortest path, cell no:"
581 << cell->getNumber() << std::endl;
582#endif
583 for (const FlippedEdge<E, N, V>* edgeInsideCell : edgesInsideCell) {
584 ArcInfo* arcInfo = myArcInfos[edgeInsideCell->getNumericalID()];
585 if ((myNode2EdgeRouter->edgeInfo(edgeInsideCell))->prohibited
586 || myNode2EdgeRouter->isProhibited(edgeInsideCell, vehicle)) {
587 continue;
588 }
589 arcInfosOnAShortestPath.insert(arcInfo);
590 }
591 delete pEdgesInsideCell;
592#ifdef AFBU_DEBUG_LEVEL_0
593 std::cout << "Edges inside cell added." << std::endl;
594 long long int timeSpent = SysUtils::getCurrentMillis() - startTime;
595 std::cout << "Shortest path identification spent " + elapsedMs2string(timeSpent) + "." << std::endl;
596#endif
597
598#ifdef AFBU_WRITE_QGIS_FILTERS
599 std::string qgisFilterString = "id IN (";
600 std::unordered_set<const FlippedNode<E, N, V>*> nodesOnAShortestPath;
601 std::unordered_set<const FlippedNode<E, N, V>*> erasedNodes;
602 for (const ArcInfo* arcInfo : arcInfosOnAShortestPath) {
603 assert(!(myNode2EdgeRouter->edgeInfo(arcInfo->edge))->prohibited
604 && !myNode2EdgeRouter->isProhibited(arcInfo->edge, vehicle));
605 nodesOnAShortestPath.insert(arcInfo->edge->getFromJunction());
606 nodesOnAShortestPath.insert(arcInfo->edge->getToJunction());
607 }
608 for (const ArcInfo* erasedEdgeArcInfo : erasedEdges) {
609 erasedNodes.insert(erasedEdgeArcInfo->edge->getFromJunction());
610 erasedNodes.insert(erasedEdgeArcInfo->edge->getToJunction());
611 }
612 size_t k = 0;
613 // go through the relevant nodes of the supercell
614 size_t numberOfNodesOnAShortestPath = nodesOnAShortestPath.size();
615 for (const FlippedNode<E, N, V>* node : nodesOnAShortestPath) {
616 k++;
617 qgisFilterString += node->getID() + (k < numberOfNodesOnAShortestPath ? ", " : "");
618 }
619 qgisFilterString += ")";
620 std::ostringstream pathAndFileName;
621 pathAndFileName << "./filter_superset_nodes_cell_" << cell->getNumber() << "_supercell_" << supercell->getNumber() << ".qqf";
622 std::ofstream file;
623 file.open(pathAndFileName.str());
624 std::ostringstream content;
625 content << "<Query>" << qgisFilterString << "</Query>";
626 file << content.str();
627 file.close();
628 // erased nodes
629 k = 0;
630 qgisFilterString.clear();
631 qgisFilterString = "id IN (";
632 // go through the erased nodes of the supercell
633 size_t numberOfErasedNodes = erasedNodes.size();
634 for (const FlippedNode<E, N, V>* node : erasedNodes) {
635 k++;
636 qgisFilterString += node->getID() + (k < numberOfErasedNodes ? ", " : "");
637 }
638 qgisFilterString += ")";
639 pathAndFileName.str("");
640 pathAndFileName.clear();
641 pathAndFileName << "./filter_erased_nodes_cell_" << cell->getNumber() << "_supercell_" << supercell->getNumber() << ".qqf";
642 file.clear();
643 file.open(pathAndFileName.str());
644 content.str("");
645 content.clear();
646 content << "<Query>" << qgisFilterString << "</Query>";
647 file << content.str();
648 file.close();
649#endif
650 // put arc flags for level 'sHARCLevel' for all supercell edges which are on a shortest path
651 for (ArcInfo* arcInfo : arcInfosOnAShortestPath) {
652 putArcFlag(arcInfo, sHARCLevel, cell->isLeftOrLowerCell());
653 }
654}
655
656template<class E, class N, class V>
657void AFBuild<E, N, V>::putArcFlag(ArcInfo* arcInfo, const int sHARCLevel, const bool isLeftOrLowerCell) {
658 assert(arcInfo);
659 (arcInfo->arcFlags)[sHARCLevel * 2 + (isLeftOrLowerCell ? 0 : 1)] = 1;
660}
661
662template<class E, class N, class V>
663void AFBuild<E, N, V>::initBoundaryEdges(const std::unordered_set<const FlippedEdge<E, N, V>*>& boundaryEdges) {
664 // initialization of arc flag vectors
665 for (const FlippedEdge<E, N, V>* boundaryEdge : boundaryEdges) {
666 assert(!boundaryEdge->isInternal());
667 ArcInfo* arcInfo;
668 arcInfo = myArcInfos[boundaryEdge->getNumericalID()];
669 if (arcInfo->arcFlags.empty()) {
670 std::fill_n(std::back_inserter(arcInfo->arcFlags),
671 myFlippedPartition->numberOfArcFlags(), false);
672 }
673 arcInfo->effortsToBoundaryNodes.clear();
674 }
675}
676
677template<class E, class N, class V>
679 const Cell* supercell,
680 const std::unordered_set<const FlippedEdge<E, N, V>*>& boundaryEdges,
681 size_t numberOfBoundaryNodes) {
682 std::pair<typename std::vector<const FlippedNode<E, N, V>*>::const_iterator,
683 typename std::vector<const FlippedNode<E, N, V>*>::const_iterator> supercellNodeIterators = supercell->nodeIterators();
684 typename std::vector<const FlippedNode<E, N, V>*>::const_iterator first = supercellNodeIterators.first;
685 typename std::vector<const FlippedNode<E, N, V>*>::const_iterator last = supercellNodeIterators.second;
686 typename std::vector<const FlippedNode<E, N, V>*>::const_iterator iter;
687 for (iter = first; iter != last; iter++) {
688 const std::vector<const FlippedEdge<E, N, V>*> incomingEdges = (*iter)->getIncoming();
689 for (const FlippedEdge<E, N, V>* supercellEdge : incomingEdges) {
690 if (supercellEdge->isInternal()) {
691 continue;
692 }
693 if (boundaryEdges.count(supercellEdge)) {
694 continue;
695 }
696 ArcInfo* supercellArcInfo;
697 supercellArcInfo = myArcInfos[supercellEdge->getNumericalID()];
698 if (supercellArcInfo->arcFlags.empty()) {
699 std::fill_n(std::back_inserter(supercellArcInfo->arcFlags),
700 myFlippedPartition->numberOfArcFlags(), false);
701 }
702 supercellArcInfo->effortsToBoundaryNodes.clear();
703 std::fill_n(std::back_inserter(supercellArcInfo->effortsToBoundaryNodes),
704 numberOfBoundaryNodes, std::numeric_limits<double>::max());
705 }
706 }
707}
#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:123
#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
Node2EdgeRouter< FlippedEdge< E, N, V >, FlippedNode< E, N, V >, V > * myNode2EdgeRouter
The node-to-edge router (for a backward graph with flipped edges)
Definition AFBuild.h:216
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:678
AbstractLookupTable< FlippedEdge< E, N, V >, V > FlippedLookupTable
Definition AFBuild.h:89
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
MsgHandler *const myErrorMsgHandler
The handler for routing errors.
Definition AFBuild.h:204
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:663
KDTreePartition< FlippedEdge< E, N, V >, FlippedNode< E, N, V >, V >::Cell Cell
Definition AFBuild.h:86
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
const std::vector< FlippedEdge< E, N, V > * > & myFlippedEdges
The flipped edges.
Definition AFBuild.h:198
const bool myHavePermissions
The boolean flag indicating whether edge permissions need to be considered or not.
Definition AFBuild.h:210
std::vector< ArcInfo * > myArcInfos
The container of arc informations (for the centralized shortest path tree)
Definition AFBuild.h:222
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 double EPS
Maximum difference of two path lengths considered to be equal.
Definition AFBuild.h:85
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:657
AFCentralizedSPTree< FlippedEdge< E, N, V >, FlippedNode< E, N, V >, V > * myCentralizedSPTree
A Dijkstra based centralized label-correcting algorithm.
Definition AFBuild.h:220
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 std::vector< FlippedEdge< E, N, V > * > * myProhibited
The list of explicitly prohibited edges.
Definition AFBuild.h:214
int sHARCLevel2PartitionLevel(int sHARCLevel)
Converts a SHARC level number to a partition level number.
Definition AFBuild.h:165
const int myNumberOfLevels
The number of levels.
Definition AFBuild.h:202
const std::shared_ptr< const FlippedLookupTable > myFlippedLookupTable
The lookup table for travel time heuristics.
Definition AFBuild.h:208
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
SUMOAbstractRouter< FlippedEdge< E, N, V >, V >::Operation getFlippedOperation()
Returns the operation for a backward graph with flipped edges.
Definition AFBuild.h:135
~AFBuild()
Destructor.
Definition AFBuild.h:129
const std::shared_ptr< const FlippedLookupTable > getFlippedLookup()
Returns the lookup table for the backward graph with flipped edges.
Definition AFBuild.h:139
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::vector< FlippedEdge< E, N, V > * > *toProhibit=nullptr)
Constructor.
Definition AFBuild.h:102
int partitionLevel2SHARCLevel(int partitionLevel)
Converts a partition level number to a SHARC level number.
Definition AFBuild.h:158
void init(SUMOTime time, const V *const vehicle, std::vector< FlagInfo * > &flagInfos)
Initialize the arc flag build.
Definition AFBuild.h:251
AFInfo< E >::FlagInfo FlagInfo
Definition AFBuild.h:88
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
AFInfo< FlippedEdge< E, N, V > >::ArcInfo ArcInfo
Definition AFBuild.h:87
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 std::vector< E * > &toProhibit)
static long getCurrentMillis()
Returns the current time in milliseconds.
Definition SysUtils.cpp:44