7 #include "../safeguards.h" 9 typedef std::queue<NodeID> NodeList;
39 this->supply_sum += node.
Supply();
48 this->demand_per_node =
max(this->supply_sum / num_demands, 1U);
60 return max(from.
Supply() *
max(1U, to.
Supply()) * this->mod_size / 100 / this->demand_per_node, 1U);
72 return (to.
Supply() == 0 || to.UndeliveredSupply() > 0) && to.
Demand() > 0;
132 if (job[from_id].Demand() > 0) {
133 uint demand_back = demand_forw * this->mod_size / 100;
134 uint undelivered = job[to_id].UndeliveredSupply();
135 if (demand_back > undelivered) {
136 demand_back = undelivered;
137 demand_forw =
max(1U, demand_back * 100 / this->mod_size);
155 job[from_id].DeliverSupply(to_id, demand_forw);
163 template<
class Tscaler>
168 uint num_supplies = 0;
169 uint num_demands = 0;
171 for (NodeID node = 0; node < job.
Size(); node++) {
172 scaler.AddNode(job[node]);
173 if (job[node].Supply() > 0) {
177 if (job[node].Demand() > 0) {
183 if (num_supplies == 0 || num_demands == 0)
return;
188 scaler.SetDemandPerNode(num_demands);
191 while (!supplies.empty() && !demands.empty()) {
192 NodeID from_id = supplies.front();
195 for (uint i = 0; i < num_demands; ++i) {
196 assert(!demands.empty());
197 NodeID to_id = demands.front();
199 if (from_id == to_id) {
201 if (demands.empty() && supplies.empty())
return;
207 int32 supply = scaler.EffectiveSupply(job[from_id], job[to_id]);
211 int32 distance = this->max_distance - (this->max_distance -
213 this->mod_dist / 100;
216 int32 divisor = this->accuracy * (this->mod_dist - 50) / 100 +
217 this->accuracy * distance / this->max_distance + 1;
221 uint demand_forw = 0;
222 if (divisor <= supply) {
226 demand_forw = supply / divisor;
227 }
else if (++chance > this->accuracy * num_demands * num_supplies) {
233 demand_forw =
min(demand_forw, job[from_id].UndeliveredSupply());
235 scaler.SetDemands(job, from_id, to_id, demand_forw);
237 if (scaler.HasDemandLeft(job[to_id])) {
243 if (job[from_id].UndeliveredSupply() == 0)
break;
246 if (job[from_id].UndeliveredSupply() != 0) {
247 supplies.push(from_id);
269 this->
mod_dist = 100 + over100 * over100;
272 switch (settings.GetDistributionType(cargo)) {
uint mod_size
Size modifier. Determines how much demands increase with the supply of the remote station...
uint Demand() const
Get demand of wrapped node.
uint supply_sum
Sum of all supplies in the component.
bool HasDemandLeft(const Node &to)
Check if there is any acceptance left for this node.
void SetDemandPerNode(uint num_demands)
Calculate the mean demand per node using the sum of supplies.
uint Supply() const
Get supply of wrapped node.
uint EffectiveSupply(const Node &from, const Node &to)
Get the effective supply of one node towards another one.
uint EffectiveSupply(const Node &from, const Node &)
Get the effective supply of one node towards another one.
void SetDemands(LinkGraphJob &job, NodeID from, NodeID to, uint demand_forw)
Set the demands between two nodes using the given base demand.
fluid_settings_t * settings
FluidSynth settings handle.
void SetDemands(LinkGraphJob &job, NodeID from, NodeID to, uint demand_forw)
Set the demands between two nodes using the given base demand.
uint demand_per_node
Mean demand associated with each node.
Symmetric distribution. The same amount of cargo travels in each direction between each pair of nodes...
void CalcDemand(LinkGraphJob &job, Tscaler scaler)
Do the actual demand calculation, called from constructor.
Asymmetric distribution. Usually cargo will only travel in one direction.
static T max(const T a, const T b)
Returns the maximum of two values.
int32 mod_dist
Distance modifier, determines how much demands decrease with distance.
DemandCalculator(LinkGraphJob &job)
Create the DemandCalculator and immediately do the calculation.
const LinkGraphSettings & Settings() const
Get the link graph settings for this component.
bool HasDemandLeft(const Node &to)
Check if there is any acceptance left for this node.
void SetDemandPerNode(uint)
Nothing to do here.
SymmetricScaler(uint mod_size)
Constructor.
Declaration of demand calculating link graph handler.
static T min(const T a, const T b)
Returns the minimum of two values.
uint8 accuracy
accuracy when calculating things on the link graph. low accuracy => low running time ...
Scale various things according to symmetric/asymmetric distribution.
A scaler for asymmetric distribution.
CargoID Cargo() const
Get the cargo of the underlying link graph.
void AddNode(const Node &node)
Count a node's supply into the sum of supplies.
int32 accuracy
Accuracy of the calculation.
uint DistanceMaxPlusManhattan(TileIndex t0, TileIndex t1)
Gets the biggest distance component (x or y) between the two given tiles plus the Manhattan distance...
uint Size() const
Get the size of the underlying link graph.
static uint MapMaxY()
Gets the maximum Y coordinate within the map, including MP_VOID.
uint8 demand_size
influence of supply ("station size") on the demand function
void AddNode(const Node &)
Nothing to do here.
byte CargoID
Cargo slots to indicate a cargo type within a game.
static uint MapMaxX()
Gets the maximum X coordinate within the map, including MP_VOID.
static TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
Class for calculation jobs to be run on link graphs.
uint8 demand_distance
influence of distance between stations on the demand function
Scaler for symmetric distribution.