Assigning certain agents to a certain resource unit based on source - anylogic

I currently have 2 different source blocks, 1 that sources agents for one half of the day, the other for the other half. Both converge into the same starting point of the model. I am only using 2 different sources to help simulate 2 different halves of the day.
I also have a resourcePool that increases in capacity from 1 to 2 at time() == 150. How can I ensure that the 1st resource unit that starts the day interacts only with those agents coming from source1, and the 2nd resource unit that arrives at time 150 only interacts with those agents coming from source2? Agents from both sources go through the same seize blocks that seize 1 unit each of 2 different resources at the same time.
There is a short overlap in which both resource units are working, so I want to ensure that one is not interacting with the other's agents.

You need to make use of the resource choice option inside a size block.
To do this start by having a new agent that will represent the resources inside your resource pool and give it a variable that you can use for assigning what source agents it will take. e.g. have an int variable sourceNumber
Now when you increase the number of resources in the resource pool from 1 to 2, you assign the source number of the second resource to 2.
resourcePool.set_capacity(2);
int counter = 0;
for (MyResource r:resourcePool) {
r.sourceNumber = counter;
}
If the agents that need to seize the resource all use the same seize blocks it is perhaps best to make a custom agent and send the seize block from which they came to the agent.
Then inside the source the resource choice field van be used to dictate the correct resource to use

Related

AnyLogic: two customer classes having different priorities

I know the basics of AnyLogic/Process Modeling Library and am about to teach simulation of basic queues with AnyLogic, transitioning from Simul8 that I 've used for many years.
I have agents of two types, 1 and 2, sent to respective queues 1 and 2, which then feed a single "service" point, so that type 1 takes higher priority (that is, whenever service is ready to pull work, it pulls from queue 1 if it is non-empty, regardless of the size of queue 2). How to capture this as simply as possible?
Having seen the reference pages for a Queue object, my preliminary (unworked) idea is to use a single queue, and control agent priority by the Queue.QUEUING_PRIORITY- Priority-based" option.
For comparison, a solution in the Simul8 software is: set "service" routing-in discipline to "priority"; and assign different priorities to the two queues.
Yes you are right you cant use two queues as the pull from the queues will be done in a round robin fashion. See the screenshot below from the AnyLogic training textbook
You should use queueing in a single queue and you can have either a single parameterised source or two.
See example below
I have 2 sources and at each of them, I set the priority to a local variable inside my agent. Agents from source 1's variable is set to 1 and the from source set to 0.
Then inside the queue, I set the priority so that the agents from source 1 is always in front.

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.

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.

Parallel activities for one agent

Is there a way to have parallel services and/or delays to occur per agent and move on with the activity that takes the longest. For example if I have an agent that can be painted and serviced at the same time, each requiring a different resource pool with different processing times but the agent will move forward when the process that took the longest is over.
Use a Split block to split your agent into two for the two parallel tasks (Service blocks) and then use a Combine to combine them back again afterwards (with the Combine block outputting the original agent 1).
You can also use RestrictedAreaStart and RestrictedAreaEnd blocks (capacity 1) around the split/combine area to ensure that other agents can't 'jump in' whilst the longest parallel process is still running (but the shorter one has already finished).
Something like the below (with resource pools).
Probably easiest to dynamically setup delay duration and resources needed from within 1 Service element:
calculate the duration your agent will use in each case (painting = 5 mins, servicing = 10 mins) --> use the longer value as the service delay
Also, make the agent require 1 painter and 1 service-engineer as resources.
Only drawback: Your painter will stay for 10 mins as well.
Alternative approach would likely involve creating your own, purely agent-based setup with seizing& releasing