News:

SimuTranslator
Make Simutrans speak your language.

Wrong Passengers get on the train

Started by dennosius, December 30, 2012, 07:04:12 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

dennosius

Hi!
I'm having a problem with my simutrans game.

It's actually more complex, but it can be simplified to this:

A--B--C--D--E

These are 5 towns connected with a high-speed railway line. C in the center has the airport, which connects the network with the rest of the world, so that's where most passengers want to go, but of course, some are also heading to destinations within A to E. B and D are bigger cities, A and E are a bit smaller.

What I formerly had were trains connecting A to B and B to C and so on, so operating only between two stops. That was easily manageable and worked well. But to make it more realistic and more comfortable for my passengers, I decided to have trains going all the way through and stopping at each station. So I made 2 new lines, one A-B-C-D-E and return, and one only B-C-D and return, because those are the bigger cities and not all trains need to serve A and E.

The problem now is: Simutrans' logic seems to prefer passengers for the next stop. So when a train heading to E stops at the airport station at C, it first loads all passengers for D and only loads passengers for E if there are places left in the train.

So what happens is:
- The train with the capacity of 400 is loaded full with passengers to D, although there were only 450 passengers waiting for D and 4,500 for E
- The train operates almost empty between D and E, because it picked up noone for E at C (it of course picks some up at D)
- The next train that only operates from C to D is almost empty, because the former train picked almost everyone up
- The passengers for E queue up at C to an illusionary amount

Am I doing anything wrong? Or is this Simutrans' logic?

In my eyes, this doesn't make sense. It may make sense in circle lines (so passengers less likely travel all the way clockwise of their destination is the next counter-clockwise), but it does make no sense in straight lines. For best results, it could be the other way round, but most realistic would probably be a proportional loading, because passengers don't care where a train goes after their respective destinations. So of there are, at C, 450 passengers for D and 4,500 for E, a train with a capacity of 400 should load 40 to D and 360 to E.

kierongreen

Passengers board trains in the order of stops on that line - so the furthest stop away will be the last to board. The reason this was chosen was to deal with the following situation:

Express: A--------D
Local:   A--B--C--D

Here if we take station A as an example - the local service will primarily fill with passengers for B and C, only taking passengers for D if there is space, meaning that most passengers for D will travel on the express. This code also tends to work reasonably well for circular routes. Of course other loading strategies would be optimum for other line layouts - such as yours. No single strategy will be perfect, most will result in certain networks failing to work correctly, or excess capacity being required. For example your proportional loading would require excess capacity on local services (that's not to say there isn't merit in your suggested strategy, but processing power required and time to code would have to be factored in also).

prissi

But if passengers accumulate, then capacity is missing between C and D, no matter what. In such cases always passenger will accumulate.

Sarlock

Your easiest solution would be an express train from C to E that skips station D.  If you are servicing E with only one train, you could set up an alternating local/express service that runs C-D-E-D-C-E-C.  This will ensure that the passengers going to/from E will be serviced as well as any passengers wanting to go to/from D & E.
Current projects: Pak128 Trees, blender graphics

Fifty

If you put a wait for load on the B-C-D-C Train at station C, you should be fine: the train handling the full line will continue, pax will load onto the shorter train, and when it leaves, the train running the longer route will have more pax for the termini. You might need another platform, though,
Why do we park on the driveway and drive on the parkway?

dennosius

#5
Thanks everyone for your answers.



Quote from: kierongreen on December 30, 2012, 08:41:14 PM
The reason this was chosen was to deal with the following situation:

Sometimes solving one problem makes another occur :) I still think that the problem you describe would not be that bad if there's enough capacity on the express line. Furthermore, this is not a classic network. Those lines do sometimes exist, but local trains usually operate in straight lines crossing at the center, the distance train station. This could also be solved by letting pax prefer a train with less stops to the destination.

Anyway, my suggestion would be making this an option in the simuconf file wheter I want proportional or first-stop-first-served-loading.

Quote from: prissi on December 30, 2012, 10:18:28 PM
But if passengers accumulate, then capacity is missing between C and D, no matter what. In such cases always passenger will accumulate.

No, as I explained, there's enough capacity between C and D. But pax for D are picked up by trains to E and C-D trains are running half empty. With the direct connections between each stop, I needed around 20 trains for the whole network and it worked perfectly, now I have 36 and it doesn't.

Edit: I understand that my new network (compared to direct connections only) necessarily causes overhead, because no concept can be as efficient as direct connections. But Simutrans' logic makes the overhead unnecessarily large.

Quote from: Sarlock on December 30, 2012, 10:29:58 PM
Your easiest solution would be an express train from C to E that skips station D.

Yes, that could solve the problem, but it's not nice nor realistic. Again, E is a smaller town. A realistic train network would - as I did - not have direct trains to E in this case.

Quote from: Fifty on December 31, 2012, 01:10:32 AM
If you put a wait for load on the B-C-D-C Train at station C, you should be fine:

That is what I actually did to fix it: I added another platform with a queue track and wait-for-load-trains from C to B and D. It somehow solves the problem, but I consider this a dirty work-around. And it does not fully solve my problem, as my network is actually more complex than my simplified example:


                    /-E--F--G--H
A--B--C--D--Airport<--I-/ \-J
                        \-K

So I'd have to add more wait-for-load-platforms at the airport, but there's not much space left and it's not nice.

kierongreen

If we go back to the original example, of two routes, one C-D and one C-D-E then we can calculate the optimum strategy for train services (you can skip to the end if you just want a summary). My calculations are based on a simple network - complex behaviour can quickly emergy in large networks so the only way to be sure how a particular method worked would be to implement it.
---
I assume that 4 times as many people want to travel to D as to E, that 100 passengers are generated per cycle for D and 25 for E.

If a train arrives every 8 cycles for each route (i.e. equal frequencies) then there is the following table (assuming all passengers are carried):

Waiting D Waiting E Travelling D Travelling E
200       50     
300       75     
400       100     
100       125       400   
200       150     
300       175     
400       200     
100       25        400   200
200       50     
300       75     
400       100     
100       125       400   
200       150     
300       175     
400       200     
100       25        400   200

In this example trains on route C-D should be 2/3 the length of those on route C-D-E if there is to not be excess capacity. Incidentally, this is the same whether we have existing code or proportional loading.

Maybe having different length units is not convenient, to avoid having wasted capacity we would want loadings like this:

Waiting D Waiting E Travelling D Travelling E
300       50     
400       75     
500       100     
100       125       500   
200       150     
300       175     
400       200     
200       25        300   200
300       50     
400       75     
500       100     
100       125       500   
200       150     
300       175     
400       200     
200       25        300   200


This doesn't happen with existing code though - passengers for D have priority so the number waiting for E builds up:

300       50     
400       75     
500       100     
100       125       500   
200       150     
300       175     
400       200     
100       125       400   100
200       150     
300       175     
400       200     
100       225       400   
200       250     
300       275     
400       300     
100       225       400   100


Would proportional loading solve this? It turns out that it does, eventually, ending up with the following loadings:

300       116     
400       141     
500       166     
100       191       500   
200       216     
300       241     
400       266     
200       91        300   200
300       116     
400       141     
500       166     
100       191       500   

That is, the number of passengers waiting for E has to build up  to a certain level before they will be transported, but it doesn't get out of control at least.

If you change the scenario so that routes are C-D-E and C-E, with 4 times as many passengers travelling to E as to D then proportional loading works in the same fashion, however the existing simutrans code actually works slightly better, with passengers having to wait less.

---

In summary - the existing code works as long as you are flexible on the length of each train (or are willing to tolerate empty capacity on some services). Proportional loading is more robust at balancing loads across trains, but at the expense of more waiting passengers in some situations.

Sarlock

You see, the citizens from city D are much larger and prone to violence than the passengers for city E... so when the train stops to pick everyone up, the city D citizens bully the citizen E people out of the way and fill the train and the poor city E citizens are left out in the cold waiting for the next train... where the same issue happens again.  Best to give those poor undersized people from city E their own direct train service ;D
Current projects: Pak128 Trees, blender graphics

Roads

Not to be smart alecky - not meaning to be at all - but for me the best course of action in a game as complex as Simutrans is to look at all possibilities that exist - not what you would like it to be.  Sometimes you will find something even more interesting than you originally had in mind.

dennosius

Quote from: kierongreen on December 31, 2012, 06:35:10 PM
In summary - the existing code works as long as you are flexible on the length of each train (or are willing to tolerate empty capacity on some services). Proportional loading is more robust at balancing loads across trains, but at the expense of more waiting passengers in some situations.

Sorry to say, but your calculation is right only in theory under lab conditions. What you calculated is pretty much what I calculated myself (I used frequency instead of train length, but wouldn't mind 1/3 empty trains).

In practice, this does not work at all, because there is absolutely no way to predict in which order the C-D and C-D-E trains operate at C. What we can calculate (what I did by measuring travel durations between stops) is a statistical frequency which we can multiply with the capacity (in other words: For the same frequency, we need much less C-D trains than C-D-E trains, because travelling C-D-C is much shorter than C-D-E-D-C). But we can in practice never predict what train will operate at C next.

Also, Pax at C are not really generated consistently. It's an airport. Sometimes, two A380 have landed between two train departures, sometimes one and sometimes none. So even if the D:E ratio was consistent in each airplane, we don't know whether the ratio of waiting passengers for D has risen since the last train departure (because an airplane landed with more pax to D) or dropped (because no airplane landed and the last train took preferred passengers to D).

Each time when the C-D-E train comes in the "wrong" moment when many Pax for D are waiting, the whole cycle is wasted.

Without (unrealistic) wait-for-load trains, the only way is to have all trains operating to D and E (then, it doesn't matter where passengers want to go, if the capacity meets the total arrivals at C) or way too many operating just to D to minimize the chance that the C-D-E train picks up too many Pax for D. Both is a waste of capacity.

Just to look at it from the other side:
- I have no problems with capacity in D. Trains leaving D (in either direction) are almost never full.
- I have no problems with capacity in E. Trains leaving E are really never full.
- I do have problems with capacity in C. This means, that the whole problem obviously must be the loading logic in C.

Quote from: Roads on January 01, 2013, 02:51:03 PM
Not to be smart alecky - not meaning to be at all - but for me the best course of action in a game as complex as Simutrans is to look at all possibilities that exist - not what you would like it to be.  Sometimes you will find something even more interesting than you originally had in mind.

I just want to have a realistic simulation. Of course, computer games have limitations in realism, but this one is wilful. There are other possibilities, of course. As I said, I had direct connections from C to D and from D to E before, which worked fine. But is is not nice for Pax having to change at D. And I have wait-for-load trains at C to D now. But that's not realistic, because passenger trains don't wait at stations for load, and a passenger to D would in reality rather not enter this train and calmly wait there while the C-D-E train operates. The realistic (and calculable) solution is what I have: a train C-D-E-D-C that skips the smaller E from time to time.

kierongreen

QuoteI just want to have a realistic simulation.
A realistic simulation is very difficult to achieve - to do this you have to not only consider the current train which is stopped at a station, but every other train that could carry a passenger to their destination. Passengers then have to "know" whether it is better to get on the current train, or wait, factoring in whether there will be capacity on other services to accommodate them, and how long each service is likely to take to get them to their destination. As well as being more complicated to code this is slower to run. Simutrans-experimental tries to do more complicated routing and it is one of the major reasons it is slower than standard simutrans. Even with the more complicated routing there are still situations where the routing doesn't behave in the way anticipated.

QuoteSorry to say, but your calculation is right only in theory under lab conditions.
I didn't claim otherwise. In fact I specifically said the only way to find out how this would work in game would be to code it.

Features do not get added to trunk because they are coded, they get added because they will improve the game for players. Therefore before starting coding on a feature it makes sense to have a good idea that it is likely to improve how the game works. I showed my calculations so that there was evidence to substantiate my summary, that is that proportional loading would result in a more robust handling of passengers, but at the expense of a manageable increase in waiting passengers in certain circumstances.

It is important to have evidence to support any changes to simutrans. In a few simple cases it is obvious but more often this must be researched - this isn't just limited to your suggestion; bugfixes should show they have fixed a problem, optimisations should be supported by benchmarks, new graphics code should have screenshots so that people can judge whether they think this is an improvement, so also more complex routing should be supported by calculations to show it will actually improve routing and that the performance hit will not be too great.

As far as I'm concerned there is a case for investigating proportional loading, and I might well try coding it. But it will then need to be run on various (large) games to see how it actually affects real games before being added to trunk.

dennosius

As I initially pointed out: Under certain circumstances, specific loading logics are more efficient. Actually, in the scenario we are discussing, it would be most efficient to have the passengers for the last (and not first) station loaded first. If it's impossible (or not implemented) to find the right principle, it's the best to use an average one - which is proportional loading. The disadvantage for the scenario discussed here is at least as big as the advantage in the scenario the current Simutrans logic was made for (A-B-C-D with big stations at A and D and one fast A-D and one regional A-B-C-D train). It's pretty easy: Whenever the smaller destinations come before the major destination, the current first-stop-preferred logic works better. Whenever the major destination comes before the smaller destinations, it messes things up.



kierongreen

I thought ages writing a reply but I realised there really wasn't any point trying to convince you. Even taking into account proportional loading being more flexible it's still debatable whether it is better overall than first-stop-loading. You think it is, but for example, circular lines most definitely would be adversely affected by proportional loading. Actually if you have sufficient excess capacity then any loading strategy is fine, it's only when you have little or no excess capacity you run into problems. So the simplest option for you is to increase capacity on the line.

In terms of code though we actually have several options here:
1) Keep existing code
2) Change to proportional loading, if someone codes it
3) Have an option in simuconf
4) Give players ability to choose which method of loading - either by stop or by schedule, or by both.

1) is the simplest, and as such most likely option by far
2) will improve the game for some players, but will also result in complaints
3) will get unnoticed by most people
4) is the compromise option which results in an ever more complex GUI

I am looking into coding a proportional loading routine, however as I've already stated this by no means guarantees it will be incorporated into trunk.

dennosius

Quote from: kierongreen on January 01, 2013, 09:25:43 PM
I thought ages writing a reply but I realised there really wasn't any point trying to convince you. Even taking into account proportional loading being more flexible it's still debatable whether it is better overall than first-stop-loading. You think it is, but for example, circular lines most definitely would be adversely affected by proportional loading.

You are right. But I think the loading logic is the wrong point to address this. If we have a too high number of Pax at a station (or bus stop or where ever) that WANT to enter the vehicle, then everyone has a proportional chance to get on in real life. This is not debatable, is it? So the point to address issues would be whether Pax WANT or DON'T WANT to enter. In a circular line, a Pax for the next stop in real life would not enter the bus in the wrong direction and go all the way, even if the bus is half empty. So it should be a matter that has to be solved in routing logic and not in loading logic.

QuoteActually if you have sufficient excess capacity then any loading strategy is fine, it's only when you have little or no excess capacity you run into problems. So the simplest option for you is to increase capacity on the line.

The overhead required by this loading logic is excessive. As I said: If I have all my trains serve E and have enough trains to pick up the whole number of Pax at C, then of course everything is fine. But each train will be 75% empty between D and E. Of course, one doesn't have to care, there's enough money and everything. But the fun of the game is making transportation efficient, isn't it?

Quote
2) Change to proportional loading, if someone codes it
Shouldn't it be in there? I think proportional loading was there before and is still there for freight?

Quote
3) Have an option in simuconf

Yes, definitely. Although many people don't use simuconf, dropping a loading logic wouldn't be necessary.

kierongreen

Simutrans has no way of determining which line passengers or goods should be routed over. It routes between stops, and providing a line serves the destination or via stop for a packet it will travel along that line. Hence packets can travel either way round a circle - currently the first-stop-loading means that packets automatically travel the right way round a circle (unless there is excess capacity).

Simutrans has never had proportional loading as such. Currently the code loops over waiting goods/passenger packets starting with nearest stop and proceeding until the last stop on the line. In the past there was no ordering by stop, hence packets were just processed in an effectively random order (when goods are added to a halt simutrans first checks for 0 entries in the ware list, and if there are none it adds an entry, this means that goods arriving at a halt can be added at the start, middle or end of the ware list). Roughly speaking this would have given a form of proportional loading but by accident rather than design. Making sure it is truly proportional would need new code, removing halt sorting would be quicker and require much less coding but would result in rather random behaviour.

dennosius

Quote from: kierongreen on January 01, 2013, 10:10:40 PM
Simutrans has no way of determining which line passengers or goods should be routed over.
I know, but that's not a principle, is it?

As I understand the routing logic, Simutrans knows which stations are connected to which (probably for each type of freight). This is (again, I'm guessing, but cannot think different) calculated by using the lines (and vehicle schedules). The only additional information that would need to be stored in memory is the line and the number of hops (maybe with a factor, so bus hops count more than airline hops). When there's another line connecting two stations with less hops, the line information is overwritten. And then, loading checks this information (or maybe the information can be attached to the 'packet' of freight).

This would solve all problems: In circular lines, Pax would not travel the wrong direction (and really not and not just not likely). And Pax would prefer the fast train over the regional train.

What does simutrans do with the hops, by the way? There's a max hops setting in simuconf, that I always wondered what it was good for (not the option as such, but what simutrans is calculating with hops).

kierongreen

Hops is number of transfers, not number of stations passed through.

Unfortunately routing all passengers via the line with fewest stops isn't necessarily the solution. If one train has no stops and the other 10 you would always take the one with no stops, but what if one has 5 stops, the other 6 - then it gets a bit more complicated. Also if there were two lines with the same number of stops you'd want passengers to take either... So storing one line to take for each destination/via station is not the way forward. simutrans-experimental went down the route of more complex routing and as I previously mentioned, it resulted in passenger routing taking much more CPU time.

Iluvalar

Right now, all this talk make me consider a weighted pseudo-random distribution. That would consider :


*Distance/maximum speed
*Number of lines avalaible
*Amount of people waiting
*Number of transfer


To take the above exemple (C-D-E vs C-D). The distance would make the pax going to D enter first in both trains if they have the same speed. But, the amount of line avalaible would make the pax going to E "push" some of the Ds from the C-D-E train. If nobody is waiting, the result would be a 50-50 distribution in the C-D-E train.


However, if the train C-D-E do not take all pax to E. The waiting amount of pax for E would increase and the amount traveling in that train would then increase proportionally until all the network find an equilibrium.


Pro : This seems to find equilibrium with good results in all the scenarii I can imagine. It will also look pretty much "natural".
Con : As it is a random distribution, there will always be some fraction of stubborn pax that refuse to do what you want them to. Like one passenger that en up going the wrong way in a circle pattern (only to see the country  ;D  ). thankfully they would be a minority. The problem could also be minimized by increaseing the power of the weight ( W^2 or W^3 ). Which would reduce greatly the number of those.

Ters

Another con is increased processing demands, perhaps also memory.

dennosius

#19
All this makes sense, somehow, but will probably not happen in the near future (or only in experimental). Circular lines are indeed an issue. If there's no (easy implementable) way for Simutrans to discover what a circular line is and apply a different loading logic automatically (would not be that complicated: a circular line is a line that has no stop twice - this also applies for point-to-point lines, but loading logic doesn't matter for those), capacities on circular lines would become an enormous problem with proportional loading.

Thinking about it, I like the idea to set the loading logic in the schedule (by stop doesn't make much sense, as there can be and at central stations usually are circular and non-circular lines). Either by a checkbox 'circular line' (people that like to may still 'abuse' it for the regional train case to make things easier) or by a drop-down-box that could also include last-station-first-served (which makes things unrealistically easier for my case, just as the current loading for the regional train case).

Edit: And I promise: If who ever invests his time to code this, I'll invest my time to document this in the Wiki in German and English. Also because my question was (as far as I can see) not documented there, although loading logic is an important factor for network planning.

Ters

Mostly, but not strictly circular lines can have a stop twice, like A-B-C-D-C-E-A or A-B-C-D-E-F-C-G-A (figure 8). Do they benefit from circular logic, default logic, or something unique to them? There are lots of possible layouts that must be taken into account.

Iluvalar

Quote from: Ters on January 02, 2013, 02:05:27 PM
Another con is increased processing demands, perhaps also memory.
We already have distance and maximum speed avalaible on a per convoy basis. The remaining must be already polled to figure the pax that jump into the train.

As I conceive it, it would demand only a couple more multiplications. I dont believe it would be anything as demanding as the pathfinding itself or such.

kierongreen

It would, it really would. Even a 'simple' calculation like working out how many passengers are waiting for a line at a particular station may take a few milliseconds. Doesn't sound like much but multiply that by many lines and many stations and the processing requirements quickly become too great.

Ters

Quote from: Iluvalar on January 02, 2013, 09:32:36 PM
We already have distance and maximum speed avalaible on a per convoy basis. The remaining must be already polled to figure the pax that jump into the train.

As I conceive it, it would demand only a couple more multiplications. I dont believe it would be anything as demanding as the pathfinding itself or such.

AFAIK, the only thing that is currently read is which stations the currently loading train stops at. Once the game needs to start taking other trains into account, the game needs to operate on a much bigger data set, and the cost of that isn't so much dictated by the calculations done on them, as that the game must find those trains and load them from RAM into the CPU.

Someone has to actually write an implementation and measure it to see if it's just wasted work or not, though.

dennosius

#24
I think Simutrans does the calculations already in routing (correct me if I'm wrong).

When you connect a factory (or whatever) to two stations and connect one to the destination with a bus line with 5 stops and the other one with a direct bus line, pax would take the latter one. Simutrans calculates with the number of stops and even weights the type of transport (airplanes preferred over trains preferred over buses) and the number of transfers. This just doesn't work within the same station, because the routing calculation is not connected to (or stored for or accessed by) the loading mechanism.

Quote from: kierongreen on January 01, 2013, 10:42:03 PM
Hops is number of transfers, not number of stations passed through.

Then, documentation in simuconf is wrong:


# Max number of steps in goods pathfinding
# This should be equal or greater than the biggest group
# of interconnected stations in your game.
#
# If you set it too low, some goods might not find a route
# if the route is too complex. If you set it too high, the
# search will take a lot of CPU power, particularly if searches
# often fail because there is no route.
#
# Depending on your CPU power, you might want to limit the search
# depth.

max_hops = 2000

# Passengers and goods will change vehicles at most "max_transfer"
# times to reach their destination.

max_transfers = 9


Quote from: Ters on January 02, 2013, 06:47:39 PM
Mostly, but not strictly circular lines can have a stop twice, like A-B-C-D-C-E-A or A-B-C-D-E-F-C-G-A (figure 8). Do they benefit from circular logic, default logic, or something unique to them? There are lots of possible layouts that must be taken into account.

There's obviously another loading principle in simutrans: Freight is not loaded for destination if vehicle stops here again before destination. This should of course be kept. And this makes half-circle lines work. 8-lines need both. So definition could be "circular lines are lines where no or one stop occurs more often than once". This also applies to point-to-point lines (loading principles don't matter for those), triangular lines (doesn't matter either for the usual use cases) and half-circles (it's okay for them).

I also think that the effect on circular lines may be over-estimated. Because loading and the transfer station prefers pax for the earlier stops. But there, pax will be unloaded which frees room for pax heading towards the transfer station (which should go the other direction); they'll be loaded last, but if the amount is equal (which it statistically should be) and the frequency on the line not very high, they'll be loaded. So on circular lines, only pax travelling within the circle benefit from the logic and not pax to/from the transfer station within the circle, which should usually be the majority.

prissi

The routing only take into account the number of stops. Transfer stops count as 8 normal stops, the mode of transport is not considered. At a station each passenger only know their destination and their next stop. Not line/convoi information is stored. (Considering that millions already travel on average maps, you do not want to increase this).

If you look at how real life works: People will try to get on whatever train goes first into their direction. Shear probability will result (in overcrowded situations) into something like "proportional loading". Thus I am no saying you are wrong, but this proportional loading will (in the far more common situation A-B-C-D-E and A-E) more likely produce the situation that local and express line are not treated differently, i.e. both loading mostly for E and A and starving intermediate stops.

dennosius

#26
Quote from: kierongreen on December 31, 2012, 06:35:10 PM
If we go back to the original example, of two routes, one C-D and one C-D-E then we can calculate the optimum strategy for train services (you can skip to the end if you just want a summary).
Sorry, I recalculated your figures and they are not just wrong because under lab conditions, but wrong in substance. I think it's because you didn't take the time momentum into account properly.

Let me show you my calculation (again, lab conditions and just looking at getting the pax from C to D and E, not back and not between D and E).

We have 1.000 pax/month in C for D and E (and the same amounts in the other direction), of which 800 (4/5) are for D and 200 (1/5) for E. Let's assume a convoy capacity of 200.

For easier calculation, we also assume that distances between C and D and E are all equal (let's say 50 tiles each) and a train goes 100 tiles/month.

So the starting point is:
We have 5 trains/month leaving C and going all the way to E. The distance for each train is 200 tiles, so we need 10 convoys for this. Over-capacity is 800 between D and E, so on 100 tiles, makes a over-capacity of 80'000 units ('tileseats per month').

The required tileseat capacity is 800*100+200*200=120'000. The 5 trains offer 5*200*200=200'000. The difference of course is the 80'000 again (makes 40% over-capacity).

I claim that the (technically, not gameplaywise) best loading strategy here would be the other way round than it is, so last-stop-first-served. We could only have 1 of the 5 trains a month going through to E ('E-train') and 4 of 5 just going to D ('D-train'). Statistically, there are - at each train arrival - 160 pax for D and 40 for E. Again statistically, there will always be 200 pax for E waiting when the one E-train arrives (at least from the second cycle on), and so it will not take any passengers to D. The 160 D-pax that this train leaves are well distributed to the four D-trains (next cycle). This way, all trains are always full, over-capacity is zero.  D-trains only go 100 tiles, so we need 4 convoys for them, and the E-train still goes 200 tiles which requires 2 convoys of them, so we need 6 convoys instead of 10.

Lets try the same with proportional loading: Having 1 E-train and 4 D-trains a month. Again, statistically there are 160 pax for D and 40 for E at each train departure. So, D-trains go 20% empty in the first cycle. When the E-train comes last in the first cycle, there will be 160D:200E Pax waiting, so the train would load proportionally 89D:111E, leaving 71D and 89E. The pax to D will easily be picked up by the four other trains in the next cycle. But pax to E will accumulate, so the E-train will load more and more of them, but never 100%, because there will statistically always be 160 new Pax to D when it departs (unless there are so many pax for E that rounding leaves zero to D on the E-train, but we don't want so many waiting). Anyway, we see that a half departure to E would already solve the problem. We just set up one more convoys on the E-line, so 3 instead of 2. Together with the 4 E-trains, it makes 7 convoys. Tileseat capacity is 4*100*200+1.5*200*200=140.000, making only 20'000 overhead (14%), which is perfectly realistic (will be around 20% under non-lab-conditions).

Now let's try again the same with the current first-stop-first-served logic (one departure on the E-line, four on the D-line): There are always 160 new pax to D when the E-train arrives, which will be loaded first. So there will always be only 40 Pax carried to E. As the E-train only serves C once a month, there will be 160 pax/month left for E, while all D-trains are 1/5 empty. There will statistically always be new Pax to D, so we need more E-trains, just as with proportional loading. So let's add the half monthly service to E, just as in the proportional calculations. So we have 5.5 departures/month, which leaves 145 D-pax for each train which again leaves 55 seats for E-pax in the E-trains, but we need 200/1.5=133. To have 133 free seats, statistical average for D-pax must be only 67, which requires in total 10.5 D-trains (800/67-1.5)! So this is evidently worse than just having all trains operate do E (requires 13.5 convoys)!

Let's try the other way round and add more E-trains instead. Now, we don't add a half E-line-service per month, but one full E-line services to have 2. So required capacity for E is 200/2=100 in each E-train, leaving 100 for D. We now have 6 services/month, which means 133 new pax to D for each E-train. Too many. We need 6 D-trains (800/100-2). So it works, but 6 D-trains plus 2 E-trains/month requires 10 convoys, so nothing saved. Maybe add another E-train? Required capacity would only be 67 to E (200/3), leaving 133 for D, making 6 D-trains necessary (800/133). But it's 12 convoys.

In other words: Under lab conditions, the best possible result of not having all trains go through to E is as bad as having all trains go through to E. Under practical conditions, the result will always be worse.

Quote from: prissi on January 04, 2013, 04:16:14 PM
If you look at how real life works: People will try to get on whatever train goes first into their direction. Shear probability will result (in overcrowded situations) into something like "proportional loading". Thus I am no saying you are wrong, but this proportional loading will (in the far more common situation A-B-C-D-E and A-E) more likely produce the situation that local and express line are not treated differently, i.e. both loading mostly for E and A and starving intermediate stops.

First of all: aren't you contradicting yourself? If people try to get on whatever train, why shouldn't they get on the local train in your example? I also question that this was 'far more common'. Local trains usually do not operate between major stations, but they usually cross one.  Almost all subway, tram and local train networks I know (plus city and regional bus networks) build on this principle (sometimes with additional circle lines or other connections, but in core). If local trains operate between major stations, it's where population is very dense. But in this areas, pax (i.e. commuters) do use the local trains, just because they're cheaper.

kierongreen

#27
In simutrans passengers for a stop served by both local and express routes will get on the local train if there is capacity available. So prissi was correct and was not contradicting himself. I would suggest if you think proportional loading is a priority you create a working patch so that the benefits and drawbacks in gameplay and performance can be evaluated.

dennosius

Quote from: kierongreen on January 05, 2013, 02:13:43 AM
In simutrans passengers for a stop served by both local and express routes will get on the local train if there is capacity available.

Prissi was referring to real life, but I may have misunderstood him. And in Simutrans, this only works in a A-b-C line (caps are express train stops). In a A-b-C-d-E line, it again wouldn't. So in non-circular lines, the one and only use case for first-stop-first-served is any number of regional train stops in between exactly two express train stops. And in this use case, the loading logic minimizes overhead unrealistically (as I showed above, just the other way round; the overhead is theoretically zero).

Quote from: kierongreen on January 05, 2013, 02:13:43 AM
I would suggest if you think proportional loading is a priority you create a working patch so that the benefits and drawbacks in gameplay and performance can be evaluated.

I'm not saying anything is a priority. But I again want to summarize the result of my calculation above:

Whenever lines serve a smaller destination behind a larger destination (A-B-c, but not limited to Pax, also delivering glass to an electronics factory behind a brewery in Pak128 could be another example, as the brewery needs more glass), there is no way in Simutrans to reduce the overhead by having some convoys serve A-B-c and some only A-B (neither works with the same convoys alternating in schedule, of course).

Because no matter how many convoys serve A-B-c or A-B, it needs exactly as many convoys (capacity) as having all convoys serve c (under lab conditions, in practice it'll be always better to always serve c). And this is not realistic and the only reason for it is the loading logic.

Am I the only one that finds this problematic? Having only some convoys serve c is at least one of the obvious and realistic solutions. So it should be possible (ad reduce overhead and not create additional one, practically). Of course, the problem can be worked around. One can just bare the overhead and have all convoys serve c, or create point-to-point lines (A-B, and B-c or A-c). But a simulation game should try to make it possible to take all obvious realistic steps in planning, shouldn't it?

What is a working patch and how do I create it? Is there any chance it'll be successful, if noone of the experiences guys here seconds it?

kierongreen

A patch is a list of changes to the source code. You'll need to download the source code, make the changes required (you'll be wanting to look in simhalt.cc and simvehikel.cc for the vehicle loading routines). Once you have got the loading working the way you want you can then generate a patch file which other people can apply to the sourcecode on their computer. If the loading works well in a wide range of situations, can be shown to not adversely affect existing games, and doesn't require much more cpu power then it should get into trunk fairly quickly. Even if it doesn't you still have the patch file and can use this to make versions for your own use that have this loading. You can even distribute your version should you so wish.

dennosius

Ah. I thought I made clear that I can't code. I promised to document the loading in the Wiki in German and English if someone who can code takes his time to do so.

prissi

I still fail to see why proportional loading will work better in the A-B-C-D-E and A-C-E situation? It will starve at least B/D more of transport capacity than loading for next (B/D) first. Proportional loading is only required, if the busiest point is not the terminus of a line. However, most simutrans games I have every seen build automatically lines which terminate at major hubs.

dennosius

#32
Quote from: prissi on January 06, 2013, 11:12:55 PM
I still fail to see why proportional loading will work better in the A-B-C-D-E and A-C-E situation? It will starve at least B/D more of transport capacity than loading for next (B/D) first. Proportional loading is only required, if the busiest point is not the terminus of a line. However, most simutrans games I have every seen build automatically lines which terminate at major hubs.

You mean, if you leave out stops in the middle rather than at the end? In this case, it depends what you call "working better".

The current loading makes it unrealistically easy to leave out stops in the middle, because - as I have proven in the calculation - it reduces overhead to zero (theoretically under lab conditions). If 'as easy as possible' is 'working better' in your eyes, then it isn't any better. But then, last-stop-first-served should still be (optionally) integrated for lines that leave out stops at the end, because they'll be easier with that.

In the A-b-C-d-E case (I use small caps for stations that are sometimes left out), some Pax in Real Life would take the A-B-C-D-E train, even if they want to travel from A to E. If it's the same train class, just because it leaves earlier and will arrive earlier, although it stops in B and D. If it's a lower train class (regional train), just because it's cheaper (Simutrans would even simulate this by the speedbonus, if implemented in pak; also, even a slower train can arrive earlier if it departs much earlier, so there are good reasons for some people to take the regional train in this example).

What we had ages ago through the random loading (any packet was loaded that was in memory first) was not proportional. Of course, random loading is statistically proportional, but only after a long time, but (usually) not during one 'cycle' of trains arriving. This caused much overhead. True proportional loading would work just fine. Just set up A-C-E trains a little bit below the necessary capacity and A-B-C-D-E trains slightly above the necessary capacity. It depends on the actual case, but in practice it'll require around 15 to 20 percent more capacity on the A-B-C-D-E line than now.

The balancing under non-lab conditions is a bit tricky (but realistic). Because if pax for B and D queue up, the first thought then is: If pax queue up for B and D, I need more A-B-C-D-E trains. But more probably more A-C-E trains would solve the problem, as they free up capacity in the A-B-C-D-E trains for pax to B and D (the more pax the A-C-E trains take, the less A-C-E pax go on the A-B-C-D-E trains, leaving more space on those for B/D pax).

The two cases (leaving out stops in the middle or at the end) are two sides of the same medal. Mathematically, the current loading is optimized for leaving out stops in the middle, for the cost of making it unattractive (useless) to leave out stops at the end (because there's no way so save spare capacity/resources). If the loading logic was the other way round (last-stop-first-served), it would be just the other way round, leaving stops out at the end would produce unrealistically low overhead, and leaving stops out in the middle would become useless.

Again, this is the mathematical way of seeing it. But Simutrans should not optimize loading mathematically, but realistically. If any railway company in real life could steer their customers' behaviour as Simutrans does, they'd be well off (or bankrupt, if they leave out stops at the end ;) ). Realistically, if there are more pax waiting for a train than the train can take, then everyone has an equal chance to get in (as long as Simutrans doesn't know who is the grandma that uses her handbag as a weapon).

Another way of explaining it without maths, but with pure logic is: What the current loading does in circular lines is simulating (or imitating, as good as possible) the 'will' of the pax not to travel the circle in the wrong direction ('not' here always means: only last). What it does when stops in the middle are left out is simulating the will of the pax that could use the fast train not to take the regional train (that will is - at least as absolute as simutrans does it - not even realistic, but with proportional loading, the will will follow the capacity offered, which is much more realistic: the more fast trains go, the less pax will choose the regional train for a fast train destination). Now, what the loading logic does when some trains leave out stops at the end: It simulates a will of the pax to the minor destination at the end, not to enter any train - and this of course doesn't make any sense and leads to bad results.

As we are talking about circles: The argument that lines that leave out stops at the end are less common is a closed circle argument. Something that doesn't work can't be common (maybe regional trains between major stations are only much more common in Simutrans than in real life because those are easier manageable than in real life). Anyway, we do agree that serving a later stop with only a portion of the vehicles is a standard measure in planning and operating transport networks, don't we? And a transportation simulation game should not prevent standard measures of transport operations, should it?

By the way, proportional loading also works better on any straight line, let's say A-B-C-D-E. The required capacity is in any case determined by the largest demand on the line, but if capacity is too low, the 'right' pax would queue up at the 'right' stations, and not all the pax for the last station (A and E). Apart from being unrealistic, this causes problems when you solve the queue by adding more trains, because the number of waiting pax can already be large and cannot be distributed further at A and E, giving wrong impressions of pseudo-under-capacity of local distribution lines at A and E.

Except for circular lines (current logic should be kept for those), proportional loading is realistic, reliable and calculable. All kinds of lines are well manageable with proportional loading, while lines that leave out stops at the end are currently unmanageable (at least if it's a bit more complex than just A-B-c, like in my case where I recognized this it's rather like a-b-C-D-E-F-G-h-i). Proportional loading would allow more realistic and complex lines and open up more opportunities for players to optimize lines.

yoshi

Let's assume following trains with capacity of 500 passengers each;

Train 1 serving A-B-C-B-A
Train 2 serving A-B-A

If there are 500 waiting passenger going from A to B and 500 waiting passengers going from A to C,

Case 1
With the current loading logic, train 1 takes 500 passengers to B, then no passenger will be carried by train 2.
There will be still 500 waiting passengers to C.

Case 2
With the proportional loading logic, train 1 takes 250 passengers to B and 250 passengers to C.
Train 2 carries 250 passengers to B.
There will be 250 waiting passengers to B.

In this case, proportional loading works better.
But of cource, the current logic works better if there is an express service serving A-C-A, as local trains don't carry many passengers going to C.


My conclusion: There is no perfectly realistic logic, as Simutrans passengers don't know the train timetable or train frequency or best connections to their destinations. Players should build a network which works best with the current logic.

dennosius

Your calculation approach is insufficient, because it disregards the time momentum.

Anyway, your result is just like what I said, but only, if "better" includes irrealistically easier. As I also said, "last-stop-first served" would work (mathematically) even better than proportional for the case you calculated, but it would still not be a nice solution as it was unrealistic.

By the way, one more argument not to favour lines that leave out stops in the middle for the cost of lines that leave out stops at the end:

In the first case, any 'overhead' is just mathematical. So some pax will use the 'wrong' train, but they'll still travel and reach their destination. In the latter case, it's true overhead (too many trains running empty too much and pax do not travel).