How to don’t seize resource units that are not needed? - anylogic

I’m simulating an unloading process of a ship. The complete unloading of the ship can be perfectly done with only two resources making round trips (load, move to destination, unload, go back to loading) and the ship would never be idle waiting for trucks to load.
I need to demonstrate that if I increase the number of resource units (trucks) to 3, the third one will never be seized because it’s not needed, the problem is that the seize block seizes all units evenly, so at the end, all units end up with a utilization percentage greater than 0.
How can I configure the seize block to only use the needed resources and leave the “excess” units with utilization of zero?
(The real model by default will have many resources available, and ships could need more than two trucks. What I want with this is to determine the best amount of resources needed).
Thank you.

In the ResourcePool there is an options Customize request choice which when set to True will allow Request choice condition function to be created. There it is possible to make sure that the resources taken first are the ones with utilisation > 0. If your assumption is correct then the 3rd truck will never be taken.

you just need to run two experiments. One with 2 trucks and another with three. Then compare them in terms of ship waiting time and truck pool utilization.

I solved the question in a very easy way:
In the Seize block use the option "Customize Resource Choice" with "Resource selection" equal to "Units with top rating" and "Unit rating" = unit.getUtilization().
In the way, Anylogic sorts the idle resources by utilization rating and chooses the most utilized resource, this means that unneeded resources will never be seized.

Related

Work shift scheduling with break times for specific agents

I am building a simulation model for a production line. There are two shifts (morning and night shift, 12 hours each) daily. Within each shift, the workers are split into 4 groups and each group goes for meal breaks at a staggered timing (eg. 4 workers in morning shift, first worker goes for break at 9am, second goes at 10am, etc.). These workers will also take ad-hoc breaks at random occurrences during their shift.
Not sure which method would work:
Creating an individual schedule within the agent and let it change states according to the schedule?
Use a common schedule for the entire resource pool, but will it be possible to pick which agent goes for break at the break time? Or will the agent be picked at random? Caus my concern is that i'll need the agents to take breaks but at staggered intervals.
Or should I generate this in a different approach?
Good question!
On option 2)
If you use the resource pool you will not be able to choose a specific agent as shifts and breaks are created for the entire pool.
What you can do is to define the capacity of the resource pool using, multiple schedules
This can help you artificially define the staggered. nature of the break-taking for resources.
Refer to the help for more details - https://anylogic.help/library-reference-guides/process-modeling-library/resourcepool.html
I believe this answers your question already but here are my notes on the other option.
Option 1)
If you require more advanced flexibility and control over the breaks and you do have the required Java skills (and time!) you can create custom code that controls when to send agents on a break and when to to return. You can use StateCharts inside your agents to build this logic. But then this will not be compatible with the resource pool since the resource pool will be oblivious to the state of the agents inside the pool and it will seize units that are taking a break...
So in this case your size delay and release will also be custom.
This is a lot of work and should only be attempted if you have the time, skills and require a level of flexibility and customization not offered by the resource pool.

Truck (Agent) Hitbox in process modeling library

im creating some paths with the process modeling library. The trucks shall stop in series when waiting for the "go" signal to go on.
At the moment the trucks are waiting "within" each other.
How to tell the trucks to recognize not the stopnode only but also the hitbox of the truck which arrived before him?
Thanks in advance
Chris
The trucks shall stop in series when waiting for the "go" signal to go on.
At the moment the trucks are waiting "within" each other. [...]
How to tell the trucks to recognize not the stopnode only but also the
hitbox of the truck which arrived before him?
AnyLogic allows for agents to queue along a path (from an animation perspective) whilst in a Queue block. So don't make them move to the stop-node (which I assume you are doing explicitly): make them (from a process point-of-view) go into a Queue which is animated via the path from the stop node 'backwards'. (This is the "Agent location" setting of the Queue block.) How you hold them in the queue and release them when they need to depends on the nature of your model; e.g.,
Use a Hold block following the Queue (if it makes sense to release them all at once)
Use a 'dangling' Queue block which you pull agents out of programmatically (e.g., via its removeFirst function) and then add them somewhere else in the process via an Enter block.
Use a Seize block (which has a built-in Queue you can set the location of) with the resource seized representing the 'token' you need to proceed.
NB: From the process perspective, they are in a Queue which happens to be animated as queueing along a path. This isn't exactly the same as modelling the 'spatial reality' of being in a queue: see this question.
Simple solution is to turn your truck agents into Transporters from the Material-handling library. They have build-in collision avoidance.
However, this can slow large models so you may want to convert them only when you need collision avoidance and then convert back to "simple" Truck agents again.
Else, you need to build your own additional stop-nodes and code spatial queuing manually. Possible but not straight forward

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).

Assign priorities for multiple Seize Blocks for the same resource in AnyLogic

I have a not so typical scenario for which I am not sure how to proceed:
There are two stations located at two different locations.
Both stations require the same resource.
The resource moves from station to station once released. So it keeps going from station 1 to station 2 to station 1, etc. until it is seized again. This is modeled by adding a link from the resource process port of the release block. So it is not completely released unless a condition applies. The condition is that there are agents waiting in the queue of the seize block of that same resource. So it should keep moving until it is needed again. The tricky part is that there are two seize blocks for that resource, one for each station. It is possible that agents are ready and waiting in the resource's seize element at both stations. I am adding an image of the resource's process at release. So at "selectOuput4" it checks whether station 1's seize element has agents waiting, if so, the resource is released and can be seized. Otherwise, it moves to station 2 and checks the same but for station 2.
My concern is that there might be a situation where both stations have agents waiting in their respective seize blocks. How can I make sure the resource will be seized by station 1's seize element and not station 2's, and vice versa. Is there a way to control where the resource is going in a case where two seize elements are waiting for it? Or is it always random?
I apologize for the long post, and I hope I managed to deliver my idea properly.
First, I think your design is a bit weird because you keep the resource always seized.
What I would do is first have a statechart in the resource that controls the resource movement from one place to the next so you have more control over it. The statechart would be used to move your resource ONLY when it's not seized. This will allow a case in which your resource is moving from station 1 to station 2 but something comes to station 1 queue and the resource can immediately react and come back to station 1 before it reaches station 2 (if you think it would be a good idea to do that)
The second is that the seize block defines the priority for a task when the agent arrives to the seize block, and your situation requires changing that priority dynamically, which can't be done as far as I know, so the wait block before the seize block is unfortunately a good option.

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.