From bda6194a42652d0b0df37bcbd390f0af66f45c72 Mon Sep 17 00:00:00 2001 From: grufoony Date: Fri, 13 Dec 2024 11:30:42 +0100 Subject: [PATCH 1/7] Template on Agent and not on Delay in Dynamics --- src/dsm/headers/Dynamics.hpp | 151 +++++++++++++------------------ src/dsm/headers/RoadDynamics.hpp | 4 +- 2 files changed, 63 insertions(+), 92 deletions(-) diff --git a/src/dsm/headers/Dynamics.hpp b/src/dsm/headers/Dynamics.hpp index 2506d78c7..4d42b1871 100644 --- a/src/dsm/headers/Dynamics.hpp +++ b/src/dsm/headers/Dynamics.hpp @@ -22,7 +22,6 @@ #include #include -#include "Agent.hpp" #include "DijkstraWeights.hpp" #include "Itinerary.hpp" #include "Graph.hpp" @@ -63,12 +62,11 @@ namespace dsm { /// @brief The Dynamics class represents the dynamics of the network. /// @tparam Id, The type of the graph's id. It must be an unsigned integral type. /// @tparam Size, The type of the graph's capacity. It must be an unsigned integral type. - template - requires(is_numeric_v) + template class Dynamics { protected: std::unordered_map> m_itineraries; - std::map>> m_agents; + std::map> m_agents; Graph m_graph; Time m_time, m_previousSpireTime; std::mt19937_64 m_generator; @@ -151,10 +149,10 @@ namespace dsm { /// @brief Add an agent to the simulation /// @param agent The agent - void addAgent(const Agent& agent); + void addAgent(const agent_t& agent); /// @brief Add an agent to the simulation /// @param agent std::unique_ptr to the agent - void addAgent(std::unique_ptr> agent); + void addAgent(std::unique_ptr agent); /// @brief Add an agent with given source node and itinerary /// @param srcNodeId The id of the source node /// @param itineraryId The id of the itinerary @@ -181,7 +179,7 @@ namespace dsm { void addAgents(T1 agent, Tn... agents); /// @brief Add a set of agents to the simulation /// @param agents Generic container of agents, represented by an std::span - void addAgents(std::span> agents); + void addAgents(std::span agents); /// @brief Add a set of agents to the simulation /// @param nAgents The number of agents to add /// @param uniformly If true, the agents are added uniformly on the streets @@ -240,9 +238,7 @@ namespace dsm { } /// @brief Get the agents /// @return const std::unordered_map>&, The agents - const std::map>>& agents() const { - return m_agents; - } + const std::map>& agents() const { return m_agents; } /// @brief Get the time /// @return Time The time Time time() const { return m_time; } @@ -283,9 +279,8 @@ namespace dsm { Measurement meanTravelTime(bool clearData = false); }; - template - requires(is_numeric_v) - Dynamics::Dynamics(Graph& graph, std::optional seed) + template + Dynamics::Dynamics(Graph& graph, std::optional seed) : m_graph{std::move(graph)}, m_time{0}, m_previousSpireTime{0}, @@ -295,9 +290,8 @@ namespace dsm { } } - template - requires(is_numeric_v) - void Dynamics::updatePaths() { + template + void Dynamics::updatePaths() { std::vector threads; threads.reserve(m_itineraries.size()); std::exception_ptr pThreadException; @@ -319,9 +313,8 @@ namespace dsm { std::rethrow_exception(pThreadException); } - template - requires(is_numeric_v) - void Dynamics::setDestinationNodes(const std::span& destinationNodes, + template + void Dynamics::setDestinationNodes(const std::span& destinationNodes, bool updatePaths) { for (const auto& nodeId : destinationNodes) { if (!m_graph.nodeSet().contains(nodeId)) { @@ -335,9 +328,8 @@ namespace dsm { } } - template - requires(is_numeric_v) - void Dynamics::addAgent(const Agent& agent) { + template + void Dynamics::addAgent(const agent_t& agent) { if (m_agents.size() + 1 > m_graph.maxCapacity()) { throw std::overflow_error(buildLog( std::format("Graph is already holding the max possible number of agents ({})", @@ -347,11 +339,10 @@ namespace dsm { throw std::invalid_argument( buildLog(std::format("Agent with id {} already exists.", agent.id()))); } - m_agents.emplace(agent.id(), std::make_unique>(agent)); + m_agents.emplace(agent.id(), std::make_unique(agent)); } - template - requires(is_numeric_v) - void Dynamics::addAgent(std::unique_ptr> agent) { + template + void Dynamics::addAgent(std::unique_ptr agent) { if (m_agents.size() + 1 > m_graph.maxCapacity()) { throw std::overflow_error(buildLog( std::format("Graph is already holding the max possible number of agents ({})", @@ -363,9 +354,8 @@ namespace dsm { } m_agents.emplace(agent->id(), std::move(agent)); } - template - requires(is_numeric_v) - void Dynamics::addAgent(Id srcNodeId, Id itineraryId) { + template + void Dynamics::addAgent(Id srcNodeId, Id itineraryId) { if (m_agents.size() + 1 > m_graph.maxCapacity()) { throw std::overflow_error(buildLog( std::format("Graph is already holding the max possible number of agents ({})", @@ -383,11 +373,10 @@ namespace dsm { if (!m_agents.empty()) { agentId = m_agents.rbegin()->first + 1; } - this->addAgent(Agent{agentId, itineraryId, srcNodeId}); + this->addAgent(agent_t{agentId, itineraryId, srcNodeId}); } - template - requires(is_numeric_v) - void Dynamics::addAgents(Id itineraryId, + template + void Dynamics::addAgents(Id itineraryId, Size nAgents, std::optional srcNodeId) { if (m_agents.size() + nAgents > m_graph.maxCapacity()) { @@ -405,28 +394,25 @@ namespace dsm { agentId = m_agents.rbegin()->first + 1; } for (Size i{0}; i < nAgents; ++i, ++agentId) { - this->addAgent(Agent{agentId, itineraryId, srcNodeId}); + this->addAgent(agent_t{agentId, itineraryId, srcNodeId}); } } - template - requires(is_numeric_v) + template template requires(is_agent_v && ...) - void Dynamics::addAgents(Tn... agents) {} + void Dynamics::addAgents(Tn... agents) {} - template - requires(is_numeric_v) + template template requires(is_agent_v && (is_agent_v && ...)) - void Dynamics::addAgents(T1 agent, Tn... agents) { + void Dynamics::addAgents(T1 agent, Tn... agents) { addAgent(agent); addAgents(agents...); } - template - requires(is_numeric_v) - void Dynamics::addAgents(std::span> agents) { + template + void Dynamics::addAgents(std::span agents) { if (this->m_agents.size() + agents.size() > this->m_graph.maxCapacity()) { throw std::overflow_error(buildLog( std::format("Graph is already holding the max possible number of agents ({})", @@ -437,9 +423,8 @@ namespace dsm { }); } - template - requires(is_numeric_v) - void Dynamics::addAgentsUniformly(Size nAgents, + template + void Dynamics::addAgentsUniformly(Size nAgents, std::optional itineraryId) { if (m_agents.size() + nAgents > m_graph.maxCapacity()) { throw std::overflow_error(buildLog( @@ -477,7 +462,7 @@ namespace dsm { streetId = streetIt->first; } while (m_graph.streetSet()[streetId]->isFull()); const auto& street{m_graph.streetSet()[streetId]}; - Agent agent{agentId, itineraryId.value(), street->nodePair().first}; + agent_t agent{agentId, itineraryId.value(), street->nodePair().first}; agent.setStreetId(streetId); this->addAgent(agent); this->setAgentSpeed(agentId); @@ -488,12 +473,11 @@ namespace dsm { } } - template - requires(is_numeric_v) + template template requires(std::is_same_v> || std::is_same_v>) - void Dynamics::addAgentsRandomly(Size nAgents, + void Dynamics::addAgentsRandomly(Size nAgents, const TContainer& src_weights, const TContainer& dst_weights) { if (src_weights.size() == 1 && dst_weights.size() == 1 && @@ -572,58 +556,50 @@ namespace dsm { } } - template - requires(is_numeric_v) - void Dynamics::removeAgent(Size agentId) { + template + void Dynamics::removeAgent(Size agentId) { m_agents.erase(agentId); } - template - requires(is_numeric_v) + template + template requires(std::is_convertible_v && (std::is_convertible_v && ...)) - void Dynamics::removeAgents(T1 id, Tn... ids) { + void Dynamics::removeAgents(T1 id, Tn... ids) { removeAgent(id); removeAgents(ids...); } - template - requires(is_numeric_v) - void Dynamics::addItinerary(const Itinerary& itinerary) { + template + void Dynamics::addItinerary(const Itinerary& itinerary) { m_itineraries.emplace(itinerary.id(), std::make_unique(itinerary)); } - template - requires(is_numeric_v) - void Dynamics::addItinerary(std::unique_ptr itinerary) { + template + void Dynamics::addItinerary(std::unique_ptr itinerary) { m_itineraries.emplace(itinerary->id(), std::move(itinerary)); } - template - requires(is_numeric_v) + template template requires(is_itinerary_v && ...) - void Dynamics::addItineraries(Tn... itineraries) { + void Dynamics::addItineraries(Tn... itineraries) { (this->addItinerary(itineraries), ...); } - - template - requires(is_numeric_v) - void Dynamics::addItineraries(std::span itineraries) { + template + void Dynamics::addItineraries(std::span itineraries) { std::ranges::for_each(itineraries, [this](const auto& itinerary) -> void { m_itineraries.insert(std::make_unique(itinerary)); }); } - template - requires(is_numeric_v) - void Dynamics::resetTime() { + template + void Dynamics::resetTime() { m_time = 0; } - template - requires(is_numeric_v) - Measurement Dynamics::agentMeanSpeed() const { + template + Measurement Dynamics::agentMeanSpeed() const { std::vector speeds; if (!m_agents.empty()) { speeds.reserve(m_agents.size()); @@ -634,9 +610,8 @@ namespace dsm { return Measurement(speeds); } - template - requires(is_numeric_v) - Measurement Dynamics::streetMeanDensity(bool normalized) const { + template + Measurement Dynamics::streetMeanDensity(bool normalized) const { if (m_graph.streetSet().size() == 0) { return Measurement(0., 0.); } @@ -648,9 +623,8 @@ namespace dsm { return Measurement(densities); } - template - requires(is_numeric_v) - Measurement Dynamics::streetMeanFlow() const { + template + Measurement Dynamics::streetMeanFlow() const { std::vector flows; flows.reserve(m_graph.streetSet().size()); for (const auto& [streetId, street] : m_graph.streetSet()) { @@ -659,9 +633,8 @@ namespace dsm { return Measurement(flows); } - template - requires(is_numeric_v) - Measurement Dynamics::streetMeanFlow(double threshold, + template + Measurement Dynamics::streetMeanFlow(double threshold, bool above) const { std::vector flows; flows.reserve(m_graph.streetSet().size()); @@ -675,9 +648,8 @@ namespace dsm { return Measurement(flows); } - template - requires(is_numeric_v) - Measurement Dynamics::meanSpireInputFlow(bool resetValue) { + template + Measurement Dynamics::meanSpireInputFlow(bool resetValue) { auto deltaTime{m_time - m_previousSpireTime}; if (deltaTime == 0) { return Measurement(0., 0.); @@ -694,9 +666,8 @@ namespace dsm { return Measurement(flows); } - template - requires(is_numeric_v) - Measurement Dynamics::meanSpireOutputFlow(bool resetValue) { + template + Measurement Dynamics::meanSpireOutputFlow(bool resetValue) { auto deltaTime{m_time - m_previousSpireTime}; if (deltaTime == 0) { return Measurement(0., 0.); diff --git a/src/dsm/headers/RoadDynamics.hpp b/src/dsm/headers/RoadDynamics.hpp index e47ebe4b5..3c0568d9e 100644 --- a/src/dsm/headers/RoadDynamics.hpp +++ b/src/dsm/headers/RoadDynamics.hpp @@ -39,7 +39,7 @@ namespace dsm { /// @tparam Size, The type of the graph's capacity. It must be an unsigned integral type. template requires(is_numeric_v) - class RoadDynamics : public Dynamics { + class RoadDynamics : public Dynamics> { protected: Time m_previousOptimizationTime; double m_errorProbability; @@ -152,7 +152,7 @@ namespace dsm { template requires(is_numeric_v) RoadDynamics::RoadDynamics(Graph& graph, std::optional seed) - : Dynamics(graph, seed), + : Dynamics>(graph, seed), m_previousOptimizationTime{0}, m_errorProbability{0.}, m_minSpeedRateo{0.}, From 9c129a15eaa63dd7a59a447f2f91ec402ad6adcb Mon Sep 17 00:00:00 2001 From: grufoony Date: Fri, 13 Dec 2024 11:44:19 +0100 Subject: [PATCH 2/7] Enhance template use in Dynamics classes --- benchmark/Dynamics/BenchDynamics.cpp | 2 +- examples/slow_charge_rb.cpp | 2 +- examples/slow_charge_tl.cpp | 2 +- examples/stalingrado.cpp | 2 +- profiling/main.cpp | 2 +- src/dsm/dsm.hpp | 2 +- src/dsm/headers/FirstOrderDynamics.cpp | 105 ++++++++++++++++++++++ src/dsm/headers/FirstOrderDynamics.hpp | 116 +------------------------ test/Test_dynamics.cpp | 2 +- 9 files changed, 114 insertions(+), 121 deletions(-) create mode 100644 src/dsm/headers/FirstOrderDynamics.cpp diff --git a/benchmark/Dynamics/BenchDynamics.cpp b/benchmark/Dynamics/BenchDynamics.cpp index 79136a329..378dc64c5 100644 --- a/benchmark/Dynamics/BenchDynamics.cpp +++ b/benchmark/Dynamics/BenchDynamics.cpp @@ -7,7 +7,7 @@ using Graph = dsm::Graph; using Itinerary = dsm::Itinerary; -using Dynamics = dsm::FirstOrderDynamics; +using Dynamics = dsm::FirstOrderDynamics; using Bench = sb::Bench; diff --git a/examples/slow_charge_rb.cpp b/examples/slow_charge_rb.cpp index f537c8415..ce13ff7dd 100644 --- a/examples/slow_charge_rb.cpp +++ b/examples/slow_charge_rb.cpp @@ -30,7 +30,7 @@ using Unit = unsigned int; using Delay = uint8_t; using Graph = dsm::Graph; -using Dynamics = dsm::FirstOrderDynamics; +using Dynamics = dsm::FirstOrderDynamics; using Street = dsm::Street; using SpireStreet = dsm::SpireStreet; using Roundabout = dsm::Roundabout; diff --git a/examples/slow_charge_tl.cpp b/examples/slow_charge_tl.cpp index 499bc074a..a93b21f6f 100644 --- a/examples/slow_charge_tl.cpp +++ b/examples/slow_charge_tl.cpp @@ -31,7 +31,7 @@ using Unit = unsigned int; using Delay = uint8_t; using Graph = dsm::Graph; -using Dynamics = dsm::FirstOrderDynamics; +using Dynamics = dsm::FirstOrderDynamics; using Street = dsm::Street; using SpireStreet = dsm::SpireStreet; using TrafficLight = dsm::TrafficLight; diff --git a/examples/stalingrado.cpp b/examples/stalingrado.cpp index 8b7db815a..551ffa6b2 100644 --- a/examples/stalingrado.cpp +++ b/examples/stalingrado.cpp @@ -21,7 +21,7 @@ using Delay = uint8_t; using Graph = dsm::Graph; using Itinerary = dsm::Itinerary; -using Dynamics = dsm::FirstOrderDynamics; +using Dynamics = dsm::FirstOrderDynamics; using Street = dsm::Street; using SpireStreet = dsm::SpireStreet; using TrafficLight = dsm::TrafficLight; diff --git a/profiling/main.cpp b/profiling/main.cpp index 268a0b210..c5e72f8dd 100644 --- a/profiling/main.cpp +++ b/profiling/main.cpp @@ -10,7 +10,7 @@ using unit = uint32_t; using Graph = dsm::Graph; using Itinerary = dsm::Itinerary; -using Dynamics = dsm::FirstOrderDynamics; +using Dynamics = dsm::FirstOrderDynamics; int main() { Graph graph{}; diff --git a/src/dsm/dsm.hpp b/src/dsm/dsm.hpp index 4c71f828c..d3cfb1158 100644 --- a/src/dsm/dsm.hpp +++ b/src/dsm/dsm.hpp @@ -6,7 +6,7 @@ static constexpr uint8_t DSM_VERSION_MAJOR = 2; static constexpr uint8_t DSM_VERSION_MINOR = 2; -static constexpr uint8_t DSM_VERSION_PATCH = 4; +static constexpr uint8_t DSM_VERSION_PATCH = 5; static auto const DSM_VERSION = std::format("{}.{}.{}", DSM_VERSION_MAJOR, DSM_VERSION_MINOR, DSM_VERSION_PATCH); diff --git a/src/dsm/headers/FirstOrderDynamics.cpp b/src/dsm/headers/FirstOrderDynamics.cpp new file mode 100644 index 000000000..fe6ad6648 --- /dev/null +++ b/src/dsm/headers/FirstOrderDynamics.cpp @@ -0,0 +1,105 @@ +#include "FirstOrderDynamics.hpp" + +namespace dsm { + FirstOrderDynamics::FirstOrderDynamics(Graph& graph, std::optional seed) + : RoadDynamics(graph, seed), m_speedFluctuationSTD{0.} {}; + + void FirstOrderDynamics::setAgentSpeed(Size agentId) { + const auto& agent{this->m_agents[agentId]}; + const auto& street{this->m_graph.streetSet()[agent->streetId().value()]}; + double speed{street->maxSpeed() * + (1. - this->m_minSpeedRateo * street->density(true))}; + if (m_speedFluctuationSTD > 0.) { + std::normal_distribution speedDist{speed, speed * m_speedFluctuationSTD}; + speed = speedDist(this->m_generator); + } + speed < 0. ? agent->setSpeed(street->maxSpeed() * (1. - this->m_minSpeedRateo)) + : agent->setSpeed(speed); + } + + void FirstOrderDynamics::setSpeedFluctuationSTD(double speedFluctuationSTD) { + if (speedFluctuationSTD < 0.) { + throw std::invalid_argument( + buildLog("The speed fluctuation standard deviation must be positive.")); + } + m_speedFluctuationSTD = speedFluctuationSTD; + } + + double FirstOrderDynamics::streetMeanSpeed(Id streetId) const { + const auto& street{this->m_graph.streetSet().at(streetId)}; + if (street->nAgents() == 0) { + return street->maxSpeed(); + } + double meanSpeed{0.}; + Size n{0}; + if (street->nExitingAgents() == 0) { + n = static_cast(street->waitingAgents().size()); + double alpha{this->m_minSpeedRateo / street->capacity()}; + meanSpeed = street->maxSpeed() * n * (1. - 0.5 * alpha * (n - 1.)); + } else { + for (const auto& agentId : street->waitingAgents()) { + meanSpeed += this->m_agents.at(agentId)->speed(); + ++n; + } + for (auto const& queue : street->exitQueues()) { + for (const auto& agentId : queue) { + meanSpeed += this->m_agents.at(agentId)->speed(); + ++n; + } + } + } + const auto& node = this->m_graph.nodeSet().at(street->nodePair().second); + if (node->isIntersection()) { + auto& intersection = dynamic_cast(*node); + for (const auto& [angle, agentId] : intersection.agents()) { + const auto& agent{this->m_agents.at(agentId)}; + if (agent->streetId().has_value() && agent->streetId().value() == streetId) { + meanSpeed += agent->speed(); + ++n; + } + } + } else if (node->isRoundabout()) { + auto& roundabout = dynamic_cast(*node); + for (const auto& agentId : roundabout.agents()) { + const auto& agent{this->m_agents.at(agentId)}; + if (agent->streetId().has_value() && agent->streetId().value() == streetId) { + meanSpeed += agent->speed(); + ++n; + } + } + } + return meanSpeed / n; + } + + Measurement FirstOrderDynamics::streetMeanSpeed() const { + if (this->m_agents.size() == 0) { + return Measurement(0., 0.); + } + std::vector speeds; + speeds.reserve(this->m_graph.streetSet().size()); + for (const auto& [streetId, street] : this->m_graph.streetSet()) { + speeds.push_back(this->streetMeanSpeed(streetId)); + } + return Measurement(speeds); + } + Measurement FirstOrderDynamics::streetMeanSpeed(double threshold, + bool above) const { + if (this->m_agents.size() == 0) { + return Measurement(0., 0.); + } + std::vector speeds; + speeds.reserve(this->m_graph.streetSet().size()); + for (const auto& [streetId, street] : this->m_graph.streetSet()) { + if (above) { + if (street->density(true) > threshold) { + speeds.push_back(this->streetMeanSpeed(streetId)); + } + } else { + if (street->density(true) < threshold) { + speeds.push_back(this->streetMeanSpeed(streetId)); + } + } + } + return Measurement(speeds); + } +} // namespace dsm \ No newline at end of file diff --git a/src/dsm/headers/FirstOrderDynamics.hpp b/src/dsm/headers/FirstOrderDynamics.hpp index 2064d20a3..fc856aff7 100644 --- a/src/dsm/headers/FirstOrderDynamics.hpp +++ b/src/dsm/headers/FirstOrderDynamics.hpp @@ -3,16 +3,13 @@ #include "RoadDynamics.hpp" namespace dsm { - template - requires(std::unsigned_integral) - class FirstOrderDynamics : public RoadDynamics { + class FirstOrderDynamics : public RoadDynamics { double m_speedFluctuationSTD; public: /// @brief Construct a new First Order Dynamics object /// @param graph, The graph representing the network - FirstOrderDynamics(Graph& graph, std::optional seed = std::nullopt) - : RoadDynamics(graph, seed), m_speedFluctuationSTD{0.} {}; + FirstOrderDynamics(Graph& graph, std::optional seed = std::nullopt); /// @brief Set the speed of an agent /// @param agentId The id of the agent /// @throw std::invalid_argument, If the agent is not found @@ -37,113 +34,4 @@ namespace dsm { /// @return Measurement The mean speed of the agents and the standard deviation Measurement streetMeanSpeed(double threshold, bool above) const override; }; - - template - requires(std::unsigned_integral) - void FirstOrderDynamics::setAgentSpeed(Size agentId) { - const auto& agent{this->m_agents[agentId]}; - const auto& street{this->m_graph.streetSet()[agent->streetId().value()]}; - double speed{street->maxSpeed() * - (1. - this->m_minSpeedRateo * street->density(true))}; - if (m_speedFluctuationSTD > 0.) { - std::normal_distribution speedDist{speed, speed * m_speedFluctuationSTD}; - speed = speedDist(this->m_generator); - } - speed < 0. ? agent->setSpeed(street->maxSpeed() * (1. - this->m_minSpeedRateo)) - : agent->setSpeed(speed); - } - - template - requires(std::unsigned_integral) - void FirstOrderDynamics::setSpeedFluctuationSTD(double speedFluctuationSTD) { - if (speedFluctuationSTD < 0.) { - throw std::invalid_argument( - buildLog("The speed fluctuation standard deviation must be positive.")); - } - m_speedFluctuationSTD = speedFluctuationSTD; - } - - template - requires(std::unsigned_integral) - double FirstOrderDynamics::streetMeanSpeed(Id streetId) const { - const auto& street{this->m_graph.streetSet().at(streetId)}; - if (street->nAgents() == 0) { - return street->maxSpeed(); - } - double meanSpeed{0.}; - Size n{0}; - if (street->nExitingAgents() == 0) { - n = static_cast(street->waitingAgents().size()); - double alpha{this->m_minSpeedRateo / street->capacity()}; - meanSpeed = street->maxSpeed() * n * (1. - 0.5 * alpha * (n - 1.)); - } else { - for (const auto& agentId : street->waitingAgents()) { - meanSpeed += this->m_agents.at(agentId)->speed(); - ++n; - } - for (auto const& queue : street->exitQueues()) { - for (const auto& agentId : queue) { - meanSpeed += this->m_agents.at(agentId)->speed(); - ++n; - } - } - } - const auto& node = this->m_graph.nodeSet().at(street->nodePair().second); - if (node->isIntersection()) { - auto& intersection = dynamic_cast(*node); - for (const auto& [angle, agentId] : intersection.agents()) { - const auto& agent{this->m_agents.at(agentId)}; - if (agent->streetId().has_value() && agent->streetId().value() == streetId) { - meanSpeed += agent->speed(); - ++n; - } - } - } else if (node->isRoundabout()) { - auto& roundabout = dynamic_cast(*node); - for (const auto& agentId : roundabout.agents()) { - const auto& agent{this->m_agents.at(agentId)}; - if (agent->streetId().has_value() && agent->streetId().value() == streetId) { - meanSpeed += agent->speed(); - ++n; - } - } - } - return meanSpeed / n; - } - - template - requires(std::unsigned_integral) - Measurement FirstOrderDynamics::streetMeanSpeed() const { - if (this->m_agents.size() == 0) { - return Measurement(0., 0.); - } - std::vector speeds; - speeds.reserve(this->m_graph.streetSet().size()); - for (const auto& [streetId, street] : this->m_graph.streetSet()) { - speeds.push_back(this->streetMeanSpeed(streetId)); - } - return Measurement(speeds); - } - template - requires(std::unsigned_integral) - Measurement FirstOrderDynamics::streetMeanSpeed(double threshold, - bool above) const { - if (this->m_agents.size() == 0) { - return Measurement(0., 0.); - } - std::vector speeds; - speeds.reserve(this->m_graph.streetSet().size()); - for (const auto& [streetId, street] : this->m_graph.streetSet()) { - if (above) { - if (street->density(true) > threshold) { - speeds.push_back(this->streetMeanSpeed(streetId)); - } - } else { - if (street->density(true) < threshold) { - speeds.push_back(this->streetMeanSpeed(streetId)); - } - } - } - return Measurement(speeds); - } } // namespace dsm \ No newline at end of file diff --git a/test/Test_dynamics.cpp b/test/Test_dynamics.cpp index cc38aea6f..687b12253 100644 --- a/test/Test_dynamics.cpp +++ b/test/Test_dynamics.cpp @@ -7,7 +7,7 @@ #include "doctest.h" -using Dynamics = dsm::FirstOrderDynamics; +using Dynamics = dsm::FirstOrderDynamics; using Graph = dsm::Graph; using SparseMatrix = dsm::SparseMatrix; using Street = dsm::Street; From 77ccf73009e5af996f0acf799976821a61af65c7 Mon Sep 17 00:00:00 2001 From: grufoony Date: Fri, 13 Dec 2024 11:51:22 +0100 Subject: [PATCH 3/7] Fix warning --- src/dsm/headers/FirstOrderDynamics.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dsm/headers/FirstOrderDynamics.hpp b/src/dsm/headers/FirstOrderDynamics.hpp index fc856aff7..14516f120 100644 --- a/src/dsm/headers/FirstOrderDynamics.hpp +++ b/src/dsm/headers/FirstOrderDynamics.hpp @@ -9,7 +9,8 @@ namespace dsm { public: /// @brief Construct a new First Order Dynamics object /// @param graph, The graph representing the network - FirstOrderDynamics(Graph& graph, std::optional seed = std::nullopt); + explicit FirstOrderDynamics(Graph& graph, + std::optional seed = std::nullopt); /// @brief Set the speed of an agent /// @param agentId The id of the agent /// @throw std::invalid_argument, If the agent is not found From 0c8684c5a526e72a2fdc5d27264131f58c84b182 Mon Sep 17 00:00:00 2001 From: grufoony Date: Fri, 13 Dec 2024 14:37:24 +0100 Subject: [PATCH 4/7] Fix --- benchmark/Dynamics/BenchDynamics.cpp | 2 -- profiling/main.cpp | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/benchmark/Dynamics/BenchDynamics.cpp b/benchmark/Dynamics/BenchDynamics.cpp index 378dc64c5..3689fad0a 100644 --- a/benchmark/Dynamics/BenchDynamics.cpp +++ b/benchmark/Dynamics/BenchDynamics.cpp @@ -28,8 +28,6 @@ int main() { dynamics.addItinerary(it2); dynamics.addItinerary(it3); dynamics.addItinerary(it4); - dynamics.setErrorProbability(0.3); - dynamics.setMinSpeedRateo(0.95); const int n_rep{100}; Bench b1(n_rep); diff --git a/profiling/main.cpp b/profiling/main.cpp index c5e72f8dd..ef91cceba 100644 --- a/profiling/main.cpp +++ b/profiling/main.cpp @@ -36,13 +36,12 @@ int main() { std::cout << "Creating dynamics...\n"; - Dynamics dynamics{graph}; + Dynamics dynamics{graph, std::nullopt, 0.95}; dynamics.addItinerary(it1); dynamics.addItinerary(it2); dynamics.addItinerary(it3); dynamics.addItinerary(it4); dynamics.setErrorProbability(0.3); - dynamics.setMinSpeedRateo(0.95); dynamics.updatePaths(); std::cout << "Done.\n" From cdeb0f9b2c55fee8417043147fca973dc8893926 Mon Sep 17 00:00:00 2001 From: grufoony Date: Fri, 13 Dec 2024 15:59:13 +0100 Subject: [PATCH 5/7] Reworked examples --- examples/Makefile | 4 ++-- examples/slow_charge_rb.cpp | 6 +++--- examples/slow_charge_tl.cpp | 13 +++++++------ utils/plotter.py | 10 +++++++--- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/examples/Makefile b/examples/Makefile index c13c5ed59..5f21810f6 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,6 +1,6 @@ slow_charge_tl: - ./slow_charge_tl.out 69 0.3 ./sctl 0 + ./slow_charge_tl.out 69 0.3 ./sctl 0 450 slow_charge_rb: - ./slow_charge_rb.out 69 0.3 ./scrb/ + ./slow_charge_rb.out 69 0.3 ./scrb/ 450 stalingrado: ./stalingrado.out \ No newline at end of file diff --git a/examples/slow_charge_rb.cpp b/examples/slow_charge_rb.cpp index a5fdf7bdc..aa067aa9b 100644 --- a/examples/slow_charge_rb.cpp +++ b/examples/slow_charge_rb.cpp @@ -18,7 +18,6 @@ namespace fs = std::filesystem; std::atomic progress{0}; std::atomic bExitFlag{false}; -uint nAgents{450}; // uncomment these lines to print densities, flows and speeds #define PRINT_DENSITIES @@ -42,15 +41,16 @@ void printLoadingBar(int const i, int const n) { } int main(int argc, char** argv) { - if (argc != 4) { + if (argc != 5) { std::cerr << "Usage: " << argv[0] - << " \n"; + << " \n"; return 1; } const int SEED = std::stoi(argv[1]); // seed for random number generator const double ERROR_PROBABILITY{std::stod(argv[2])}; const std::string BASE_OUT_FOLDER{argv[3]}; + auto nAgents{std::stoul(argv[4])}; std::cout << "-------------------------------------------------\n"; std::cout << "Input parameters:\n"; diff --git a/examples/slow_charge_tl.cpp b/examples/slow_charge_tl.cpp index a6b49b69e..8240a5cfe 100644 --- a/examples/slow_charge_tl.cpp +++ b/examples/slow_charge_tl.cpp @@ -18,7 +18,6 @@ namespace fs = std::filesystem; std::atomic progress{0}; std::atomic bExitFlag{false}; -uint nAgents{315}; // 315 for error probability 0.3, 450 for error probability 0.05 // uncomment these lines to print densities, flows and speeds #define PRINT_DENSITIES @@ -43,9 +42,10 @@ void printLoadingBar(int const i, int const n) { } int main(int argc, char** argv) { - if (argc != 5) { - std::cerr << "Usage: " << argv[0] - << " \n"; + if (argc != 6) { + std::cerr + << "Usage: " << argv[0] + << " \n"; return 1; } @@ -54,6 +54,7 @@ int main(int argc, char** argv) { std::string BASE_OUT_FOLDER{argv[3]}; const bool OPTIMIZE{std::string(argv[4]) != std::string("0")}; BASE_OUT_FOLDER += OPTIMIZE ? "_op/" : "/"; + auto nAgents{std::stoul(argv[5])}; const std::string IN_MATRIX{"./data/matrix.dat"}; // input matrix file const std::string IN_COORDS{"./data/coordinates.dsm"}; // input coords file @@ -68,6 +69,7 @@ int main(int argc, char** argv) { std::cout << "Seed: " << SEED << '\n'; std::cout << "Error probability: " << ERROR_PROBABILITY << '\n'; std::cout << "Base output folder: " << BASE_OUT_FOLDER << '\n'; + std::cout << "Initial number of agents: " << nAgents << '\n'; if (OPTIMIZE) { std::cout << "Traffic light optimization ENABLED.\n"; } @@ -89,12 +91,11 @@ int main(int argc, char** argv) { graph.importCoordinates(IN_COORDS); std::cout << "Setting street parameters..." << '\n'; for (const auto& [streetId, street] : graph.streetSet()) { - street->setLength(2e3); - street->setCapacity(225); street->setTransportCapacity(1); street->setMaxSpeed(13.9); } graph.buildAdj(); + graph.normalizeStreetCapacities(); const auto dv = graph.adjMatrix().getDegreeVector(); // graph.addStreet(Street(100002, std::make_pair(0, 108))); diff --git a/utils/plotter.py b/utils/plotter.py index 4c55147df..1138b9cab 100644 --- a/utils/plotter.py +++ b/utils/plotter.py @@ -57,7 +57,7 @@ import networkx as nx from tqdm import tqdm -PRESENTATION = True +PRESENTATION = False class RealTimePeakDetection: @@ -267,17 +267,21 @@ def adjust_dataframe(_df): df_den_array.append(temp) # make an unique dataframe as mean of all the dataframes + DF = None if len(df_array) > 0: DF = pd.concat(df_array) DF = DF.groupby(DF.index).mean() else: - DF = None + print("No data found") + exit() + DF_DEN = None if len(df_den_array) > 0: DF_DEN = pd.concat(df_den_array) DF_DEN = DF_DEN.groupby(DF_DEN.index).mean() else: - DF_DEN = None + print("No density data found") + exit() ############################################ # Load densities From 3190db9b15b28baeb1cb18e2c5d65ebb8e600fc8 Mon Sep 17 00:00:00 2001 From: grufoony Date: Fri, 13 Dec 2024 16:02:08 +0100 Subject: [PATCH 6/7] Fix pylint --- utils/plotter.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/utils/plotter.py b/utils/plotter.py index 1138b9cab..160eaf418 100644 --- a/utils/plotter.py +++ b/utils/plotter.py @@ -49,6 +49,7 @@ """ import os +import sys from argparse import ArgumentParser import pandas as pd import seaborn as sns @@ -273,7 +274,7 @@ def adjust_dataframe(_df): DF = DF.groupby(DF.index).mean() else: print("No data found") - exit() + sys.exit() DF_DEN = None if len(df_den_array) > 0: @@ -281,7 +282,7 @@ def adjust_dataframe(_df): DF_DEN = DF_DEN.groupby(DF_DEN.index).mean() else: print("No density data found") - exit() + sys.exit() ############################################ # Load densities From c28210376938f8adad27c586e8118d48dcf7112e Mon Sep 17 00:00:00 2001 From: grufoony Date: Fri, 13 Dec 2024 17:50:48 +0100 Subject: [PATCH 7/7] Update rb script --- examples/Makefile | 2 +- examples/slow_charge_rb.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/Makefile b/examples/Makefile index 5f21810f6..97c887e3e 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,6 +1,6 @@ slow_charge_tl: ./slow_charge_tl.out 69 0.3 ./sctl 0 450 slow_charge_rb: - ./slow_charge_rb.out 69 0.3 ./scrb/ 450 + ./slow_charge_rb.out 69 0.3 ./scrb/ 900 stalingrado: ./stalingrado.out \ No newline at end of file diff --git a/examples/slow_charge_rb.cpp b/examples/slow_charge_rb.cpp index aa067aa9b..f51b0f0ed 100644 --- a/examples/slow_charge_rb.cpp +++ b/examples/slow_charge_rb.cpp @@ -57,6 +57,7 @@ int main(int argc, char** argv) { std::cout << "Seed: " << SEED << '\n'; std::cout << "Error probability: " << ERROR_PROBABILITY << '\n'; std::cout << "Base output folder: " << BASE_OUT_FOLDER << '\n'; + std::cout << "Initial number of agents: " << nAgents << '\n'; std::cout << "-------------------------------------------------\n"; const std::string IN_MATRIX{"./data/matrix.dat"}; // input matrix file @@ -83,12 +84,11 @@ int main(int argc, char** argv) { graph.importCoordinates(IN_COORDS); std::cout << "Setting street parameters..." << '\n'; for (const auto& [streetId, street] : graph.streetSet()) { - street->setLength(2e3); - street->setCapacity(225); street->setTransportCapacity(1); street->setMaxSpeed(13.9); } graph.buildAdj(); + graph.normalizeStreetCapacities(); std::cout << "Number of nodes: " << graph.nNodes() << '\n'; std::cout << "Number of streets: " << graph.nEdges() << '\n';