According to the AnyLogic's documentation, a Seize block embeds a Queue block, and "The rich interface of Queue (ability to use priorities, timeouts, remove agents, etc.) is fully exposed by Seize.".
I want to access the queue portion of a seize block in order to make agent prioritization, which can be found under the first "Advanced" tab of the Queue block properties. However, I cannot see this in the properties of a Seize block.
Is there anything I have to do in order for this property to appear in the Seize block? Or do I have to set the queue capacity of the Seize block to 0 and add a separate Queue block in front? I want the model to be as readable as possible for my case organization, thus I want to use as few blocks as possible.
In the seize, the conceptual difference is that instead of "queue priority" you have "task priority"
You can basically do everything related to priority using only that. If you do nothing, you use FIFO, if you want to prioritize based on priority based, well then it's the exact same. If you want to use LIFO, then you can use agent.getBlockEnterTime() as your priority variable, and if you want to compare agents, it's the same as using priority based.
So no, you don't need to add another queue
Related
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!
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));
}
I know the basics of AnyLogic/Process Modeling Library and am about to teach simulation of basic queues with AnyLogic, transitioning from Simul8 that I 've used for many years.
I have agents of two types, 1 and 2, sent to respective queues 1 and 2, which then feed a single "service" point, so that type 1 takes higher priority (that is, whenever service is ready to pull work, it pulls from queue 1 if it is non-empty, regardless of the size of queue 2). How to capture this as simply as possible?
Having seen the reference pages for a Queue object, my preliminary (unworked) idea is to use a single queue, and control agent priority by the Queue.QUEUING_PRIORITY- Priority-based" option.
For comparison, a solution in the Simul8 software is: set "service" routing-in discipline to "priority"; and assign different priorities to the two queues.
Yes you are right you cant use two queues as the pull from the queues will be done in a round robin fashion. See the screenshot below from the AnyLogic training textbook
You should use queueing in a single queue and you can have either a single parameterised source or two.
See example below
I have 2 sources and at each of them, I set the priority to a local variable inside my agent. Agents from source 1's variable is set to 1 and the from source set to 0.
Then inside the queue, I set the priority so that the agents from source 1 is always in front.
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.
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?