5 #include "../core/math_func.hpp"
8 #include "../safeguards.h"
10 typedef std::queue<NodeID> NodeList;
61 return std::max(from.base.
supply * std::max(1U, to.base.
supply) * this->mod_size / 100 / this->demand_per_node, 1U);
73 return (to.base.
supply == 0 || to.undelivered_supply > 0) && to.base.
demand > 0;
133 if (job[from_id].base.demand > 0) {
134 uint demand_back = demand_forw * this->
mod_size / 100;
135 uint undelivered = job[to_id].undelivered_supply;
136 if (demand_back > undelivered) {
137 demand_back = undelivered;
138 demand_forw = std::max(1U, demand_back * 100 / this->
mod_size);
156 job[from_id].DeliverSupply(to_id, demand_forw);
164 template<
class Tscaler>
169 uint num_supplies = 0;
170 uint num_demands = 0;
172 for (NodeID node = 0; node < job.
Size(); node++) {
173 scaler.AddNode(job[node]);
174 if (job[node].base.supply > 0) {
178 if (job[node].base.demand > 0) {
184 if (num_supplies == 0 || num_demands == 0)
return;
189 scaler.SetDemandPerNode(num_demands);
192 while (!supplies.empty() && !demands.empty()) {
193 NodeID from_id = supplies.front();
196 for (uint i = 0; i < num_demands; ++i) {
197 assert(!demands.empty());
198 NodeID to_id = demands.front();
200 if (from_id == to_id) {
202 if (demands.empty() && supplies.empty())
return;
208 int32_t supply = scaler.EffectiveSupply(job[from_id], job[to_id]);
211 constexpr int32_t divisor_scale = 16;
222 const int32_t divisor = divisor_scale + ((this->
accuracy * scaled_distance * divisor_scale) / (this->
base_distance * 2));
223 assert(divisor >= divisor_scale);
225 uint demand_forw = 0;
226 if (divisor <= (supply * divisor_scale)) {
230 demand_forw = (supply * divisor_scale) / divisor;
231 }
else if (++chance > this->
accuracy * num_demands * num_supplies) {
237 demand_forw = std::min(demand_forw, job[from_id].undelivered_supply);
239 scaler.SetDemands(job, from_id, to_id, demand_forw);
241 if (scaler.HasDemandLeft(job[to_id])) {
247 if (job[from_id].undelivered_supply == 0)
break;
250 if (job[from_id].undelivered_supply != 0) {
251 supplies.push(from_id);
279 this->
mod_dist = 100 + ((over100 * over100) / 12);
282 switch (
settings.GetDistributionType(cargo)) {