Auto timetabling: bias timetable adjustment to favour negative adjustments.

This is to prevent positive feedback where timetable times are increased
due to congestion, which creates more congestion due to trains waiting
for extended periods at stations and/or due to timetable auto separation
going overboard due to overly long timetables.

* Double rate of negative adjustments.
* Half rate of positive adjustments.
* Only do step changes for large negative adjustments.
* Reduce jam detection threshold.
This commit is contained in:
Jonathan G Rennison 2015-08-11 21:06:21 +01:00
parent d24f7763cc
commit cca6495d1e

View File

@ -668,15 +668,7 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling)
new_time = time_loading;
}
/* Check for too large a difference from expected time, and if so don't average. */
if (!(new_time > (int32)timetabled * 2 || new_time < (int32)timetabled / 2)) {
int arrival_error = timetabled - new_time;
/* Compute running average, with sign conversion to avoid negative overflow. */
new_time = ((int32)timetabled * 4 + new_time + 2) / 5;
/* Use arrival_error to finetune order ticks. */
if (arrival_error < 0) new_time++;
if (arrival_error > 0) new_time--;
} else if (new_time > (int32)timetabled * 10 && travelling) {
if (new_time > (int32)timetabled * 4 && travelling) {
/* Possible jam, clear time and restart timetable for all vehicles.
* Otherwise we risk trains blocking 1-lane stations for long times. */
ChangeTimetable(v, v->cur_real_order_index, 0, travelling ? MTF_TRAVEL_TIME : MTF_WAIT_TIME, true);
@ -686,6 +678,15 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling)
SetWindowDirty(WC_VEHICLE_TIMETABLE, v2->index);
}
return;
} else if (new_time >= (int32)timetabled / 2) {
/* Compute running average, with sign conversion to avoid negative overflow. */
if (new_time < (int32)timetabled) {
new_time = ((int32)timetabled * 3 + new_time * 2 + 2) / 5;
} else {
new_time = ((int32)timetabled * 9 + new_time + 5) / 10;
}
} else {
/* new time is less than hald old time, set value directly */
}
if (new_time < 1) new_time = 1;