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.
Related
If an agent enters a seize block that seizes 2 resource units each of different pools, if resource unit 1 is seized by that block while resource unit 2 is not because it is currently performing another task, resource unit 1 is considered idle when I use ResourcePool.idle(). The problem with this is that in other parts of my model, when I try to set conditions based on if a certain resource unit is not idle (meaning it is busy), it considers the time that resource unit 1 is waiting for the seize of resource unit 2 as idle, when really, I would like it to be busy.
Make sure you have "Seize units one by one" checked.
Otherwise all units remain idle until one both are available to be seized jointly.
I'm trying to represent a machine that works for a x amount of time before warning the operator that the oil tank needs to be refilled. Have in mind that the machine doesn't stop as soon as it send the warning message out. That way, the operator will wait until the machine stops any activity it had already started, and once it's done, he'll stop the machine and fill the tank.
In order to represent this process I'm using a Station block from the Material Handling library, that seizes a resource from a resource pool block, to which a downtime block is applied.
Is there a way to make the downtime block wait until the machine stops before performing the maintenance?
I also want to associate a resource pool representative of the operator to the downtime block, so that the operator is busy during the downtime, since he's the responsible for filling the tank. Can I do that?
Thank you in advance!
Is there a way to make the downtime block wait until the machine stops before performing the maintenance?
Yes, explore how Priorities work. Give your machine task a higher priority than the downtime task and ensure that the downtime block does not preempt other tasks:
I also want to associate a resource pool representative of the operator to the downtime block, so that the operator is busy during the downtime, since he's the responsible for filling the tank. Can I do that?
Yes, set the task type to "go to flowchart" and use a custom flow chart to seize from a resource pool (again, check the help on how to set this up in detail):
PS: Please only ask 1 question per issue always. See https://stackoverflow.com/help/how-to-ask and for AnyLogic https://www.benjamin-schumann.com/blog/2021/4/1/how-to-win-at-anylogic-on-stackoverflow
I’m simulating an unloading process of a ship. The complete unloading of the ship can be perfectly done with only two resources making round trips (load, move to destination, unload, go back to loading) and the ship would never be idle waiting for trucks to load.
I need to demonstrate that if I increase the number of resource units (trucks) to 3, the third one will never be seized because it’s not needed, the problem is that the seize block seizes all units evenly, so at the end, all units end up with a utilization percentage greater than 0.
How can I configure the seize block to only use the needed resources and leave the “excess” units with utilization of zero?
(The real model by default will have many resources available, and ships could need more than two trucks. What I want with this is to determine the best amount of resources needed).
Thank you.
In the ResourcePool there is an options Customize request choice which when set to True will allow Request choice condition function to be created. There it is possible to make sure that the resources taken first are the ones with utilisation > 0. If your assumption is correct then the 3rd truck will never be taken.
you just need to run two experiments. One with 2 trucks and another with three. Then compare them in terms of ship waiting time and truck pool utilization.
I solved the question in a very easy way:
In the Seize block use the option "Customize Resource Choice" with "Resource selection" equal to "Units with top rating" and "Unit rating" = unit.getUtilization().
In the way, Anylogic sorts the idle resources by utilization rating and chooses the most utilized resource, this means that unneeded resources will never be seized.
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 not so typical scenario for which I am not sure how to proceed:
There are two stations located at two different locations.
Both stations require the same resource.
The resource moves from station to station once released. So it keeps going from station 1 to station 2 to station 1, etc. until it is seized again. This is modeled by adding a link from the resource process port of the release block. So it is not completely released unless a condition applies. The condition is that there are agents waiting in the queue of the seize block of that same resource. So it should keep moving until it is needed again. The tricky part is that there are two seize blocks for that resource, one for each station. It is possible that agents are ready and waiting in the resource's seize element at both stations. I am adding an image of the resource's process at release. So at "selectOuput4" it checks whether station 1's seize element has agents waiting, if so, the resource is released and can be seized. Otherwise, it moves to station 2 and checks the same but for station 2.
My concern is that there might be a situation where both stations have agents waiting in their respective seize blocks. How can I make sure the resource will be seized by station 1's seize element and not station 2's, and vice versa. Is there a way to control where the resource is going in a case where two seize elements are waiting for it? Or is it always random?
I apologize for the long post, and I hope I managed to deliver my idea properly.
First, I think your design is a bit weird because you keep the resource always seized.
What I would do is first have a statechart in the resource that controls the resource movement from one place to the next so you have more control over it. The statechart would be used to move your resource ONLY when it's not seized. This will allow a case in which your resource is moving from station 1 to station 2 but something comes to station 1 queue and the resource can immediately react and come back to station 1 before it reaches station 2 (if you think it would be a good idea to do that)
The second is that the seize block defines the priority for a task when the agent arrives to the seize block, and your situation requires changing that priority dynamically, which can't be done as far as I know, so the wait block before the seize block is unfortunately a good option.