Priority queue is not working in AnyLogic - simulation

I have two variables in agent
handicap = RandonTrue(0.3)
priority.
The priority variable value set in source exit based on wither agent is handicap or not, as shown in the image below.
Now in the queue I set Queuing to priority base and set agent priority to agent.priority . Shown in image below.
Note: Queue capacity is set to 10.
Now when I run the model and 10 agents enter I the queue, according to the priority handicap agents should be on the top of the queue but that is not happening. shown in the image below.
When the agents enter the delay after the queue, I also print their priorities on the console. The result is still the same, no priority is followed.
In the above image it is clear that they are not sorted based on priority.
Why priority queue is not working?
Moreover, I also changed the Queuing to LIFO, queue showed the same result, showing zero effect on agents.

this happens because contrary to the intuitive idea that events happen in the order you see, they don't... Things occur in the following order:
agent is created with the default value for the priority value
on at exit action is executed
the queue priority value is checked for the queue
the on exit action is executed
So from the point of view of the queue, the priority for all agents is the same
Solution
Instead of setting the priority value "on exit" do it on the "on at exit" action of the source block

Related

How to manually increase the task’s priority by code, using the On task suspended action of the service block

I want to do as written in the title. I'm referring to the part of Anylogic's service block page that says:
“If this order does not suit your needs, manually increase the task’s priority by code, using the On task suspended action of the block.”
I couldn't find how to do it. I did find in the seize block function that recalculates the priorities of the agents in the queue, but this function does not exist for the service block.
Here is a link to the help page:
https://anylogic.help/library-reference-guides/process-modeling-library/service.html
I will add that my goal is to use downtime for service with the policy "seize any unit" but the default of Analogic is to put the suspended agent in the back of the queue. I need it to be the first to seize the next available resource.
Thank you very much!

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))

Change priority rule of a Queue block at runtime in Anylogic

I am trying to implement reinforcement learning in Anylogic using pathmind library, the RL agent can take either of two actions which is changing the priority rule of a Queue block.
I have a Queue block where I'm using priority-based queueing. I have two priority rules: using agent's departure date & agent's wait time. I want to either of these rules during runtime using another function called doAction(action). A value 0 or 1 will be passed to this function. The function body would be like this:
doAction(action){
if(action==0){
//set departure_date as priority rule of Queueblock}
else{
//set wait_time as priority rule of Queueblock}
}
The expression of my queue block is given here. .
RL parameters are mentioned here.
What should be the code to set priority rule dynamically from the doAction(action) function?
I would suggest to rather make the priority rule dynamic inside the queue.
I assume you have some agent with a field for departureTime as well as for waitingTime.
Then you can do something like the following:
You simply have a different priority level for each agent if the priority option changes.
Here I am using boolean useDaprtureTime, but you can make it as complex as you need and even have a function in the "Agent Priority" field that returns the priority level.
Just remember that you need to call queue.sortAgents() if you change the rule since only the new agents that arrive are sorted, not the entire list of agents waiting in the queue since this will be too resource-intensive.
To use priorities, you specify an expression to determine the priority of the agent in the Queue's "Agent priority" or "Agent 1 is preferred to agent 2" property (depending what priority scheme you're using).
So have that expression be calling a function (defined within the agent type in question) which returns either the departure date or wait-time alternative.
Also, you didn't say whether this is a global setting --- i.e., use either departure or wait-time-based priorities for the whole run --- or could change dynamically; if you want the latter, you potentially need to call the sortAgents function of the Queue block (which might be inside a Service or Seize block, depending what you're doing) at the appropriate times (i.e., when your prioritisation scheme changes) to re-calculate all the priorities for agents currently waiting in the queue.
EDIT: I see from your other comment that you're trying to use reinforcement learning, presumably learning how to make a decision on how to prioritise the agents. (You should put that in an edit to your question since it's pretty important and relevant!)
So if you view the queue as the 'learning agent', you need to separate the learning action (which will set up / decide which prioritisation scheme you're using) from then using that scheme in the prioritisation.
This depends on whether you're using a Queue on its own (with priority based or agent comparison queueing), or you're doing this within a Service or Seize block. It matters because the on-enter action of the latter runs before the priority calculation expression but, with a plain Queue, it runs after the priority calculation.
Case 1: Using Service or Seize block
Have the on-enter action be the RL action which would then, say, set some variable to say which prioritisation scheme it had chosen and then call sortAgents on its embedded queue (self.queue) to recalc all the priorities. Then have switches in the priority calculation expression as above to do the calculation for the incoming agent using the required scheme.
Case 2: Using a plain Queue block
As above, but do the prioritisation scheme decision in the on-at-exit actions of all immediately preceding blocks (i.e., so that this is run just before the agent arrives at the Queue block and has its prioritisation allocated).
You can always use 2 queue blocks and send agents to only one using a SelectOutput block in front of them.
Each agent decides which queue to use based on your conditions.

Priority based queue in Anylogic

I am using a priority based queue to pick agents from a pallet rack. Priority of agents can be 0 or 1. If there are 10 agents in palletRack, I want to pick all the agents having priority=1 first. My problem in the current flowchart is: Agents with priority=0 are pickup up before agents with priority=1. May be because the agents enter & leave the Queue block one by one, multiple agents aren't present in the Queue block at the same time so that they can be sorted. How to resolve this?
put a hold block between queueStorage2 and pickFromStorage1 and on the on enter action of queueStorage2, you check if all your agents are there, and if they are (with whatever condition you need to check to be sure everything is there) you unblock the hold with hold.unblock();

Assign priority to 50% agents in anylogic

I want to assign priority to my agents and then queue them based on that. I have an agent Container which has two parameters carrier (which can be either Truck or Train) & priority (which is to be assigned with some value). 50% of agents where carrier=Truck and 50% of agents where carrier=Train should be assigned priority 1 and rest should be zero. How can I do that?
This is my model. []. I want to move the above mentioned agents from storage1 to rackPick block on priority.
Thanks in advance.
This can be achieved by creating an integer 'priority' field in the agent and then setting it to 0 or 1 based on random(0.5) value in the on at exit action of the originating Source and then checking that field in the Queue to get priority. It won't be exactly 50% but pretty close for a large enough number of agent.