|
|
|
@ -308,23 +308,26 @@ void DemandCalculator::CalcDemand(LinkGraphJob &job, const std::vector<bool> &re
|
|
|
|
|
int32_t supply = scaler.EffectiveSupply(job[from_id], job[to_id]);
|
|
|
|
|
assert(supply > 0);
|
|
|
|
|
|
|
|
|
|
/* Scale the distance by mod_dist around max_distance */
|
|
|
|
|
int32_t distance = this->max_distance - (this->max_distance -
|
|
|
|
|
(int32_t)DistanceMaxPlusManhattan(job[from_id].XY(), job[to_id].XY())) *
|
|
|
|
|
this->mod_dist / 100;
|
|
|
|
|
constexpr int32_t divisor_scale = 16;
|
|
|
|
|
|
|
|
|
|
int32_t scaled_distance = this->base_distance;
|
|
|
|
|
if (this->mod_dist > 0) {
|
|
|
|
|
const int32_t distance = DistanceMaxPlusManhattan(job[from_id].XY(), job[to_id].XY());
|
|
|
|
|
/* Scale distance around base_distance by (mod_dist * (100 / 1024)).
|
|
|
|
|
* Note that this means that the distance range is always compressed because mod_dist <= 1024. */
|
|
|
|
|
scaled_distance = this->base_distance + (((distance - this->base_distance) * this->mod_dist) / 1024);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Scale the accuracy by distance around accuracy / 2 */
|
|
|
|
|
int32_t divisor = this->accuracy * (this->mod_dist - 50) / 100 +
|
|
|
|
|
this->accuracy * distance / this->max_distance + 1;
|
|
|
|
|
|
|
|
|
|
assert(divisor > 0);
|
|
|
|
|
const int32_t divisor = divisor_scale + ((this->accuracy * scaled_distance * divisor_scale) / (this->base_distance * 2));
|
|
|
|
|
assert(divisor >= divisor_scale);
|
|
|
|
|
|
|
|
|
|
uint demand_forw = 0;
|
|
|
|
|
if (divisor <= supply) {
|
|
|
|
|
if (divisor <= (supply * divisor_scale)) {
|
|
|
|
|
/* At first only distribute demand if
|
|
|
|
|
* effective supply / accuracy divisor >= 1
|
|
|
|
|
* Others are too small or too far away to be considered. */
|
|
|
|
|
demand_forw = supply / divisor;
|
|
|
|
|
demand_forw = (supply * divisor_scale) / divisor;
|
|
|
|
|
} else if (++chance > this->accuracy * num_demands * num_supplies) {
|
|
|
|
|
/* After some trying, if there is still supply left, distribute
|
|
|
|
|
* demand also to other nodes. */
|
|
|
|
@ -410,7 +413,7 @@ void DemandCalculator::CalcMinimisedDistanceDemand(LinkGraphJob &job, const std:
|
|
|
|
|
* @param job Job to calculate the demands for.
|
|
|
|
|
*/
|
|
|
|
|
DemandCalculator::DemandCalculator(LinkGraphJob &job) :
|
|
|
|
|
max_distance(DistanceMaxPlusManhattan(TileXY(0,0), TileXY(MapMaxX(), MapMaxY())))
|
|
|
|
|
base_distance(IntSqrt(DistanceMaxPlusManhattan(TileXY(0,0), TileXY(MapMaxX(), MapMaxY()))))
|
|
|
|
|
{
|
|
|
|
|
const LinkGraphSettings &settings = job.Settings();
|
|
|
|
|
CargoID cargo = job.Cargo();
|
|
|
|
@ -419,8 +422,7 @@ DemandCalculator::DemandCalculator(LinkGraphJob &job) :
|
|
|
|
|
this->mod_dist = settings.demand_distance;
|
|
|
|
|
if (this->mod_dist > 100) {
|
|
|
|
|
/* Increase effect of mod_dist > 100 */
|
|
|
|
|
int over100 = this->mod_dist - 100;
|
|
|
|
|
this->mod_dist = 100 + over100 * over100;
|
|
|
|
|
this->mod_dist = 100 + ((this->mod_dist - 100) * 4);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (settings.GetDistributionType(cargo) == DT_MANUAL) return;
|
|
|
|
|