@@ -6,13 +6,15 @@ namespace dsm {
66 template <typename delay_t >
77 requires (std::unsigned_integral<delay_t >)
88 class FirstOrderDynamics : public RoadDynamics <delay_t > {
9+ double m_alpha;
910 double m_speedFluctuationSTD;
1011
1112 public:
1213 // / @brief Construct a new First Order Dynamics object
1314 // / @param graph, The graph representing the network
14- FirstOrderDynamics (Graph& graph, std::optional<unsigned int > seed = std::nullopt )
15- : RoadDynamics<delay_t >(graph, seed), m_speedFluctuationSTD{0 .} {};
15+ FirstOrderDynamics (Graph& graph,
16+ std::optional<unsigned int > seed = std::nullopt ,
17+ double minSpeedRateo = 0 .);
1618 // / @brief Set the speed of an agent
1719 // / @param agentId The id of the agent
1820 // / @throw std::invalid_argument, If the agent is not found
@@ -38,18 +40,49 @@ namespace dsm {
3840 Measurement<double > streetMeanSpeed (double threshold, bool above) const override ;
3941 };
4042
43+ template <typename delay_t >
44+ requires (std::unsigned_integral<delay_t >)
45+ FirstOrderDynamics<delay_t >::FirstOrderDynamics(Graph& graph,
46+ std::optional<unsigned int > seed,
47+ double minSpeedRateo)
48+ : RoadDynamics<delay_t >(graph, seed),
49+ m_alpha{0 .},
50+ m_speedFluctuationSTD{0 .} {
51+ if (minSpeedRateo < 0 . || minSpeedRateo > 1 .) {
52+ throw std::invalid_argument (buildLog (
53+ std::format (" The minimum speed rateo must be between 0 and 1, but it is {}" ,
54+ minSpeedRateo)));
55+ } else {
56+ m_alpha = minSpeedRateo;
57+ }
58+ double globMaxTimePenalty{0 .};
59+ for (const auto & [streetId, street] : this ->m_graph .streetSet ()) {
60+ globMaxTimePenalty =
61+ std::max (globMaxTimePenalty,
62+ std::ceil (street->length () /
63+ ((1 . - m_alpha) * street->maxSpeed ())));
64+ }
65+ if (globMaxTimePenalty > static_cast <double >(std::numeric_limits<delay_t >::max ())) {
66+ throw std::overflow_error (
67+ buildLog (std::format (" The maximum time penalty ({}) is greater than the "
68+ " maximum value of delay_t ({})" ,
69+ globMaxTimePenalty,
70+ std::numeric_limits<delay_t >::max ())));
71+ }
72+ }
73+
4174 template <typename delay_t >
4275 requires (std::unsigned_integral<delay_t >)
4376 void FirstOrderDynamics<delay_t >::setAgentSpeed(Size agentId) {
4477 const auto & agent{this ->m_agents [agentId]};
4578 const auto & street{this ->m_graph .streetSet ()[agent->streetId ().value ()]};
4679 double speed{street->maxSpeed () *
47- (1 . - this -> m_minSpeedRateo * street->density (true ))};
80+ (1 . - m_alpha * street->density (true ))};
4881 if (m_speedFluctuationSTD > 0 .) {
4982 std::normal_distribution<double > speedDist{speed, speed * m_speedFluctuationSTD};
5083 speed = speedDist (this ->m_generator );
5184 }
52- speed < 0 . ? agent->setSpeed (street->maxSpeed () * (1 . - this -> m_minSpeedRateo ))
85+ speed < 0 . ? agent->setSpeed (street->maxSpeed () * (1 . - m_alpha ))
5386 : agent->setSpeed (speed);
5487 }
5588
@@ -74,7 +107,7 @@ namespace dsm {
74107 Size n{0 };
75108 if (street->nExitingAgents () == 0 ) {
76109 n = static_cast <Size>(street->waitingAgents ().size ());
77- double alpha{this -> m_minSpeedRateo / street->capacity ()};
110+ double alpha{m_alpha / street->capacity ()};
78111 meanSpeed = street->maxSpeed () * n * (1 . - 0.5 * alpha * (n - 1 .));
79112 } else {
80113 for (const auto & agentId : street->waitingAgents ()) {
0 commit comments