For sure, you've used the break or continue keyword in your models, as you needed to terminate a loop, or you needed to skip one of its iterations.
And then you tried doing the same with nested loops, but then everything became confusing because you need to add these keywords in multiple places, depending on the desired outcome.
Have you heard of Java labels?
Labels allow you to control which loop we want to break/continue. Let's look at an example.
Imagine you have a population of an agent called Car, and this car has many parts, some with a random probability of being defective. Now, mechanics can only service one car at a time, so you want to send them the first car that you find with a defect. In order to find the first car with at least one of these defective parts and send it to the mechanic, you could write the code as follows:
boolean carFound = false;
for (Car car: cars) {
for (Part part: car.parts) {
if (part.isDefective()) {
carFound = true;
car.goToMechanic();
break;
}
}
if (carFound) break;
}
Here we need to make use of a temporary variable carFound in order to save that we have found a car, and then we need two break statements to exit both loops
Note: If we wanted to exit this function entirely, we could have called the return; statement and it would exit the entire function. But let's assume there are some other actions below this for loop that we also want to execute in the same function.
With labels you can simply create a label before the loop you want to control, and break it when you find the defective part:
carLoop:
for (Car car: cars) {
for (Part part: car.parts) {
if (part.isDefective()) {
car.goToMechanic();
break carLoop;
}
}
}
So, the code becomes more compact and readable.
The same thing can be applied with continue keyword. Let's assume now that the mechanic can have a queue of cars waiting for it, and we now want to send all cars with defects to the mechanic. But we also want to check with the suppliers if they have stock of the defective part before we send the car, and we still want to stop assessing a specific car if we find a single defective part.
carLoop:
for (Car car: cars) {
for (Part part: car.parts) {
if (part.isDefective()) {
for (Supplier supplier:suppliers){
if (supplier.stockAvailable(part)) {
car.goToMechanic();
continue carLoop;
}
}
}
}
}
Note: If you do find yourself in complex nested for loops, it might be a sign that you need to move some of them to a different function and split your code into smaller manageable pieces
You can find the source code for the model in the references' section at the bottom of this post
What to learn more?
We have an online course for beginner to moderate AnyLogic users that want to learn how to use the Java programming language and Object-Oriented Programming principles to make better, more efficient models faster in AnyLogic.
You can check it out here
What next?
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 of 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!
References
You can download the alp file here
Or play and download the model from the AnyLogic code here
What next?
If you liked this post, you could read more posts by following the links above. 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. You can also join the mobile app here!
If you really want to make a difference in supporting us please consider joining our Patreon community here
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!
Comments