AnyLogic: Distribution by enter block depending on capacities in three resources - simulation

I have created multiple instances of a resource and filled them with specific delay and queue blocks. At the start of the resource I set a restricted area to check how many agents are in the resource.
My goal is to distribute incoming agents in queue1 first to resource1 until it contains 50 agents. These 50 agents are then in resource1 and are in longer delay blocks. After that resource2 should be filled until there are 50 agents in it, then resource3 and so on (theoretically still scalable upwards, but for now only for three).
The agents all arrive in time. There is a priority that first one resource is filled completely, then the next one.
For this I have written a function, which is regularly updated in the event.
My problem is that I don't how to make such distributions based on more and more arriving agents and additionally consider the capacities of each resource.
Unfortunately, since all conditions are true at the beginning and thus all if queries are true, an error is thrown. Can someone please help me here?

Adjust the code as below:
if (resource1.restrictedAS.entitiesInside() < 50) {
...
} else if (resource2.restrictedAS.entitiesInside() < 50) {
...
} else if (resource3.restrictedAS.entitiesInside() < 50) {
...
}

Related

Assigning certain agents to a certain resource unit based on source

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

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

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.

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

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.

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.

Request entity from Anyogic Process Block and wait until it's available if there is not currently one

I'm trying to emulate what QUEST does when a buffer is queried for a certain Part. In there if the part is not in the buffer the request is left pending and if a Part arrives to the buffer it's released to the machine requesting it. I have also seen this behavior in SimPy which is another DES engine.
I can't seem to find a simple way to do this in AL. The queue block has the following methods:
release(agent): Will return false and forget about the request if there's not an agent as the one specified
remove(agent): Will return null if there's no agent in the queue
So those methods won't do what I want...
It gets a little more complicated as the queue contains agents with parameters and I want to request a specific set of parameters (let's say the agents have a number parameter that can go from 1 to 3 and I'm only interested in agents in the queue if this parameter has the value 2).
Also there's a series of agents pulling this agents from the queue simultaneously and I'd like a priority to be set (let's say FIFO)
so there's a couple things that I've tried and have lead me nowhere:
Using a seize block instead of queue and adding the agents to the embedded queue in the seize block. -> I can't find the proper method to seize from the buffer in a different way from a buffer block (so I moved to option 2) but seize does have a promising customize resource choice that could help with the parameter down-selection
Using a seize block and storing the agents in a pool as resources. issues with dynamic creation of resources, seizing the appropriate one etc...
Creating a queue of requests that have returned null from a queue. This sounds like an overkill but I'll look into it
All of those appear to be a bit complex for such a simple thing in other softwares for simulation so I'm wondering if I'm missing something or if someone has come across this issue before
Suggestion 1: may it helps you to store the agents in the queue in a collection (or different collections, according to the parameter settings). Events: "on enter" and "on exit"
Suggestion 2: may the Wait - block helps you here?