Does reducing capacity of a resourcePool at a certain time/condition make the unit immediately stop and leave the model? - anylogic

If I have a condition where a resource pool reduces capacity from 2 to 1 at a certain time of the model OR when the unit interacts with a certain number of different agents, will the unit that is being removed from the model stop what it's doing and leave? Or will it finish all of it's queued tasks? I would like it to finish all of it's queued tasks.
My code for the condition is as follows where Surgeons is the resourcePool and seizedAgents is a collection inside the Surgeon agent type:
if( unit.seizedAgents.stream().distinct().count() >= 17 ) {
Surgeons.set_capacity(1);;
}

If the capacity is dynamically reduced by calling set_capacity(), and the number of currently seized units exceeds the new capacity, the extra units will only be disposed of after they are released. The rest immediately
Thus units busy with a task will be disposed of only after completing the current task
Check the help for more details.

Related

ResourcePool.idle() is considering resources in seize blocks as idle

If an agent enters a seize block that seizes 2 resource units each of different pools, if resource unit 1 is seized by that block while resource unit 2 is not because it is currently performing another task, resource unit 1 is considered idle when I use ResourcePool.idle(). The problem with this is that in other parts of my model, when I try to set conditions based on if a certain resource unit is not idle (meaning it is busy), it considers the time that resource unit 1 is waiting for the seize of resource unit 2 as idle, when really, I would like it to be busy.
Make sure you have "Seize units one by one" checked.
Otherwise all units remain idle until one both are available to be seized jointly.

Frame collector & Out of memory errors (large memory allocations)

Task: Tasks spawn with fixed time intervals (source), each has remaining processing time which is given by uniform random [0 .. x]. Each task is processed by the module (delay). Each module has a fixed processing time. Module substracts it's processing time from the task's remaining processing time. If a task's remaining processing time depleted (less than 0), that task becomes completed reaches (sink). Otherwise it goes to the next module, and the same process repeats. There are N modules, that are linked one after eachother. If the task's remaining processing time has not depleted after processing at the N'th module, it goes to the 1st module with the highest priority and is being processed there until remaining processing time depletes.
Model Image
The issue: I've created the model, the max amount of spawned/sinked agents i could get is 17 for -Xmx8G and 15 for -Xmx4G. Then CPU/RAM usage rises to max and nothing happens.
Task Manager + Simulation Image
Task Manager Image
I've also checked troubleshooting "I got “Out Of Memory” error message. How can I fix it?" page.
Case
Result
Large number of agents, or agents with considerable memory footprints
My agents have 2 parameters that are unique to each agent. One is double (remaining_processing_time), another one is integer (queue_priority). Also all 17 spawned agents reached sink.
System Dynamics delay structures under small numeric time step settings
Not using that function anywhere, besides delay block.
Datasets auto-created for dynamic variables
This option is turned off
Maybe i missing something, but i can't really analyze with such small amount of agents. I'll leave a model here.
This model really had me stumped. Could not figure out where the memory was going and why as you run the model visually it stops yet the memory keeps on increasing exponentially... Until I did a Java profiling and found that you have 100s of Main in the memory...
]
You create a new Main() for every agent that comes from the source - so every agent is a new Main and every Main is a completely new "simulation" if you will..
Simply change it back to the default or in your case create your own agent type, since you want to save the remaining time and queue priority
You will also need to change the agent type in all your other blocks
Now if you run. your app it uses a fraction of memory

Using a shared ResourcePool for multiple Seize Blocks

I have recently started using anylogic, and I am facing a problem with a shared ResourcePool in my process flow.
I want to create a process flow that consists of 10 tasks.
Each task is modeled by Seize-Delay-Release-Blocks and seizes either one operator and an additional (task-specific) tool or a machine. Each operator is capable of processing all tasks, so there is one shared ResourcePool Operator.
The problem I am facing is that although the capacity of the ResourcePool Operator is sufficiently high enough to be deployed on all tasks in parallel, the tasks are processed sequentially. For example, the model starts with processing all parts entering task 1; if the queue is empty, task 2 is processed, and so on. In case if new parts enter the queue of task 1, again, task1 is the only one being processed.
The Seize-Blocks lock the same as follows:
Picture Seize-Block.
It should seize one of the available Workers.
Using Task Priority in the Seize-Block with increasing priority per task (task 1 lowest -> task 10 highest) does not solve this problem as capacity remains unused because tasks are processed sequentially.
How do I have to set up the model that the shared ResourcePool Operator can be used for all tasks in parallel?

Service block reduce delay time using resource pool workers

I have a resource pool and a service block. The number of the operator in the resource pool is 5 which is linked to the service block. I would like to setup the service in a way that the more workers work on the service the delay time decreases. (ex: if 1 worker works the delay time is 10 min - if 2 workers work the delay time is 5 min. - if 3 workers work the delay time is 3.33 min). I would like up to 5 operators to be working at the same time in the service block based on their availability.
Service Block and Resource Pool
How can I achieve this?
So you're trying to do two things with your Service block:
Seize a dynamic number of units (in the simplest case, seize all available units).
Have the delay time dependent on the number of units seized (in the simplest case, just decreasing multiplicatively according to the number of resources).
For the former, assuming you're seizing from a single pool, just enter a dynamic expression in the "Number of units" property. In the simplest case (seize all available) it would just be pool.idle() (for a resource pool called pool) but that's problematic if the next agent arrives whilst the first is being processed (because it will be treated as needing zero resources) so, depending what you want, you might need to do something like put RestrictedAreaStart / End blocks around your Service block so only one agent can be in the Service block at once.
NB: AnyLogic currently has a bug/limitation that the resource pool's idle/busy counts (from its idle() and busy() functions) are not guaranteed to be correct unless you are at a later simulation time than when seizes/releases occurred. (This is due to how things are resolved in hidden events under-the-covers.) So, if you want to use them in your determination of the number of resources to seize you need to work round this; e.g., by
tracking the number of busy/idle units via your own counts;
using the isIdle() function on individual resources in the pool instead (which typically requires ensuring the resource pool agents are in a custom population, not the hidden default one, so you can explicitly reference/loop through them);
something horrible and hacky like adding a very-small-timeout Delay block before entering a Service block (possibly within RestrictedAreaStart / Ends to ensure that agents don't make it into the Delay, and hence the Service block's seize mechanism, until you want them to).
In general, it makes sense to put the resources-needed calculation in a function (which returns an int and takes the agent as an argument) which you call in the "Number of units" expression. That way you can make the calculation as complex as you like; it would seem you might need a more complex consideration than just "grab everyone" (e.g., perhaps depending on the stream of to-arrive agents if you have knowledge of them, etc.). Maybe, for example, you'd also want to hold your arriving agents in a Wait block beforehand and only release them when the number of resources you want are available. (You'd need to give more precise detail about your requirements to be any more definite here.)
For the variable delay time, have an appropriate dynamic expression for the delay time; you can use the resourceUnits() function to get a list of the resource units seized by your agent. So, in the simplest case (decreases multiplicatively according to the number of resources) it would be something like 10.0 / agent.resourceUnits().size() (for a base delay of 10 time units).

AnyLogic "End of Shift" logic

I have a resource pool that adds units into the population "forklifts". The agents of type Forklift are chosen by other agents and later seized for specific tasks. There is also a schedule for the resource pool.
The problem is that whenever capacity decreases, forklifts units that are moving in the model (but not seized yet) are halted because they are no longer active. Is there a way to customize the choice of resources for the "end of shift". I cannot find anything in Help or online.
Thanks!
I have tried iterating through the resource pool but there is no function I could find to determine whether a unit is active or not. There are boolean functions for idle and busy.
agent.unload_forklift = findFirst(forklifts, f->f.in_use == false);
There are agents that choose resource agents based on internal variables. Maybe I could iterate through the resource pool instead of the population...
I expect forklifts' capacity to decrease based on a customize signal not randomly.