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;
139 if (job[from_id].base.demand > 0) {
140 uint demand_back = demand_forw * this->
mod_size / 100;
141 uint undelivered = job[to_id].undelivered_supply;
142 if (demand_back > undelivered) {
143 demand_back = undelivered;
144 demand_forw = std::max(1U, demand_back * 100 / this->
mod_size);
162 job[from_id].DeliverSupply(to_id, demand_forw);
170template <
class Tscaler>
175 uint num_supplies = 0;
176 uint num_demands = 0;
178 for (NodeID node = 0; node < job.
Size(); node++) {
179 scaler.AddNode(job[node]);
180 if (job[node].base.supply > 0) {
184 if (job[node].base.demand > 0) {
190 if (num_supplies == 0 || num_demands == 0)
return;
195 scaler.SetDemandPerNode(num_demands);
198 while (!supplies.empty() && !demands.empty()) {
199 NodeID from_id = supplies.front();
202 for (uint i = 0; i < num_demands; ++i) {
203 assert(!demands.empty());
204 NodeID to_id = demands.front();
206 if (from_id == to_id) {
208 if (demands.empty() && supplies.empty())
return;
214 int32_t supply = scaler.EffectiveSupply(job[from_id], job[to_id]);
217 constexpr int32_t divisor_scale = 16;
228 const int32_t divisor = divisor_scale + ((this->
accuracy * scaled_distance * divisor_scale) / (this->
base_distance * 2));
229 assert(divisor >= divisor_scale);
231 uint demand_forw = 0;
232 if (divisor <= (supply * divisor_scale)) {
236 demand_forw = (supply * divisor_scale) / divisor;
237 }
else if (++chance > this->
accuracy * num_demands * num_supplies) {
243 demand_forw = std::min(demand_forw, job[from_id].undelivered_supply);
245 scaler.SetDemands(job, from_id, to_id, demand_forw);
247 if (scaler.HasDemandLeft(job[to_id])) {
253 if (job[from_id].undelivered_supply == 0)
break;
256 if (job[from_id].undelivered_supply != 0) {
257 supplies.push(from_id);
285 this->
mod_dist = 100 + ((over100 * over100) / 12);
288 switch (
settings.GetDistributionType(cargo)) {
290 this->CalcDemand<SymmetricScaler>(job, SymmetricScaler(settings.demand_size));
293 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.
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.
uint32_t IntSqrt(uint32_t num)
Compute the integer square root.
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.