Updated: Apr 6
From start to finish, best practices and practical advice for doing a simulation-based project
This post is part 3 of a 7 part series about the Simulation Model Life cycle. You can catch up on the previous post here
Life cycle of a simulation model
Building the Model
Analyze the Results
Report on the Findings
This post focuses on the third step and future posts will focus on the remaining steps - you can start watching the lecture from step 3 here, or continue reading the blog post.
Note: Although one does go "back" in later steps to do some activities during previous steps, you by no means redo the entire step. The steps listed above are guidelines of the general steps that a typical project follows. On all steps, you can go backward and revisit previous steps, but unlikely that you will skip a step or move forward before completing a step to at least 80%-90%.
For a more insightful discussion on the matter read here
3) Building the Model
“Model building rarely has a RIGHT answer. You need to just start DOING something and that, in turn, will reveal “next hurdles” to revisit/redo/dig deeper”
Model building is often the most consuming part of the project but also the most fun part for most model builders. This is where you can get your hands dirty, get deep into the process and make things move on a computer screen (My personal favorite!). That said there are a number of things to consider in order to be successful in this step. For this post I am only going to cover a few high-level things that all modelers need to keep in mind while building:
Gradually build more detail
Test after every feature
Test individual features
Test integration of features
If we take the retailer example, from the start of this series, I literally started building the model with only a source, a queue, a delay and a sink and then expanded from there. Replacing the queue and delay with more complex structures and then adding in additional data objects, functions, variables etc....
This is a very simple example since we only have one process, but if you are modeling a complex environment with lots of processes the nice thing about starting off simple is that the entire system is modeled from the start, although at a very high level of abstraction. This means that you have a working model that represents everything, even though at a very high level of abstraction, very early on!
Model building Pro-Tip: Split your logic and animation
Did you notice the little agent at the bottom of the screen called animation in the previous image?
The reason behind this complete separation of animation and logic is twofold:
1) Improves the performance of the editor while building the model
If you have tons of images and drawings on the canvas the editor takes a while to render them every time you move around on the canvas to navigate to different parts of your model.
I have seen (and worked on) models where if you open the main agent it takes between 10 -15 seconds for AnyLogic just to open the agent. It was a nightmare to make even the simplest of changes!
Once we removed all the animation objects into different agents it was a few seconds to open the Main agent, and after splitting all the many library blocks into different agents it was just 1-2 seconds to open any agent and work on it!
2) Improves the performance during run time
When you are in an agent during model execution AnyLogic will have to do all the calculations required for any piece of animation that exists on that agent. Many modelers think that only the objects that are visible for the user are calculated or drawn but due to the dynamic nature of the objects, AnyLogic first needs to do the required calculations to determine what is visible or not. To test this have an animation-intensive model and simply navigate away to some blank agent with nothing inside of it and see how the execution speed increases.
P.S. If you have experienced this before let us know in the comments or even share a link to your model on the cloud where you illustrate this phenomenon.
To set up the animations in a separate agent you simply move all the non-logic components to other agents, place those agents where you need them, maybe some central location, maybe close to the logic.
See the example below - or download the model at the end of the post.
When building models I always follow the following framework:
Add Feature -> Test Feature -> Integration Test -> Test Previous Features
What this basically entails is that if you want to add any feature to your model, you need to test this specific feature, test that it works with other features and then re-run all your previous tests.
Sometimes I will even create the test first, confirm that I am not getting the expected result and then continue working on that feature until I get the expected result. Usually, there is more than 1 test for every feature as I would include various parameter options for this feature as well as testing the feature with other features (integration tests) as part of my setup.
Then once I confirmed that the feature is doing what I expected, I need to check if I have broken anything else that was previously working... I do this by testing all the previous features! And more often than not there are some previous tests that fail... and I either need to make adjustments to my new feature to prevent breaking other features, or I need to upgrade those existing features to be able to cope with the new feature.
Since testing can be very time-consuming, which is probably the reason why it is neglected in most projects, you need to implement the following testing best practices to ensure it is worth the investment:
Test each feature individually
Test multiple features
Store all tests
Tests must be reproducible
Ability to run automated tests
Let's look at an example of how to do this inside AnyLogic using our example model from the previous posts in this series.
WARNING: Advanced modeling techniques ahead. You can achieve something similar but less efficient using normal experiments.
Step 1: Create a custom experiment
By using one of the more advanced features and a little bit of code you can set up an experiment that can run, without any animation, as fast as possible and you can call it from anywhere, even let it run inside a separate thread. (more on this in a future post....)
Step 2: Create Tests
Since we followed the best practice to create a data object to data-drive our model we can very easily create a new scenario object, pass it to our custom experiment, that will give it to the model and run it.
In this example, I set up the experiment inside the button, but for big models, you might want to use a Java class where you create your scenarios and then automate the running of all of them sequentially or in parallel.
This is great because all our tests are now well documented and stored ready to be used at any given time. And if we change something in the model logic that impacts our tests or the scenario the compiler will let us know and we can fix it immediately. Whereas if you test with Excel sheets you will never have known that they are not valid anymore until you try and run them again...
“Tests is a great way of documenting your model features and functionality”
Pro-Tip: Running multiple Tests one after each other.
Did you know you can use custom experiments to run almost anything you want?
How about running all your Unit tests - either set up inside the experiment or retrieved from some Java classes where you set them up. You can then very easily run them using the play button found inside AnyLogic. See example below
If you have followed everything up to this point and nothing was new, contact me for a job offer ;-)
I know this post went way beyond the basics and some of the concepts might be too much for beginners but my advice will be to try and implement the parts that do make sense and investigate those that don't. If you don't manage to figure it out, build a small model and post your question to Stack Overflow, there are a number of experts, including myself ;-), that will be ready to help.
If you want to get access to the example model from this step you can simply send a blank email to email@example.com
Looking forward to the next post on best practices for building your model?
Watch the full lecture here, the video below starts at step 3
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!