Holding agents before a select output element to avoid default port - anylogic

I've been trying to model a scenario but still cannot find the best way to do it. The scenario is as follows:
Agents arrive at a point where they need to choose one of three paths. Each path is a delay with capacity 1. If the first path already has an agent in it (in the delay block), then the 1st condition is not met and the agent tries the second port. In the second port, if the delay block is available it can proceed, otherwise it checks the third. If all are busy, then the agent should wait in a queue before the select output.
To model this process, I used the following sequence:
Queue > Hold > Select Output 5 > 1 Delay element of capacity 1 after each of the three first output ports of the select output
The condition for the select output is for example "Delay1.size() == 0" then for the second port "Delay2.size() == 0", etc.
Then, I created a function that checks if all delay.size() == 1, then the hold element is set to blocked to avoid having agents going through the select output's default port. The function is tested at every "On Enter" and "On Exit" fields of all the blocks.
Despite the above, agents are still going through the default port which means that the hold element is not working properly.
Is there a more efficient way to model the described scenario? Thank you!

Well, you are not actually blocking your Hold element at all, hence agents will walk through anytime :-)
There are many ways for such a situation.
You could replace the Delay with a Wait element instead. Whenever an agent leaves one of your Delay blocks, you unblock the Hold.
Whenever an agent passes the Hold, you block it, but only if all 3 pathes are currently busy.
Should do the trick

Related

AnyLogic: Empty agent parameter in the function

I was faced with a problem in AnyLogic.
I created a function with an argument. The argument is agent Message. However, the function doesn't get the current agent. It seems that the argument is empty. Why?
this is one of the most confusing things in anylogic that things get calculated in reverse order compared to what you expect.
First the condition is calculated in order for the agent to decide where to go, and after that the agent exits the source...
Based on what we see here, the volume is probably calculated on the "on exit" action of your source and you should calculate it on the "on at exit" or you can also put a delay of 1 milisecond after the source and everything will be ok

Is there a way to stop the "Source" block from generating agents after a specific time in AnyLogic?

Utilizing a source generating agents on an Interarrival time basis, I would like to stop the source block from generating agents after a certain amount of time passing so that the model can continue to process the agents.
One option to encapsulate all the logic inside the source block, without external events or variables, would be to select Multiple agents per arrival as true and then have a conditional statement for the number of agents, for example time() > 10 ? 0 : 1, so that after 10 model time units there will no agents arriving
Sure. If it is a inter-arrival source block, make it use a variable as the interrarrival time, of type double:
Then, create an event that triggers once only, after your specific time. Make it change the variable to 0 as below. Make SURE to trigger it not at time 0 (as in the screen but when you need it!):
NOTE: Do not set myRate = 0;. Instead, set it to infinity` to actually have no more arrivals.

AnyLogic: Select specific resource set based on condition

I have created a simple model in AnyLogic (see screenshot). Now I want to add a condition that selects one of the two resource sets in the service block. As an example the following scenario shall apply: If there are more than 5 parts in the queue, worker 3 and worker 4 should perform the service. If there are <= 5 parts in the queue, the service shall be performed by worker 1 and worker 2. This is only meant to be a simplified example. I am primarily interested in solving this problem using a condition. I have already tried different approaches, but without success. Does anyone have an idea how the Java code for this condition could look like?
First, you don't need the queue since the service block already has a queue... So For this particular example in your resource choice conditions you will do the following:
service.queueSize()>5 ? (worker3.containsUnit(unit) || worker4.containsUnit(unit))
:
(worker1.containsUnit(unit) || worker2.containsUnit(unit))
You can change service.queueSize() with queue.size() if you insist in using a queue. After that you need to be sure to recalculate the conditions when needed, for this particular example i think you only need to recalculate them on exit action of the service block:
self.recalculateResourceChoiceConditions();
One easy approach is to use Seize and Delay (and Release once done) blocks instead of Service. Before Seize, you can place your condition in a SelectOutputOut block. Like this:

access variables in "Main" from another agent (anylogic)

I have a model as shown below with two situations, I am running it for two situations.
In the first run (for situation1), I write traceln function as "traceln(productDemand)" in the "event-generateDemand" placed in "Main". At the end of simulation, I get the values in the first column below.
2)In the second run (for situation2), for once I write traceln function as "traceln(main.productDemand)" in the "event" placed in "Producer" agent.At the end of the second simulation, I get the values in the second column below.
Normally, these two values are always same , it expected that at the every simulation time they have to be same, but they are not same as shown in the Fig.1. what's the problem? Why the "productDemand" variable is different when we try to access from another agent at the same time?
I hope I was able to explain my problem.
Fig.1- The obtained results as table format
Fig.2- The screenshot of Event placed in Main
Fig.3- The screenshot of Event placed in Producer agent
Fig.4- The obtained results for both traceln functions on the running
Fig.5- Simulation experiment screenshot.
fig.1
fig.2
fig.3
fig.4
fig.5
There is no bug in the model it is just a simple case of timing. Not all events occur at exactly the same "time" although they all occur at the same timestep. One will always execute before the other.
See the simple example below:
I have eventA that increases the variable value and then traces the value (similar to your event on main)
Then I have another event that traces the variable as well, similar to yours in the agent.
Yet when I run the model at the same time the variable appears to be different from the different locations of tracing
If you click on the Events tab in the console you will see that event B is scheduled to run before event A
Even though both will run at the same timestep in the model they don't run "at the same time"
If you want to be in total control of what happens on a specific time step, it is advised to have one event that runs at the time interval you want, e.g daily, and have it sit on main and then call all the functions in the order you want them executed.
If you don't do this then AnyLogic will schedule the events as they get created, which most of the time is the order in which you placed them on the canvas.

AnyLogic if condition selectOutput

I'm modelling a manufacturing line in anylogic. Two agents are being processed and transported via the same conveyor. Both Agents need to spend diffent delay times in a service station. Because of that i added two parallel services and now i want to sort the agents arriving on the conveyor to their corrosponding service stations.
flowchart
Agent1 needs to go to service and Agent2 to serviceT.
I assigned parameters to both Agents, Agent1 has the boolean parameter "S" set to true and Agent2 the same parameter set to false.
To sort the Agents in the selectOutput block i typed in the if condition agent.S == true as seen in the next screenshot.
selectOutput
Anylogic prompts following error: "Unresolved compilation problem: S cannot be resolved or is not a field"
What can i do about this?
Thank you!
I would like to answer this question in two parts:
Instead of using a selectOutput to model different delay times for the SAME station, it would be more reasonable to have only ONE service representing that ONE station. To model different times, set the delay time equal to agent.S where S is the delay time for each agent.
Regardless of whether you choose what I suggested or what you are already using, you will still get the same error. The reason for this error is most likely that you haven't specified the agent type going through the select output properly. In fact, if you look at the image of the select output properties you shared, under the "Advanced" tab, the agent type is set as the default type Agent. Make sure to replace that by the agent type that contains the parameter S.