I am trying to make my resource pool available/not available as per defined on/off schedule.
Anylogic asks the capacity when on, i have mentioned it as 2.
But i want it to be connected with a slider so that capacity while on can also be made variable while running the model to test the effects.
when i am trying to link the slider, my desired resource pool gets "disabled".
only those resource poolss are shown as enabled whose capacities are defined as "Direct" but not by schedule.
what to do?
You can link the field Capacity when on of a resource pool dynamically with the current value of a slider using the function slider.getIntValue().
Please note however, that the resource pool capacity can't be changed for the current active shift (when the on/off-schedule is currently "on"). So for example, if your shift is currently active with a capacity of 2 and you changed the slider value to let's say 3, the result will be:
Capacity during the current "on" shift: 2
Capacity during the next "on" shift: 3
Related
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
I currently have 2 different source blocks, 1 that sources agents for one half of the day, the other for the other half. Both converge into the same starting point of the model. I am only using 2 different sources to help simulate 2 different halves of the day.
I also have a resourcePool that increases in capacity from 1 to 2 at time() == 150. How can I ensure that the 1st resource unit that starts the day interacts only with those agents coming from source1, and the 2nd resource unit that arrives at time 150 only interacts with those agents coming from source2? Agents from both sources go through the same seize blocks that seize 1 unit each of 2 different resources at the same time.
There is a short overlap in which both resource units are working, so I want to ensure that one is not interacting with the other's agents.
You need to make use of the resource choice option inside a size block.
To do this start by having a new agent that will represent the resources inside your resource pool and give it a variable that you can use for assigning what source agents it will take. e.g. have an int variable sourceNumber
Now when you increase the number of resources in the resource pool from 1 to 2, you assign the source number of the second resource to 2.
resourcePool.set_capacity(2);
int counter = 0;
for (MyResource r:resourcePool) {
r.sourceNumber = counter;
}
If the agents that need to seize the resource all use the same seize blocks it is perhaps best to make a custom agent and send the seize block from which they came to the agent.
Then inside the source the resource choice field van be used to dictate the correct resource to use
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.
I have a resource pool and a service block. The number of the operator in the resource pool is 5 which is linked to the service block. I would like to setup the service in a way that the more workers work on the service the delay time decreases. (ex: if 1 worker works the delay time is 10 min - if 2 workers work the delay time is 5 min. - if 3 workers work the delay time is 3.33 min). I would like up to 5 operators to be working at the same time in the service block based on their availability.
Service Block and Resource Pool
How can I achieve this?
So you're trying to do two things with your Service block:
Seize a dynamic number of units (in the simplest case, seize all available units).
Have the delay time dependent on the number of units seized (in the simplest case, just decreasing multiplicatively according to the number of resources).
For the former, assuming you're seizing from a single pool, just enter a dynamic expression in the "Number of units" property. In the simplest case (seize all available) it would just be pool.idle() (for a resource pool called pool) but that's problematic if the next agent arrives whilst the first is being processed (because it will be treated as needing zero resources) so, depending what you want, you might need to do something like put RestrictedAreaStart / End blocks around your Service block so only one agent can be in the Service block at once.
NB: AnyLogic currently has a bug/limitation that the resource pool's idle/busy counts (from its idle() and busy() functions) are not guaranteed to be correct unless you are at a later simulation time than when seizes/releases occurred. (This is due to how things are resolved in hidden events under-the-covers.) So, if you want to use them in your determination of the number of resources to seize you need to work round this; e.g., by
tracking the number of busy/idle units via your own counts;
using the isIdle() function on individual resources in the pool instead (which typically requires ensuring the resource pool agents are in a custom population, not the hidden default one, so you can explicitly reference/loop through them);
something horrible and hacky like adding a very-small-timeout Delay block before entering a Service block (possibly within RestrictedAreaStart / Ends to ensure that agents don't make it into the Delay, and hence the Service block's seize mechanism, until you want them to).
In general, it makes sense to put the resources-needed calculation in a function (which returns an int and takes the agent as an argument) which you call in the "Number of units" expression. That way you can make the calculation as complex as you like; it would seem you might need a more complex consideration than just "grab everyone" (e.g., perhaps depending on the stream of to-arrive agents if you have knowledge of them, etc.). Maybe, for example, you'd also want to hold your arriving agents in a Wait block beforehand and only release them when the number of resources you want are available. (You'd need to give more precise detail about your requirements to be any more definite here.)
For the variable delay time, have an appropriate dynamic expression for the delay time; you can use the resourceUnits() function to get a list of the resource units seized by your agent. So, in the simplest case (decreases multiplicatively according to the number of resources) it would be something like 10.0 / agent.resourceUnits().size() (for a base delay of 10 time units).
I have a resource pool that adds units into the population "forklifts". The agents of type Forklift are chosen by other agents and later seized for specific tasks. There is also a schedule for the resource pool.
The problem is that whenever capacity decreases, forklifts units that are moving in the model (but not seized yet) are halted because they are no longer active. Is there a way to customize the choice of resources for the "end of shift". I cannot find anything in Help or online.
Thanks!
I have tried iterating through the resource pool but there is no function I could find to determine whether a unit is active or not. There are boolean functions for idle and busy.
agent.unload_forklift = findFirst(forklifts, f->f.in_use == false);
There are agents that choose resource agents based on internal variables. Maybe I could iterate through the resource pool instead of the population...
I expect forklifts' capacity to decrease based on a customize signal not randomly.