Why do not agents go out from the queue? - anylogic

I have a queue,followed by selectoutput. the problem is that the agent does not go out from the queue.In this case the agent should choose the third exit of the selectoutput, so it is not possible (i presume) that the agent does not go out because the following block is full.What could be the reason? Thanks

the reason is that the condition that you think is true, is actually false, because anylogic calculates first the condition in the select output block, and then it runs the code on the "on exit" action of the queue7 block...
So my guess here, is that you are doing something on the on exit action, that changes the result for the condition.. but it's already too late..
use the "on at exit" action or sometimes you need to put a dummy delay of 1 milisecond or so between your last block before the selectoutput and the selectoutput to ensure your condition is met correctly
This is the order in which things happen:
on at exit queue
check condition
on exit queue
on enter select output

Related

Anylogic: StopDelay() is not working due to which agent is not able to leave the Delay block

StopDelay() is not working due to which agent is not able to leave the Delay3 block.
of course your stopDelay won't work because no agent ever reaches delay4
delay3 REQUIRES a call for stopDelay, but there's nothing doing that since the only time stopDelay is called, is further in the flow.
What you need to do instead is on the on enter action of the delay3:
if(delay4.size()==0){
delay3.stopDelay(agent);
}
and on the on exit of the delay4 you do:
if(delay3.size()>0){
delay3.stopDelay(delay3.get(0));
}

How to make condition for queue?

I want to make agents to not enter the queue if it's full (if it's full then go to sink) at the moment of arrival in selectOutput5.
I tried to put "if-else" into "Actions" section
But I don't really know which parameter to use (tried to use queue.size and queue.capacity but I don't know how to code this properly), please help. Not sure if I doing the right thing at all by trying to put if-else into actions of selectOutput5
The model look like this:
You need to code the conditions under which they should enter which queue and then if the conditions are not met it will assess the next out option.
See example below
It will only go to queue 1 if the queue size is less than 5, else it will assess the queue size of queue 2 and if both are full then go to the exit.
The Actions section is only for code you want to execute if they do exit one of the out options.
Put a selectOutputOut block, select conditions there. And type below your condition: yourQueue.size()>=yourQueue.capacity(). Send the ones to Sink block when this condition is true.

Anylogic - Assembler should stop working for 2 hours after 10 assemblies done

The "Assembler" should stop working for 2 hours after 10 assemblies are done.
How can I achieve that?
There are so many ways to do this depending on what it means to stop working and what the implications are for the incoming parts.. but here's one option
create a resourcePool called Machine, this will be used along with the technicians:
on the "on exit" action of the assembler do this (I use 9 instead of 10 because the out.count() doesn't count until the agent is completely out, so when it counts 9, it means that you have produced 10)
if(self.out.count()==9){
machine.set_capacity(0);
create_MyDynamicEvent(2, HOUR);
}
In your dynamice event (that you have to create) you will add the following code:
machine.set_capacity(1);
A second option is to have a variable countAssembler count the number of items produced... then
on exit you write countAssembler++;
on enter delay you write the following:
if(countAssembler==10){
self.suspend(agent);
create_MyDynamicEvent(2, HOUR,agent);
}
on the dynamic event you write:
assembler.resume(agent);
Don't forget to add the parameter needed in the dynamic event:
Create a variable called countAssembler of type int. Increment this as agents pass through the assembler. Also create a variable called assemblerStopTime. You also record the assembler stop time with assemblerStopTime=time()
Place a selectOutputOut block before the and let them in if countAssembler value is less than 10. Otherwise send to a Wait block.
Now, to maintain the FIFO rule, in the first selectOutputOut condition, you need to check also if there is any agent in the wait block and if the current time - assemblerStopTime is greater than 2. If there is, you free it and send to the assembler with wait.free(0) function. And send the current agent to wait. You also need to reset the countAssembler to zero.

Is it possible to dynamically update if functions in anylogic?

I'm using a state chart in combination with a schedule in Anylogic (see picture). The output of the schedule is equal to 1 during working hours and 0 otherwise. Now I want the transition from state1 to state2 to happen when the schedule is turning to 1 or is equal to 1(so otherwise wait until the working hours).
I have tried using an if statement
if( main.plannerSchedule()==1 )(<perform action>)
However, by this method, the state transition only happens if the statement is true but doesn't wait for it to become true. Is there a way to constantly update the state transition or is there a "wait until" function that can solve this problem?
Best let the schedule send a message to your statechart when it switches. This assumes that the statechart lives on the same agent type as the schedule. Write this code in the action code box of the schedule:
if (value==1) {
statechart.fireEvent("go to state 2");
}
Obviously, your message transition needs to await the "go to state 2" message.
Note the value keyword. See https://www.benjamin-schumann.com/blog/2016/2/4/the-magic-lightbulb-and-how-it-can-help-your-anylogic-modelling for more info on that

Unexpected behavior SelectOutput block in AnyLogic

In a model I use a selectoutput block using a condition, based on the agent's p_Dx_EGFR_SOC_AH parameter, which is of type Option list (options: Mutated, NotMutated, UnknownStatus). If agent.p_Dx_EGFR_SOC_AH == Mutated evaluates to true, then the exit via the true port, otherwise they exit through the false port. To check whether it works correctly, I included a traceln(agent.p_Dx_EGFR_SOC_AH); in the On exit (True) field of that selectoutput block.
It turns out it's not working as expected. The traceline shows that agents with either of the three options of the parameter exit through the True port:
This is also true for the False port; agents with either of the three options exit through that port. Am I doing something wrong here, or is this a known bug in AnyLogic?
The problem here, is that the order in which things are calculated is in reverse... so let's imagine the following model and the condition to exit true is agent.parameter==0 and the default value of the parameter is 0
the order in which things happens is
the agent is on at the exit port of the source block
the agent calculates the condition on the selectoutput block
the agent moves out of the source block and makes the calculations on the "on exit" action
that means that if you change the value of the parameter on the on exit action of the source block agent.parameter=1, the agent will still exit on the true exit of the selectoutput becacuse the condition was already calculated
if you change the value of the parameter on the on at exit action, the agent will exit through the false exit of the selectoutput block
It's a bit weird, but that's the way things are done
Sometimes you don't have the "on at exit" action, in which case you might need in between an auxiliary delay of 1 milisecond in order to have the order you want.