Updated: Mar 16
There is a special feature when using the Select Output block (and a few others) that sometimes confuses even the most advanced users. If you use process modeling blocks or pedestrian blocks, you either have experienced it yourself or you will.
Hopefully reading this article will help you identify and resolve this issue in the future.
Let's say we have a model where a pedestrian, after moving from point A to point B, needs to choose 1 of 5 outputs from a select output and then exit. We want the pedestrians to choose randomly between the 5 possible outputs.
In our implementation after the pedestrian has made its move we sample from a distribution and save the chosen exit number to a variable, exitNumber, inside our custom pedestrian agent.
When the pedestrian gets to the select output, it will choose an exit based on the value of the variable. We will also trace out the pedestrian's exitNumber variable just to double-check if the number they stored matches the exit they choose.
We expect that when the pedestrian exits the GoTo block, it samples an exit number and then at the select output block it follows the exit based on the number sampled
But when running the model, the following happens!
All pedestrians exit out of the first exit!
Note: We are printing to the console the exit number when the agent reaches the Select Output block, and we can see that each agent has a randomly assigned exit number.
Why are all pedestrians going through exit 1 when we know that other exits were sampled?
Perhaps a bit counter-intuitively, but AnyLogic first checks where the pedestrian will go - by selecting an output from the SelectOutput block - and only then does it trigger the GoTo blocks's On Exit code. This actually makes sense, because how can the pedestrian exit the GoTo block if it has not yet identified where it will go and if it even can go anywhere? What if there is a hold block after the select output?
In short, when checking where to go next, the agent does not yet have his exit defined - it holds the default value of an integer, which is 0, until it has already decided which of the SelectOutput block's exit's to use
How to resolve this
There are a few options:
1) Define the exit variable before the pedestrian exits.
This can be done on the On Enter code of the GoTo block, or even when. You create the pedestrian, it all depends on the specific logic behind choosing an exit.
2) Do the choice of exit logic explicitly inside the select output
This is probably the most logical place to do it - but again depends on your specific model and conditions.
3) Use the On At Exit code if available
Although not available in all blocks, most of the Process Modelling Library blocks have an option to execute code when the agent is about to exit but has not yet exited the block
4) Using a hack ;-)
Place a 0-time delay just in front of the Select Output.
This is not the preferred option as it adds an unnecessary block inside your process flow which.
Please take a look at the example model here:
Or plan and download the model on the AnyLogic Cloud here
To prove others have experienced the same issue, here is a link to a similar issue experienced by a user on Stack Overflow
It is very important to keep in mind that:
If you have a select output block (or any of its variations), the decision "which exit will the agent take?" will be evaluated before the on exit code is performed
Chronologically, the model execution will be as follows:
The agent enters the block (in our example the GoTo block) and triggers the "on enter" code
After execution of the block specific action, the next block is Select Output, so the agent evaluates where to go next (in our example it evaluated the exit number variable)
The agent performs the "on exit" code (in our example it sampled the exit number)
This small nuance has even made us question our own sanity after hours of debugging, but now you know about it ;)
If you liked this post, you are welcome to read more posts by following the links above to similar posts. Why not subscribe to our blog or follow us on any of the social media accounts for future updates. The links are in the Menu bar at the top or the footer at the bottom.
If you want to contact us for some advice, maybe a potential partnership or project or just to say "Hi!", feel free to get in touch here and we will get back to you soon!