|
Dynamical System Framework
|
The FirstOrderDynamics class represents the dynamics of the network. More...
#include <FirstOrderDynamics.hpp>
Public Member Functions | |
| FirstOrderDynamics (RoadNetwork &&graph, bool useCache=false, std::optional< unsigned int > seed=std::nullopt) | |
| Construct a new FirstOrderDynamics object. | |
| void | prepareNetwork (bool const bAdjustNodeCapacities=true, bool const bAutoMapStreetLanes=false, bool const bAutoAssignRoadPriorities=true, bool const bAutoInitTrafficLights=true) |
| Automatically prepare the network for the simulation. This method calls the following methods in order: | |
| void | setErrorProbability (double errorProbability) |
| Set the error probability. | |
| void | setPassageProbability (double passageProbability) |
| Set the passage probability. | |
| void | killStagnantAgents (double timeToleranceFactor=3.) |
| Set the time tolerance factor for killing stagnant agents. An agent will be considered stagnant if it has not moved for timeToleranceFactor * std::ceil(street_length / street_maxSpeed) time units. | |
| void | saveData (std::time_t const savingInterval, bool const saveAverageStats=false, bool const saveStreetData=false, bool const saveTravelData=false, bool const saveAgentData=false) |
| Enable data saving (compatibility wrapper; persistence is handled by TrafficSimulator). | |
| template<typename... TArgs> | |
| void | setSpeedFunction (SpeedFunction const speedFunction, TArgs &&... args) |
| Set the speed function. Options are: | |
| void | setForcePriorities (bool const forcePriorities) noexcept |
| Set the force priorities flag. | |
| void | setUpdatePathsThrowOnEmpty (bool const throwOnEmpty) noexcept |
| Set the update paths throw on empty flag. | |
| void | setDataUpdatePeriod (Delay const dataUpdatePeriod) noexcept |
| Set the data update period. | |
| void | setMeanTravelDistance (double const meanTravelDistance) |
| Set the mean distance travelled by a random agent. The distance will be sampled from an exponential distribution with this mean. | |
| void | setMeanTravelTime (std::time_t const meanTravelTime) noexcept |
| Set the mean travel time for random agents. The travel time will be sampled from an exponential distribution with this mean. | |
| void | setUTurnPenaltyFactor (double uturnPenaltyFactor) |
| Set the penalty factor applied to U-turns when choosing the next street. | |
| void | setReinsertAgents (bool const reinsertAgents) noexcept |
| void | setIntelligentAgentsFraction (double const intelligentFraction) |
| Set the fraction of intelligent agents. | |
| void | setOrigins (std::unordered_map< Id, double > const &origins={}) |
| Set the origins. | |
| void | setDestinations (std::unordered_map< Id, double > const &destinations) |
| Set the destinations. | |
| void | setDestinations (std::initializer_list< Id > destinations) |
| Set the destinations. | |
| void | setODs (std::vector< std::tuple< Id, Id, double > > const &ODs) |
| Set the origin-destination pairs with their associated weights. | |
| void | setConditionalODs (std::unordered_map< Id, std::tuple< double, std::vector< std::tuple< Id, double > > > > const &originToDestinations) |
| Set the origin-destination pairs with their associated weights from a map of origin nodes to vectors of destination nodes and weights. | |
| template<typename TContainer> requires (std::is_convertible_v<typename TContainer::value_type, Id>) | |
| void | setDestinations (TContainer const &destinationNodes) |
| Set the destinations. | |
| void | importODsFromCSV (std::string_view const fileName, char const separator=';', bool const bEdges=true) |
| Import origin-destination pairs from a CSV file. Possibilities are: | |
| void | setTransitionMatrix (std::unordered_map< Id, std::unordered_map< Id, double > > const &transitionMatrix) |
| Set the transition matrix used to route random agents. | |
| void | importTransitionMatrixFromJSON (std::string_view const fileName) |
| Import the transition matrix used to route random agents from a JSON file. | |
| void | initTurnCounts () |
| Initialize the turn counts map. | |
| void | resetTurnCounts () |
| Reset the turn counts map values to zero. | |
| void | updatePaths () |
| Update the paths of the itineraries based on the given weight function. | |
| void | addAgentsUniformly (std::size_t nAgents, std::optional< Id > itineraryId=std::nullopt) |
| Add agents uniformly on the road network. | |
| void | addAgent (std::unique_ptr< Agent > agent) |
| Add an agent to the simulation. | |
| void | addAgent (std::vector< std::shared_ptr< Itinerary > > const &trip, std::optional< Id > optSrcStreetId=std::nullopt) |
| Add an agent to the simulation. | |
| void | addAgent (std::shared_ptr< Itinerary > pItinerary=nullptr, std::optional< Id > optSrcStreetId=std::nullopt) |
| Add an agent to the simulation. | |
| void | addAgents (std::size_t const nAgents, AgentInsertionMethod const mode) |
| Add agents to the simulation. | |
| template<typename... TArgs> requires (std::is_constructible_v<Itinerary, TArgs...>) | |
| void | addItinerary (TArgs &&... args) |
| Add an itinerary. | |
| void | addItinerary (std::shared_ptr< Itinerary > itinerary) |
| Add an itinerary. | |
| StepDataResult | evolve (StepDataRequest const &dataRequest={}) |
| Evolve the simulation. | |
| void | optimizeTrafficLights (TrafficLightOptimization optimizationType=TrafficLightOptimization::DOUBLE_TAIL, const std::string &logFile=std::string(), double const percentage=0.3, double const threshold=1.3) |
| Optimize the traffic lights by changing the green and red times. | |
| auto const & | freeflowItineraries () const noexcept |
| Get the free-flow itineraries. | |
| auto | intelligentAgentsFraction () const noexcept |
| Get the fraction of intelligent agents, i.e. following the updated paths. | |
| auto const & | itineraries () const noexcept |
| Get the itineraries. | |
| auto const & | origins () const noexcept |
| Get the origin nodes of the graph. | |
| auto & | origins () noexcept |
| Get the origin nodes of the graph. | |
| auto const & | destinations () const noexcept |
| Get the destination nodes of the graph. | |
| auto & | destinations () noexcept |
| Get the destination nodes of the graph. | |
| auto const & | transitionMatrix () const noexcept |
| Get the transition matrix used to route random agents. | |
| const std::vector< std::unique_ptr< Agent > > & | agents () const noexcept |
| Get the agents. | |
| auto | nAgents () const |
| Get the number of agents currently in the simulation. | |
| auto | ghostAgents () const |
| Get the number of ghost agents waiting to be inserted. | |
| Measurement< double > | meanTravelTime (bool clearData=false) |
| Get the mean travel time of the agents in \(s\). | |
| Measurement< double > | meanTravelDistance (bool clearData=false) |
| Get the mean travel distance of the agents in \(m\). | |
| Measurement< double > | meanTravelSpeed (bool clearData=false) |
| Get the mean travel speed of the agents in \(m/s\). | |
| TurnCountsDict const & | turnCounts () const noexcept |
| Get the turn counts of the agents. | |
| std::unordered_map< Id, std::unordered_map< Id, double > > const | normalizedTurnCounts () const noexcept |
| Get the normalized turn counts of the agents. | |
| tbb::concurrent_unordered_map< Id, std::size_t > | originCounts (bool const bReset=true) noexcept |
| Get the origin counts of the agents. | |
| tbb::concurrent_unordered_map< Id, std::size_t > | destinationCounts (bool const bReset=true) noexcept |
| Get the destination counts of the agents. | |
| template<bool Normalized> | |
| Measurement< double > | streetMeanDensity () const |
| Get the mean density of the streets in \(m^{-1}\) or \(a.u.\) if Normalized. | |
| Measurement< double > | streetMeanFlow () const |
| Get the mean flow of the streets in \(s^{-1}\). | |
| Measurement< double > | streetMeanFlow (double threshold, bool above) const |
| Get the mean flow of the streets in \(s^{-1}\). | |
| auto | agentStats () const noexcept |
| Get agents stats from this Dynamics as the following tuple: (nAddedAgents, nInsertedAgents, nArrivedAgents, nKilledAgents, nAgents). | |
| void | summary (std::ostream &os=std::cout) const |
| Print a summary of the dynamics to an output stream. | |
| Public Member Functions inherited from dsf::Dynamics< RoadNetwork > | |
| Dynamics (RoadNetwork &&graph, std::optional< unsigned int > seed=std::nullopt) | |
| Construct a new Dynamics object. | |
| void | setSeed (unsigned int const seed) noexcept |
| Set the seed for the random number generator. | |
| void | setConcurrency (std::size_t const concurrency) |
| Set the maximum number of threads to use for parallel execution. | |
| auto | concurrency () const |
| Get the current concurrency (number of threads configured in the task arena). | |
| auto const & | graph () const |
| Get the graph. | |
| auto | time_step () const |
| Get the current simulation time-step. | |
Protected Attributes | |
| TurnCountsDict | m_turnCounts |
| tbb::concurrent_unordered_map< Id, std::unordered_map< Direction, double > > | m_queuesAtTrafficLights |
| tbb::concurrent_vector< std::pair< double, double > > | m_travelDTs |
| tbb::concurrent_vector< std::unique_ptr< Agent > > | m_agentsToReinsert |
| std::time_t | m_previousOptimizationTime {0} |
| std::optional< double > | m_errorProbability {std::nullopt} |
| std::optional< double > | m_passageProbability {std::nullopt} |
| std::optional< double > | m_meanTravelDistance {std::nullopt} |
| std::optional< std::time_t > | m_meanTravelTime {std::nullopt} |
| std::optional< Delay > | m_dataUpdatePeriod |
| bool | m_bCacheEnabled |
| std::optional< double > | m_timeToleranceFactor {std::nullopt} |
| bool | m_forcePriorities {false} |
| Protected Attributes inherited from dsf::Dynamics< RoadNetwork > | |
| std::unique_ptr< RoadNetwork > | m_graph |
| tbb::task_arena | m_taskArena |
| std::mt19937_64 | m_generator |
Additional Inherited Members | |
| Protected Member Functions inherited from dsf::Dynamics< RoadNetwork > | |
| void | m_evolve () |
The FirstOrderDynamics class represents the dynamics of the network.
| dsf::mobility::FirstOrderDynamics::FirstOrderDynamics | ( | RoadNetwork && | graph, |
| bool | useCache = false, | ||
| std::optional< unsigned int > | seed = std::nullopt ) |
Construct a new FirstOrderDynamics object.
| graph | The graph representing the network |
| useCache | If true, the cache is used (default is false) |
| seed | The seed for the random number generator (default is std::nullopt) |
| void dsf::mobility::FirstOrderDynamics::addAgent | ( | std::shared_ptr< Itinerary > | pItinerary = nullptr, |
| std::optional< Id > | optSrcStreetId = std::nullopt ) |
Add an agent to the simulation.
| pItinerary | std::shared_ptr to the itinerary |
If pItinerary is nullptr, the agent will be added without an itinerary
| optSrcStreetId | std::optional<Id> representing the source street id. If not provided, the source street will be selected randomly. |
| void dsf::mobility::FirstOrderDynamics::addAgent | ( | std::unique_ptr< Agent > | agent | ) |
Add an agent to the simulation.
| agent | std::unique_ptr to the agent |
| void dsf::mobility::FirstOrderDynamics::addAgent | ( | std::vector< std::shared_ptr< Itinerary > > const & | trip, |
| std::optional< Id > | optSrcStreetId = std::nullopt ) |
Add an agent to the simulation.
| trip | std::vector of std::shared_ptr to the itineraries |
| optSrcStreetId | std::optional<Id> representing the source street id. If not provided, the source street will be selected randomly. |
| void dsf::mobility::FirstOrderDynamics::addAgents | ( | std::size_t const | nAgents, |
| AgentInsertionMethod const | mode ) |
Add agents to the simulation.
| nAgents | The number of agents to add |
| mode | The method to use for adding the agents.Possible values are:
|
| void dsf::mobility::FirstOrderDynamics::addAgentsUniformly | ( | std::size_t | nAgents, |
| std::optional< Id > | itineraryId = std::nullopt ) |
Add agents uniformly on the road network.
| nAgents | The number of agents to add |
| itineraryId | The id of the itinerary to use (default is std::nullopt) |
| std::runtime_error | If there are no itineraries |
| void dsf::mobility::FirstOrderDynamics::addItinerary | ( | std::shared_ptr< Itinerary > | itinerary | ) |
Add an itinerary.
| itinerary | std::unique_ptr to the itinerary |
| std::invalid_argument | If the itinerary already exists |
| std::invalid_argument | If the itinerary's destination is not a node of the graph |
| void dsf::mobility::FirstOrderDynamics::addItinerary | ( | TArgs &&... | args | ) |
Add an itinerary.
| ...args | The arguments to construct the itinerary |
The arguments must be compatible with any constructor of the Itinerary class
|
inlinenoexcept |
Get the agents.
|
inlinenoexcept |
Get agents stats from this Dynamics as the following tuple: (nAddedAgents, nInsertedAgents, nArrivedAgents, nKilledAgents, nAgents).
|
noexcept |
Get the destination counts of the agents.
| bReset | If true, the destination counts are cleared (default is true) |
|
inlinenoexcept |
Get the destination nodes of the graph.
|
inlinenoexcept |
Get the destination nodes of the graph.
| StepDataResult dsf::mobility::FirstOrderDynamics::evolve | ( | StepDataRequest const & | dataRequest = {} | ) |
Evolve the simulation.
Evolve the simulation by moving the agents and updating the travel times. In particular:
| dataRequest | The save/collection request for the current step |
|
inlinenoexcept |
Get the free-flow itineraries.
|
inline |
Get the number of ghost agents waiting to be inserted.
| void dsf::mobility::FirstOrderDynamics::importODsFromCSV | ( | std::string_view const | fileName, |
| char const | separator = ';', | ||
| bool const | bEdges = true ) |
Import origin-destination pairs from a CSV file. Possibilities are:
| void dsf::mobility::FirstOrderDynamics::importTransitionMatrixFromJSON | ( | std::string_view const | fileName | ) |
Import the transition matrix used to route random agents from a JSON file.
| fileName | The path of the JSON file |
The file must contain an object whose keys are the current street ids and whose values are objects mapping the candidate next street ids to their probabilities, e.g.:
Rows are not required to sum to 1: the probability of ending the trip is always inferred at runtime as one minus the sum of the other probabilities. The imported matrix is then passed to setTransitionMatrix, which validates it.
| std::runtime_error | If the file cannot be parsed or has an invalid structure |
| std::invalid_argument | If a key is not a valid street id, if a probability is negative or if a row sums up to more than 1 |
| void dsf::mobility::FirstOrderDynamics::initTurnCounts | ( | ) |
Initialize the turn counts map.
| std::runtime_error | if the turn counts map is already initialized |
|
inlinenoexcept |
Get the fraction of intelligent agents, i.e. following the updated paths.
|
inlinenoexcept |
Get the itineraries.
| void dsf::mobility::FirstOrderDynamics::killStagnantAgents | ( | double | timeToleranceFactor = 3. | ) |
Set the time tolerance factor for killing stagnant agents. An agent will be considered stagnant if it has not moved for timeToleranceFactor * std::ceil(street_length / street_maxSpeed) time units.
| timeToleranceFactor | The time tolerance factor |
| std::invalid_argument | If the time tolerance factor is not positive |
| Measurement< double > dsf::mobility::FirstOrderDynamics::meanTravelDistance | ( | bool | clearData = false | ) |
Get the mean travel distance of the agents in \(m\).
| clearData | If true, the travel distances are cleared after the computation |
| Measurement< double > dsf::mobility::FirstOrderDynamics::meanTravelSpeed | ( | bool | clearData = false | ) |
Get the mean travel speed of the agents in \(m/s\).
| clearData | If true, the travel times and distances are cleared after the computation |
| Measurement< double > dsf::mobility::FirstOrderDynamics::meanTravelTime | ( | bool | clearData = false | ) |
Get the mean travel time of the agents in \(s\).
| clearData | If true, the travel times are cleared after the computation |
|
inline |
Get the number of agents currently in the simulation.
|
noexcept |
Get the normalized turn counts of the agents.
| void dsf::mobility::FirstOrderDynamics::optimizeTrafficLights | ( | TrafficLightOptimization | optimizationType = TrafficLightOptimization::DOUBLE_TAIL, |
| const std::string & | logFile = std::string(), | ||
| double const | percentage = 0.3, | ||
| double const | threshold = 1.3 ) |
Optimize the traffic lights by changing the green and red times.
| optimizationType | TrafficLightOptimization, The type of optimization. Default is DOUBLE_TAIL |
| logFile | The file into which write the logs (default is empty, meaning no logging) |
| percentage | double, the maximum amount (percentage) of the green time to change (default is 0.3) |
| threshold | double, The ratio between the self-density and neighbour density to trigger the non-local optimization (default is 1.3) |
The local optimization is done by changing the green time of each traffic light, trying to make it proportional to the queue lengths at each phase. The non-local optimization is done by synchronizing the traffic lights which are congested over threshold.
|
noexcept |
Get the origin counts of the agents.
| bReset | If true, the origin counts are cleared (default is true) |
|
inlinenoexcept |
Get the origin nodes of the graph.
|
inlinenoexcept |
Get the origin nodes of the graph.
| void dsf::mobility::FirstOrderDynamics::prepareNetwork | ( | bool const | bAdjustNodeCapacities = true, |
| bool const | bAutoMapStreetLanes = false, | ||
| bool const | bAutoAssignRoadPriorities = true, | ||
| bool const | bAutoInitTrafficLights = true ) |
Automatically prepare the network for the simulation. This method calls the following methods in order:
| bAdjustNodeCapacities | If true, the nodes' capacities are adjusted using the streets' transport capacities (default is true) |
| bAutoMapStreetLanes | If true, the streets' lanes are automatically mapped using the network's topology (default is false) |
| bAutoAssignRoadPriorities | If true, the streets' priorities are automatically assigned using the network's topology (default is true) |
| bAutoInitTrafficLights | If true, the traffic lights' phases are automatically initialized using the streets' geometry (default is true) |
| void dsf::mobility::FirstOrderDynamics::resetTurnCounts | ( | ) |
Reset the turn counts map values to zero.
| std::runtime_error | if the turn counts map is not initialized |
| void dsf::mobility::FirstOrderDynamics::setConditionalODs | ( | std::unordered_map< Id, std::tuple< double, std::vector< std::tuple< Id, double > > > > const & | originToDestinations | ) |
Set the origin-destination pairs with their associated weights from a map of origin nodes to vectors of destination nodes and weights.
| originToDestinations | An unordered map where the keys are origin node ids and the values are origin weights and vectors of tuples (destination node id, weight) |
|
inlinenoexcept |
Set the data update period.
| dataUpdatePeriod | Delay, The period |
Some data, i.e. the street queue lengths, are stored only after a fixed amount of time which is represented by this variable.
| void dsf::mobility::FirstOrderDynamics::setDestinations | ( | std::initializer_list< Id > | destinations | ) |
Set the destinations.
| destinations | The destinations (as an initializer list) |
| void dsf::mobility::FirstOrderDynamics::setDestinations | ( | std::unordered_map< Id, double > const & | destinations | ) |
Set the destinations.
| destinations | The destinations |
| void dsf::mobility::FirstOrderDynamics::setDestinations | ( | TContainer const & | destinationNodes | ) |
Set the destinations.
| destinations | A container of destination ids |
The container must have a value_type convertible to Id and begin() and end() methods
| void dsf::mobility::FirstOrderDynamics::setErrorProbability | ( | double | errorProbability | ) |
Set the error probability.
| errorProbability | The error probability |
| std::invalid_argument | If the error probability is not between 0 and 1 |
|
inlinenoexcept |
Set the force priorities flag.
| forcePriorities | The flag |
If true, if an agent cannot move to the next street, the whole node is skipped
| void dsf::mobility::FirstOrderDynamics::setIntelligentAgentsFraction | ( | double const | intelligentFraction | ) |
Set the fraction of intelligent agents.
| intelligentFraction | The fraction, in [0, 1] |
When it is added, each non-random agent is flagged as intelligent with this probability (default is 0, i.e. no intelligent agents). Intelligent agents follow the paths recomputed at each updatePaths() call, while the others route on the free-flow best paths (see freeflowItineraries()).
| std::invalid_argument | If the fraction is not in [0, 1] |
|
inline |
Set the mean distance travelled by a random agent. The distance will be sampled from an exponential distribution with this mean.
| meanTravelDistance | The mean distance |
| std::invalid_argument | If the mean distance is negative |
|
inlinenoexcept |
Set the mean travel time for random agents. The travel time will be sampled from an exponential distribution with this mean.
| meanTravelTime | The mean travel time |
| void dsf::mobility::FirstOrderDynamics::setODs | ( | std::vector< std::tuple< Id, Id, double > > const & | ODs | ) |
Set the origin-destination pairs with their associated weights.
| ODs | A vector of tuples (origin node id, destination node id, weight) |
| void dsf::mobility::FirstOrderDynamics::setOrigins | ( | std::unordered_map< Id, double > const & | origins = {} | ) |
Set the origins.
| origins | The origin nodes |
| void dsf::mobility::FirstOrderDynamics::setPassageProbability | ( | double | passageProbability | ) |
Set the passage probability.
| passageProbability | The passage probability |
The passage probability is the probability of passing through a node It is useful in the case of random agents
| void dsf::mobility::FirstOrderDynamics::setSpeedFunction | ( | SpeedFunction const | speedFunction, |
| TArgs &&... | args ) |
Set the speed function. Options are:
| void dsf::mobility::FirstOrderDynamics::setTransitionMatrix | ( | std::unordered_map< Id, std::unordered_map< Id, double > > const & | transitionMatrix | ) |
Set the transition matrix used to route random agents.
| transitionMatrix | The transition matrix, i.e. a map whose outer key is the current street id, whose inner keys are the candidate next street ids and whose values are the corresponding probabilities |
The probabilities of each row must sum up to at most 1: the missing mass is the probability that the agent ends its trip at that junction, which is inferred at runtime and must not be part of the given matrix. Streets which are not a key of the matrix keep the default uniform behaviour. Entries which cannot be used because the destination street is unknown or is not an outgoing edge of the source street's target node are dropped and reported as warnings, which reduces the row's total probability and thus increases the end probability accordingly. Forbidden turns and U-turns are handled differently: since random agents can never take them, their probability is instead redistributed proportionally among the other entries of the same row, so that the end probability is unaffected by their weights. If a row only contains forbidden-turn and/or U-turn entries, there is nothing to redistribute onto and the probability is dropped (reported as a warning) like any other unusable entry.
| std::invalid_argument | If a probability is negative or if a row sums up to more than 1 |
|
inlinenoexcept |
Set the update paths throw on empty flag.
| throwOnEmpty | The flag |
If true, if an itinerary has an empty path when updating paths, an exception is thrown. If false, the itinerary is left unchanged.
|
inline |
Set the penalty factor applied to U-turns when choosing the next street.
| uturnPenaltyFactor | The penalty factor, which must be positive. |
| std::invalid_argument | If the penalty factor is not positive. |
|
inline |
Get the mean density of the streets in \(m^{-1}\) or \(a.u.\) if Normalized.
| Normalized | If true, the density is normalized by the street's capacity |
| Measurement< double > dsf::mobility::FirstOrderDynamics::streetMeanFlow | ( | ) | const |
Get the mean flow of the streets in \(s^{-1}\).
The flow uses the speeds of the agents that left each street since the last data save (see evolve); reading it does not reset them.
| Measurement< double > dsf::mobility::FirstOrderDynamics::streetMeanFlow | ( | double | threshold, |
| bool | above ) const |
Get the mean flow of the streets in \(s^{-1}\).
Same speed samples as streetMeanFlow(); reading them does not reset them.
| threshold | The density threshold to consider |
| above | If true, the function returns the mean flow of the streets with a density above the threshold, otherwise below |
| void dsf::mobility::FirstOrderDynamics::summary | ( | std::ostream & | os = std::cout | ) | const |
Print a summary of the dynamics to an output stream.
| os | The output stream to write to (default is std::cout) |
The summary includes:
|
inlinenoexcept |
Get the transition matrix used to route random agents.
|
inlinenoexcept |
Get the turn counts of the agents.
| void dsf::mobility::FirstOrderDynamics::updatePaths | ( | ) |
Update the paths of the itineraries based on the given weight function.
Itineraries without a free-flow counterpart get one, copied from the freshly computed path. This snapshot is never updated afterwards, so the first call should happen on the empty network.
| std::runtime_error | if m_updatepathsThrowOnEmpty is true and an itinerary has an empty path |