Link graph: Change distance scaling algorithm in demand scaler
Fix erratic scaling and increase effect at large setting values
This commit is contained in:
@@ -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;
|
||||
|
@@ -15,9 +15,9 @@ public:
|
||||
DemandCalculator(LinkGraphJob &job);
|
||||
|
||||
private:
|
||||
int32_t max_distance; ///< Maximum distance possible on the map.
|
||||
int32_t mod_dist; ///< Distance modifier, determines how much demands decrease with distance.
|
||||
int32_t accuracy; ///< Accuracy of 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.
|
||||
|
||||
template<class Tscaler>
|
||||
void CalcDemand(LinkGraphJob &job, const std::vector<bool> &reachable_nodes, Tscaler scaler);
|
||||
|
Reference in New Issue
Block a user