Anylogic: How to keep an agent waiting in queue until it changes state? (Discrete Events flowchart) - simulation

I'm starting to use Anylogic for a simulation class, and for this I need to model the following behaviour: there's a stream of agents that enter a FIFO queue, and then enter into a server (that I modeled with a delay block), one at a time. The agents have two states (call them A and B), and if an agent reaches the end of the queue in state A, it has to wait until it returns to state B to go into the service.
I think a wait block with capacity for one agent, between the queue and the delay block could potentially solve this situation. But I don't know how to make the wait block to free the agent as soon as it changes state.
Other methods are welcome. I just need the agent to be retained before the delay block as long as it is in the state A, but not any longer. Thanks in advance.

Yes... a wait block with capacity 1 after your queue block is what I would do.
Now when your agent enters the state, on the entry action of that stateB you do the following:
if(currentBlock().equals(main.waitBlock) && main.service.size()==0){
main.waitBlock.free(this);
}
You will also need to do this in the "on enter" of the wait block:
if(agent.inState(agent.stateB) && service.size()==0){
self.free(agent);
}
also, just in case, add a population of 0 of your agent type in main, to be able to use main. in your agent state code.

Related

How agents will wait in the queue for there turn to go to the Delay section?

I used seize-move-release in order to move the agent with the resource. shown in the figure below.
Problem
Now the only problem is, how agents will wait in the queue (capacity 2) for there turn to go to the Delay section using resource. Explanation is in the image below.
What i am trying to achieve:
I mean agents wait in the queue (capacity 2). Once the delay(machine) gets empty, only then resource transfer the agent from the queue to the delay.
Note:
I try to use service because Service block have queue too but I need the queue before the resource pool.
I hope I explain my problem well let me know if I miss some thing.
I used Wait Block for the agents to Wait but when wait capacity equals to 2 . Agents stop moving forward.
Use a "Wait" object ahead of moveTo.
Whenever the delay capacity decreases to zero ("on exit" code box of delay you can check it using delay.size()==0?), you can tell an agent in the "Wait" object to advance now, using wait.free(agentToFree).
If you want to free the oldest agent, use wait.free(wait.get(wait.size()-1))

Agents not leaving the queue before a transporter is free

in my model I have a queue were multiple agents from different sources come together to seize an transporter ( see picture). But now they leave immediately after they enter the queue to the seize transporter block. But I want to keep them in to queue until a transporter is free and then the first one in the queue should seize a transporter and so should move to the seize transporter block. How should I fix this?
There are several ways:
After the queue, add a RestrictedArea elements to limit the number of agents in the Seize seizeTransporter4 element. In the queue, you can sort the agents.
Instead of a queue element, use a Wait element, in which case you need to write the logic for extracting agents and sending them to seizeTransporter4 element.
The second way is more flexible in terms of writing logic.
seizeTransporter has its own embedded queue. You can access that value with seizeTransporter4.size(). If you insist on having them separately, instead of queue, use delay block, with stopDelay option. Whenever the seizeTransporter4.size() drops below number of available transporters, run the stop delay function. Like
if (seizeTransporter4.size()<=3){
myDelay.stopDelay(myDelay.get(0));
}

Anylogic ResourcePoolName.idle() is not update real time?

I use the below command to check availability of ResourcePool:
ResourcePoolName.idle()
ResourcePoolName.busy()
I found that the idle unit (or busy unit) is slowly updated.
When the agent leave the Service block, ResourcePoolName.busy() is still busy and ResourcePoolName.idle() is sill not idle. I need to wait for the agent to enter the next 3rd block so that ResourcePoolName.busy() unit and ResourcePoolName.idle() are updated correctly.
How can we have the idle unit (or busy unit) of the ResourcePool update real time????
Someone recommend me this solution and it work well.
Instead of using A Services Block alone, I uses Services Block + Delay (with delay time = 0). Now when the agent leave the Delay Block, ResourcePoolName.idle() status did updated correctly.

How to store agents in a block untill a tronsporter can move them?

I'm a new AnyLogic user so hopefully this is a simple problem. I would like to use a block as to represent a storage area for items to be used in an assembly, I am using the delay block with delay time of 0, but maybe the queue block would be more appropriate? I have set up a model in which every X number of seconds a "truck" arrives and if the delay block contains less than a specified capacity of elements, the inject function is called to refill the block. This sort of works, but is seems that the agents are flowing through the delay block's out port and thus do not count toward its capacity (that makes sense to me...) resulting in my source blocks continuing to create agents when the system isn't ready for them. My delay block is followed by a "move by transporter" block which seems to be getting all of the delay blocks outputs immediately. There are only two transporters in my model and I am not sure why more than two agents can be accepted by the transporter block at a time. I set my transporter fleet to have a capacity of 2 but that did not solve the problem.
Any advice would be helpful! Perhaps a different approach is needed. My goal is to have an essentially unlimited pool of parts at the inlet of the factory, but only create agents when the downstream processes are able to pull them in. Thanks in advance!
Welcome to SOF :)
Best use a "Wait" block here:
Let your trucks dump stuff into "Wait" whenever they arrive. Your downstream block can now pull them when they are ready using myWaitBlock.free(someAgent for as many agents as they want to pull from it.
Similarly, you can use a Delay with infinite capacity and set its type to "Until stopDelay() is called". Then similarly as the "Wait" block, you call myDelayBlock.stopDelay(someAgent) when you want.
Another option: Use a hold-block in front of a normal (infinite) queue and unblock it when ready: myHoldBlock.unBlock(numToLetThrough) --> probably the easiest
PS: Please also check how to ask good questions here on SOF, yours is very long, much easier to understand with some screenshots :) --> https://stackoverflow.com/help/how-to-ask

Anylogic: Is there an alternative to the delay block in order to stop an agent over a path until a given simulation time is reached?

If someone wants to delay an agent over the path, the delay block can be used customizing the delay time in order to get a deterministic exit time matching the desired simulation time.
Exists an alternative to that?
You can use a wait block with an event inside the agent that is going to be triggered after your delay time is over and call the free() function to get out of the wait block.
Nevertheless, you can customize your delay time in the delay block by using agent.delay (assuming that you have a variable called delay in your agent that identifies how long the delay will be for the agent)