@@ -128,6 +128,8 @@ namespace dsm {
128128 const TContainer& dst_weights,
129129 const size_t minNodeDistance = 0 );
130130
131+ void addAgentsRandomly (Size nAgents, const size_t minNodeDistance = 0 );
132+
131133 // / @brief Evolve the simulation
132134 // / @details Evolve the simulation by moving the agents and updating the travel times.
133135 // / In particular:
@@ -234,7 +236,10 @@ namespace dsm {
234236 }
235237 }
236238 }
237- assert (possibleMoves.size () > 0 );
239+ if (possibleMoves.empty ()) {
240+ Logger::error (
241+ std::format (" No possible moves from node {} for agent {}" , nodeId, agentId));
242+ }
238243 std::uniform_int_distribution<Size> moveDist{
239244 0 , static_cast <Size>(possibleMoves.size () - 1 )};
240245 uint8_t p{0 };
@@ -317,9 +322,7 @@ namespace dsm {
317322 }
318323 }
319324 if (bArrived) {
320- if (pStreet->dequeue (queueIndex) == std::nullopt ) {
321- continue ;
322- }
325+ pStreet->dequeue (queueIndex);
323326 m_travelDTs.push_back ({pAgent->distance (), static_cast <double >(pAgent->time ())});
324327 if (reinsert_agents) {
325328 // reset Agent's values
@@ -334,10 +337,10 @@ namespace dsm {
334337 if (nextStreet->isFull ()) {
335338 continue ;
336339 }
337- if (pStreet->dequeue (queueIndex) == std::nullopt ) {
338- continue ;
340+ pStreet->dequeue (queueIndex);
341+ if (destinationNode->id () != nextStreet->source ()) {
342+ Logger::error (std::format (" Agent {} is going to the wrong street" , agentId));
339343 }
340- assert (destinationNode->id () == nextStreet->nodePair ().first );
341344 if (destinationNode->isIntersection ()) {
342345 auto & intersection = dynamic_cast <Intersection&>(*destinationNode);
343346 auto const delta{nextStreet->deltaAngle (pStreet->angle ())};
@@ -492,7 +495,7 @@ namespace dsm {
492495 } else if (!agent->streetId ().has_value () && !agent->nextStreetId ().has_value ()) {
493496 Id srcNodeId = agent->srcNodeId ().has_value () ? agent->srcNodeId ().value ()
494497 : nodeDist (this ->m_generator );
495- const auto & srcNode{this ->m_graph .nodeSet ()[ srcNodeId] };
498+ const auto & srcNode{this ->m_graph .node ( srcNodeId) };
496499 if (srcNode->isFull ()) {
497500 continue ;
498501 }
@@ -594,7 +597,16 @@ namespace dsm {
594597 const TContainer& src_weights,
595598 const TContainer& dst_weights,
596599 const size_t minNodeDistance) {
597- if (src_weights.size () == 1 && dst_weights.size () == 1 &&
600+ auto const & nSources{src_weights.size ()};
601+ auto const & nDestinations{dst_weights.size ()};
602+ Logger::debug (
603+ std::format (" Init addAgentsRandomly for {} agents from {} nodes to {} nodes with "
604+ " minNodeDistance {}" ,
605+ nAgents,
606+ nSources,
607+ dst_weights.size (),
608+ minNodeDistance));
609+ if (nSources == 1 && nDestinations == 1 &&
598610 src_weights.begin ()->first == dst_weights.begin ()->first ) {
599611 throw std::invalid_argument (Logger::buildExceptionMessage (
600612 std::format (" The only source node {} is also the only destination node." ,
@@ -628,9 +640,10 @@ namespace dsm {
628640 if (!this ->agents ().empty ()) {
629641 agentId = this ->agents ().rbegin ()->first + 1 ;
630642 }
643+ Logger::debug (std::format (" Adding {} agents at time {}." , nAgents, this ->time ()));
631644 while (nAgents > 0 ) {
632645 Id srcId{0 }, dstId{0 };
633- if (dst_weights. size () == 1 ) {
646+ if (nDestinations == 1 ) {
634647 dstId = dst_weights.begin ()->first ;
635648 srcId = dstId;
636649 }
@@ -646,19 +659,24 @@ namespace dsm {
646659 }
647660 }
648661 }
649- if (src_weights. size () > 1 ) {
662+ if (nSources > 1 ) {
650663 dstId = srcId;
651664 }
652665 while (dstId == srcId) {
653666 dRand = dstUniformDist (this ->m_generator );
654667 sum = 0 .;
655668 for (const auto & [id, weight] : dst_weights) {
656669 // if the node is at a minimum distance from the destination, skip it
657- auto result{this ->m_graph .shortestPath (srcId, id)};
658- if (result.has_value () && result.value ().path ().size () < minNodeDistance &&
659- dst_weights.size () > 1 ) {
670+ if (this ->itineraries ().at (id)->path ().getRow (srcId).empty ()) {
660671 continue ;
661672 }
673+ if (nDestinations > 1 && minNodeDistance > 0 ) {
674+ // NOTE: Result must have a value in this case, so we can use value() as sort-of assertion
675+ if (this ->m_graph .shortestPath (srcId, id).value ().path ().size () <
676+ minNodeDistance) {
677+ continue ;
678+ }
679+ }
662680 dstId = id;
663681 sum += weight;
664682 if (dRand < sum) {
@@ -681,6 +699,20 @@ namespace dsm {
681699 }
682700 }
683701
702+ template <typename delay_t >
703+ requires (is_numeric_v<delay_t >)
704+ void RoadDynamics<delay_t >::addAgentsRandomly(Size nAgents,
705+ const size_t minNodeDistance) {
706+ std::unordered_map<Id, double > src_weights, dst_weights;
707+ for (auto const & id : this ->m_graph .inputNodes ()) {
708+ src_weights[id] = 1 .;
709+ }
710+ for (auto const & id : this ->m_graph .outputNodes ()) {
711+ dst_weights[id] = 1 .;
712+ }
713+ addAgentsRandomly (nAgents, src_weights, dst_weights, minNodeDistance);
714+ }
715+
684716 template <typename delay_t >
685717 requires (is_numeric_v<delay_t >)
686718 void RoadDynamics<delay_t >::evolve(bool reinsert_agents) {
@@ -699,15 +731,6 @@ namespace dsm {
699731 }
700732 }
701733 }
702- // for (const auto& [streetId, pStreet] : this->m_graph.streetSet()) {
703- // if (bUpdateData) {
704- // m_streetTails[streetId] += pStreet->nExitingAgents();
705- // }
706- // Logger::info(std::format("Evolving street {}", streetId));
707- // for (auto i = 0; i < pStreet->transportCapacity(); ++i) {
708- // this->m_evolveStreet(pStreet, reinsert_agents);
709- // }
710- // }
711734 // Move transport capacity agents from each node
712735 for (const auto & [nodeId, pNode] : this ->m_graph .nodeSet ()) {
713736 for (auto i = 0 ; i < pNode->transportCapacity (); ++i) {
@@ -747,11 +770,11 @@ namespace dsm {
747770
748771 double inputGreenSum{0 .}, inputRedSum{0 .};
749772 for (const auto & [streetId, _] : this ->m_graph .adjMatrix ().getCol (nodeId, true )) {
750- auto const & pStreet{this ->m_graph .streetSet ()[ streetId] };
773+ auto const & pStreet{this ->m_graph .street ( streetId) };
751774 if (streetPriorities.contains (streetId)) {
752- inputGreenSum += m_streetTails[ streetId] / pStreet->nLanes ();
775+ inputGreenSum += m_streetTails. at ( streetId) / pStreet->nLanes ();
753776 } else {
754- inputRedSum += m_streetTails[ streetId] / pStreet->nLanes ();
777+ inputRedSum += m_streetTails. at ( streetId) / pStreet->nLanes ();
755778 }
756779 }
757780 inputGreenSum /= meanGreenFraction;
@@ -791,11 +814,11 @@ namespace dsm {
791814 // - If the previous check fails, do nothing
792815 double outputGreenSum{0 .}, outputRedSum{0 .};
793816 for (const auto & [streetId, _] : this ->m_graph .adjMatrix ().getRow (nodeId, true )) {
794- auto const & pStreet{this ->m_graph .streetSet ()[ streetId] };
817+ auto const & pStreet{this ->m_graph .street ( streetId) };
795818 if (streetPriorities.contains (streetId)) {
796- outputGreenSum += m_streetTails[ streetId] / pStreet->nLanes ();
819+ outputGreenSum += m_streetTails. at ( streetId) / pStreet->nLanes ();
797820 } else {
798- outputRedSum += m_streetTails[ streetId] / pStreet->nLanes ();
821+ outputRedSum += m_streetTails. at ( streetId) / pStreet->nLanes ();
799822 }
800823 }
801824 auto const outputDifference{(outputGreenSum - outputRedSum) / nCycles};
0 commit comments