Common stacker for multiple stations that never jams
Posted: Sat Feb 17, 2024 9:38 pm
I heard many times that multiple stations with common stacker cannot have dynamic limits: it just does not work, it jams. Well... I think there is an interesting and simple solution. So the problem:
Design a common stacker for multiple train stations that never jams and allows to park as much trains as possible.
Suppose there are 3 stations A , B, C, and a stacker for 3 trains.
Video: https://www.veed.io/view/c6096e7f-65cb- ... 7f8fc2af34
There is a boring non-optimal solution: put static train limit 2 on each station (1 train in a station and 1 train in a stacker slot). There will be no jamming. But if, for any reason, there are no trains going to stations A and B, then 2 stacker slots will always be empty. This is not optimal as these 2 slots could be in theory occupied by trains going to station C
I think there is an almost optimal solution via dynamic change of trains limits. My wife has found it, she is a mathematician. So she said: "basically, train limit is an invitation. If you put limit = 3 that means you invite 3 trains to come to the station", and suggested the following simple solution.
Indeed, we should always avoid jams, so if a train is going to a station then we should always assume that it will occupy a slot in the stacker (worst case scenario) and
Now choose train limits. Obviously, if some trains are already going to station X, they should be included in the limit of station X as they have already been invited. Further, we can invite new trains to occupy all available slots on the stacker. So for any station X, put
For example, if there is only 1 available slot in the stacker, then each station will invite 1 new train = 3 new trains in total. This looks very strange, but works surprisingly well! If a train decides to accept an invitation an go to station X, the number of available slots immediately goes down to 0 and no new trains will be invited.
This solution also works if you have an other logic to set train limits (e.g. Nilaus load or unload stations): you just compute minimum of those two limits.
There remains one edge case: if two stations increase their train limit simultaneously at the same tick. In this case it may happen that number of invited trains would become bigger than the staker size, which would create a jam. This case is solved easily: we do not need to invite trains to a station at any tick, we invite trains to station A at tick 10, to station B at tick 20 and to station C at tick 30 of 60 ticks in a second.
Here is a bp with an example
Design a common stacker for multiple train stations that never jams and allows to park as much trains as possible.
Suppose there are 3 stations A , B, C, and a stacker for 3 trains.
Video: https://www.veed.io/view/c6096e7f-65cb- ... 7f8fc2af34
There is a boring non-optimal solution: put static train limit 2 on each station (1 train in a station and 1 train in a stacker slot). There will be no jamming. But if, for any reason, there are no trains going to stations A and B, then 2 stacker slots will always be empty. This is not optimal as these 2 slots could be in theory occupied by trains going to station C
I think there is an almost optimal solution via dynamic change of trains limits. My wife has found it, she is a mathematician. So she said: "basically, train limit is an invitation. If you put limit = 3 that means you invite 3 trains to come to the station", and suggested the following simple solution.
- Any station knows the number of trains that are going to the station: C = [train count]
- Any station knows if there is a train stopped at the station: T = [train id] if present.
Code: Select all
[number of occupied slots in the stacker] = [number of trains going to all station] - [number of trains stopped on stations]
Code: Select all
[number of available slots] = [stacker size] - [number of occupied slots]
Code: Select all
L = [number of available slots] + C
This solution also works if you have an other logic to set train limits (e.g. Nilaus load or unload stations): you just compute minimum of those two limits.
There remains one edge case: if two stations increase their train limit simultaneously at the same tick. In this case it may happen that number of invited trains would become bigger than the staker size, which would create a jam. This case is solved easily: we do not need to invite trains to a station at any tick, we invite trains to station A at tick 10, to station B at tick 20 and to station C at tick 30 of 60 ticks in a second.
Here is a bp with an example