68 return std::max(from.base.
supply * std::max(1U, to.base.
supply) * this->mod_size / 100 / this->demand_per_node, 1U);
80 return (to.base.
supply == 0 || to.undelivered_supply > 0) && to.base.
demand > 0;
137 if (job[from_id].base.demand > 0) {
138 uint demand_back = demand_forw * this->
mod_size / 100;
139 uint undelivered = job[to_id].undelivered_supply;
140 if (demand_back > undelivered) {
141 demand_back = undelivered;
142 demand_forw = std::max(1U, demand_back * 100 / this->
mod_size);
160 job[from_id].DeliverSupply(to_id, demand_forw);
168template <
class Tscaler>
173 uint num_supplies = 0;
174 uint num_demands = 0;
176 for (NodeID node = 0; node < job.
Size(); node++) {
177 scaler.AddNode(job[node]);
178 if (job[node].base.supply > 0) {
182 if (job[node].base.demand > 0) {
188 if (num_supplies == 0 || num_demands == 0)
return;
193 scaler.SetDemandPerNode(num_demands);
196 while (!supplies.empty() && !demands.empty()) {
197 NodeID from_id = supplies.front();
200 for (uint i = 0; i < num_demands; ++i) {
201 assert(!demands.empty());
202 NodeID to_id = demands.front();
204 if (from_id == to_id) {
206 if (demands.empty() && supplies.empty())
return;
212 int32_t supply = scaler.EffectiveSupply(job[from_id], job[to_id]);
215 constexpr int32_t divisor_scale = 16;
226 const int32_t divisor = divisor_scale + ((this->
accuracy * scaled_distance * divisor_scale) / (this->
base_distance * 2));
227 assert(divisor >= divisor_scale);
229 uint demand_forw = 0;
230 if (divisor <= (supply * divisor_scale)) {
234 demand_forw = (supply * divisor_scale) / divisor;
235 }
else if (++chance > this->
accuracy * num_demands * num_supplies) {
241 demand_forw = std::min(demand_forw, job[from_id].undelivered_supply);
243 scaler.SetDemands(job, from_id, to_id, demand_forw);
245 if (scaler.HasDemandLeft(job[to_id])) {
251 if (job[from_id].undelivered_supply == 0)
break;
254 if (job[from_id].undelivered_supply != 0) {
255 supplies.push(from_id);
283 this->
mod_dist = 100 + ((over100 * over100) / 12);
286 switch (
settings.GetDistributionType(cargo)) {
288 this->CalcDemand<SymmetricScaler>(job, SymmetricScaler(settings.demand_size));
291 this->CalcDemand<AsymmetricScaler>(job, AsymmetricScaler());
uint8_t CargoType
Cargo slots to indicate a cargo type within a game.
A scaler for asymmetric distribution.
void AddNode(const Node &)
Nothing to do here.
uint EffectiveSupply(const Node &from, const Node &)
Get the effective supply of one node towards another one.
void SetDemandPerNode(uint)
Nothing to do here.
bool HasDemandLeft(const Node &to)
Check if there is any acceptance left for this node.
void CalcDemand(LinkGraphJob &job, Tscaler scaler)
Do the actual demand calculation, called from constructor.
DemandCalculator(LinkGraphJob &job)
Create the DemandCalculator and immediately do the calculation.
int32_t base_distance
Base distance for scaling purposes.
int32_t mod_dist
Distance modifier, determines how much demands decrease with distance.
int32_t accuracy
Accuracy of the calculation.
Class for calculation jobs to be run on link graphs.
const LinkGraphSettings & Settings() const
Get the link graph settings for this component.
CargoType Cargo() const
Get the cargo of the underlying link graph.
NodeID Size() const
Get the size of the underlying link graph.
Hash table based node list multi-container class.
Scale various things according to symmetric/asymmetric distribution.
void SetDemands(LinkGraphJob &job, NodeID from, NodeID to, uint demand_forw)
Set the demands between two nodes using the given base demand.
uint mod_size
Size modifier. Determines how much demands increase with the supply of the remote station.
uint EffectiveSupply(const Node &from, const Node &to)
Get the effective supply of one node towards another one.
uint demand_per_node
Mean demand associated with each node.
void SetDemandPerNode(uint num_demands)
Calculate the mean demand per node using the sum of supplies.
void AddNode(const Node &node)
Count a node's supply into the sum of supplies.
bool HasDemandLeft(const Node &to)
Check if there is any acceptance left for this node.
void SetDemands(LinkGraphJob &job, NodeID from, NodeID to, uint demand_forw)
Set the demands between two nodes using the given base demand.
uint supply_sum
Sum of all supplies in the component.
SymmetricScaler(uint mod_size)
Constructor.
uint32_t IntSqrt(uint32_t num)
Compute the integer square root.
Declaration of demand calculating link graph handler.
fluid_settings_t * settings
FluidSynth settings handle.
uint DistanceMaxPlusManhattan(TileIndex t0, TileIndex t1)
Gets the biggest distance component (x or y) between the two given tiles plus the Manhattan distance,...
static TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
A number of safeguards to prevent using unsafe methods.
Definition of base types and functions in a cross-platform compatible way.
uint supply
Supply at the station.
uint demand
Acceptance at the station.
Size related data of the map.