AnyLogic
Expand
Font size

ResourcePool

AnyLogic: The ResourcePool block

The ResourcePool block defines a set of resource units that can be seized and released by agents using the Seize, Release, Assembler, and Service flowchart blocks.

There are 3 types of resources:

  • Static resources are tied to a specific location (that is, a node) within the network and cannot move or be moved. An example of a static resource would be an X-ray room or a weigh bridge.
  • Moving resources can move on their own and can represent personnel, vehicles, and so on.
  • Portable resources can be moved by agents or by moving resources. A portable U-sound device or a wheelchair would be an example of a portable resource.

Moving and portable resources have home locations to which they can optionally return or be returned. The resource units in a pool can have individual properties, can be animated, collect unit-based statistics, and so on. You can define your own resource type to represent staff, equipment, and so on. The agent uses the pool name to refer to the resource units, and can select a particular unit by analyzing the unit’s attributes.

Each resource unit can be either idle or busy. This block collects utilization statistics, which are continuous time statistics on the percentage of busy units. Resource units always collect their individual utilization statistics. You can also collect detailed statistics on the downtime of individual resource units, that is, the time that a particular unit has spent on maintenance, breaks, broken, or in user-defined downtime.

Moving resources do not recognize each other as obstacles and will move over each other, which does not correspond to reality. If you want to take collisions into account and model how moving resources resolve navigational conflicts, path-guided or free-space transporters would be a better choice.

Library blocks that work with resources

There are a variety of possible operations with resource units supported by the Process Modeling Library: the agent can seize one or more units (Seize), release units (Release), send seized units to a specific location (ResourceSendTo), attach units so that they will move with the agent (ResourceAttach), and detach attached units (ResourceDetach). Whenever an operation is performed on multiple resource units, the list of their ResourcePool blocks is specified. For example, to seize two nurses and an X-ray room, you would specify Nurse, Nurse, XRay.

The requests from different Seize and Service blocks are queued in ResourcePool if they cannot be satisfied immediately. The queue can be simple FIFO or based on priorities.

A set of resources may have multiple tasks with different priorities and preemption policies.

  • If all tasks have the same priority, they will be executed in the usual way following their occurrence schedule. If there are enough resource units available, tasks can be executed simultaneously. If two tasks have the same priority, but one of them was suspended for some reason, this suspended task will be picked1.
  • If you have configured no preemption policy for the tasks, these tasks will be executed one after another following their occurrence schedule. If there are enough resource units available, tasks can be executed simultaneously.
  • The occurrence of one task does not reset the priorities for other tasks.
1 Each resource unit may receive requests from different sources. When a single resource unit receives multiple tasks, suspended and new, with identical priority values, some rules apply to the picking order:
  • The suspended tasks from the individual queue of the resource unit have the highest priority.
    This queue is formed by agents waiting in blocks that have the Task preemption policy set to Wait for original resource.
  • After that, the suspended tasks from the queue of the ResourcePool block are processed.
    This queue is formed by agents waiting in the blocks that have the Task preemption policy set to Seize any resource.

Once the suspended tasks from these queues are completed, the resource unit begins to process new tasks from their individual queues, and after that, the queue of the ResourcePool block.

If this order does not suit your needs, manually decrease the task’s priority by code, using the On task suspended action of the block.

Defining the resources capacity

The capacity of this block (the number of units) can be defined directly as a number that you type into its Capacity parameter. Then, if you want to change the number of resources dynamically at the model runtime, you can use the set_capacity(new value) function. If the capacity is dynamically reduced by calling set_capacity(), but the number of currently seized units exceeds the new capacity, the extra units are not removed from the pool until they are released.

Another way to define capacity is by the home location of resources. The special space markup elements called nodes are used as the home locations for resources. Click the AnyLogic: The Plus icon button to add a node or click the AnyLogic: The Add icon first and then select a node in the graphical editor.

The number of nodes you add as home locations determines the capacity of the resources. You can even add the same node multiple times in this parameter.

In the figure below, you can see that the ...based on attractors option is also selected. Then the ResourcePool block will count the number of attractors in the home node and treat that number as the number of the resource units in this pool.

If you define the capacity both with multiple nodes as the home locations and with attractors in those nodes, the total number of resources will be the sum of all elements.

AnyLogic: The ResourcePool block with its capacity defined by the number of attractors

Defining an operating schedule for the resources

You can define a work schedule for your resources. There are four different ways to use the AnyLogic: The Schedule icon Schedule element to define the capacity for the resources. The Schedule element is part of the Agent palette. You can also add the Clock element from the Pictures palette to the agent diagram to keep track of time at the model runtime.

  • By schedule — With a schedule that defines how the number of resources changes over time (the schedule Type is integer). For each of the intervals that you define in the schedule, you must specify the number of the resources that are available during this interval.

    AnyLogic: The number of resources defined by a schedule

  • By "on/off" schedule — With a schedule that defines how resource availability changes over time (the schedule Type is on/off). Here you define the intervals and set the type of value for each time period, on or off. Then, in the ResourcePool properties, you specify the number of the resources available during the on intervals. During the off intervals, 0 resources are available.

    AnyLogic: The number of resources defined by an on/off schedule

  • By shifts: group schedules — In the ResourcePool properties, select multiple schedules of integer type in the Schedules property:

    AnyLogic: The number of resources defined by a group schedule

    These schedules will all run at the same time creating the number of resource units according to the values in their intervals. You can create these schedules so that the shifts they define overlap or do not overlap:

    AnyLogic: Runtime: The number of resources defined by a group schedule

  • By shift plan — Define the capacity of resources in a schedule, but for different shifts, that is, a shift plan (for examples, see the shift plan Wikipedia page).
    You define the number of resources for each shift in the ResourcePool property Shift group sizes { size1, size2, … }. In the example below, the shift with the ID 1 contains 10 resource units, the shift with the ID 2 contains 8 resource units, and the shift with the ID 3 contains 5 units. The IDs are a simple count starting from 1 and so on, i.e. you do not need to define these IDs anywhere.
    Next, in the schedule of type integer, you assign a shift ID to each interval: the interval from 1 to 7 AM belongs to the shift with the ID 1. This means that during this interval, the number of resource units will be 10 as it is defined in the Shift group sizes { size1, size2, … } property.

    AnyLogic: The number of resources set by a shift plan

    At the model runtime, the schedule shows the shift IDs:

    AnyLogic: Runtime: The number of resources set by a shift plan

Demo model: Defining a Work Schedule for Resources Open the model page in AnyLogic Cloud. There you can run the model or download it (by clicking Model source files).

Parameters

In all dynamic parameters the resource unit is available as the unit local variable.

Resource type
The type of the resource units in this pool: Static, Moving, Portable.
Syntax: ResourceType type
Default value: Moving (ResourcePool.RESOURCE_MOVING)
Valid values:
ResourcePool.RESOURCE_MOVING
ResourcePool.RESOURCE_STATIC
ResourcePool.RESOURCE_PORTABLE
Capacity defined
Defines how the number of resource units is defined:
Directly — explicitly as a fixed number, in the Capacity field below.
By home location — it will be defined by the home location nodes (equal to the number of nodes specified as the Home location (nodes), or to the number of attractors inside these node(s), if the based on attractors option is selected).
By schedule — with a schedule that defines how the number of resources changes over time (the schedule Type is integer).
By "on/off" schedule — with a schedule that defines how the resources availability changes over time (the schedule Type is on/off).
By shifts: group schedules — here you can choose several schedules (integer) to define the resources’ capacity.
By shift plan — here you use one schedule (integer) to define the resources’ capacity for different shifts.
Syntax: ResourcePool.CapacityDefinitionType capacityDefinitionType
Default value: Directly (ResourcePool.CAPACITY_DIRECT)
Valid values:
ResourcePool.CAPACITY_DIRECT
ResourcePool.CAPACITY_HOME_LOCATION
ResourcePool.CAPACITY_SCHEDULE
ResourcePool.CAPACITY_SCHEDULE_ON_OFF
ResourcePool.CAPACITY_SHIFT_GROUP_SCHEDULES
ResourcePool.CAPACITY_SHIFT_PLAN
Capacity
[Visible if capacity is defined Directly]
The number of resource units in the pool.
Syntax: int capacity
Set new value at runtime: set_capacity(new value)
Default value: 1
When capacity decreases
[Visible if capacity is defined Directly, By schedule or By on/off schedule]
Select here what should be done with the excess units:
units are preserved ('End of shift') — units are retained alive when the capacity of pool decreases (this is like their shift ends) and reactivated when capacity recovers.
units are destroyed — once the capacity of pool decreases, all the excess units will be destroyed (and removed from their population, if any), so for the next capacity recovery, brand new units will be created.
Syntax: boolean destroyExcessUnits
Based on attractors
[Visible if capacity is defined By home location]
If selected, the number of resource units in the pool will be equal to the number of attractors inside the node specified as the Home location (nodes) for this resource pool. Otherwise the number of resources is equal to the number of Home location (nodes).
Syntax: boolean capacityBasedOnAttractors
Capacity schedule
[Visible if capacity is defined By schedule]
Schedule that defines how the number of resources changes over time (the schedule Type is integer).
Syntax: Schedule<integer> capacitySchedule
On/off schedule
[Visible if capacity is defined By "on/off" schedule]
Schedule that defines how the resources availability changes over time (the schedule Type is on/off).
When the schedule value is off — there are no resources.
When the schedule value is on — there are Capacity when "On" resources.
Syntax: Schedule<boolean> capacityScheduleOnOff
Capacity when "On"
[Visible if capacity is defined By "on/off" schedule]
The number of resource units in the pool when the schedule value is on.
Value type: int
Default value: 1
Schedules
[Visible if capacity is defined By shifts: group schedules]
Several schedules of the integer type.
Syntax: Schedule<integer>[] shiftGroupSchedules
Shift group sizes { size1, size2,.. }
[Visible if capacity is defined By shift plan]
Type the number of resources for each shift ID (delimited with commas).
Syntax: int[] shiftGroupSizes
Schedule of shift group IDs (1, 2,..)
[Visible if capacity is defined By shift plan] Schedule containing IDs of shiftGroups, where 1 = the first shift group.
Use -1 to mark common out-of-shift time when all shiftGroups are off.
Syntax: Schedule<integer> shiftGroupsPlan
New resource unit
Specify here the type of the resources in this resource pool. Referred below as T.
Default value: Agent
Speed
[Visible if the Resource type is Moving]
The speed with which resource units move.
Syntax: double speed
Default value: 10 meters per second
Home location (nodes)
Select the nodes that will be used as the home locations for these resources.
Syntax: INode[] homeNodes
Show default animation
[Visible if the Resource type is Static] If selected, and the resources are of default Agent type (not of some user-created custom resource type), the static resources will be animated as small multi-colored circles. This option is mostly used to check that the static resources are correctly placed in the desired nodes.
Syntax: boolean showDefaultAnimationStatic
Default value: true

Maintenance, failures, shifts, breaks

Specified by
Here you can select the way to define the downtime tasks for your resource pool. The default option is a Downtime block(s) — a list of Downtime blocks that describe the corresponding behavior. Alternatively, you can use the ResourcePool properties option to define the tasks from the ResourcePool block properties.
Syntax: ResourcePool.DowntimeSource downtimeSource
Set new value at runtime: set_downtimeSource(new value)
Valid values:
ResourcePool.DOWNTIME_LIST
ResourcePool.DOWNTIME_RESOURCE_POOL_PROPERTIES
Downtime block(s)
[Visible and applies only if the Specified by: Downtime block(s) option is selected]
Here you can list the Downtime blocks.
Syntax: Downtime[] downtimeList
Set new value at runtime: set_downtimeList(new value)
Maintenance
[Visible and applies only if the Specified by: ResourcePool properties option is selected]
If selected, the resource units of this pool will have maintenance. The maintenance task parameters are configured using the properties below.
Syntax: boolean enableMaintenance
Set new value at runtime: set_enableMaintenance(new value)
Initial time to maintenance
[Visible if Maintenance is enabled]
Time before the first maintenance.
Value type: double
Local variable: T unit — the resource unit
Time to next maintenance
[Visible if Maintenance is enabled]
Time between maintenance tasks (starts counting when the maintenance task ends).
Value type: double
Local variable: T unit — the unit.
'Maintenance' priority
[Visible if Maintenance is enabled]
The priority of the maintenance task. Higher value means higher priority. It will be compared to other task priorities when making decisions what task may preempt other, and so on.
Value type: double
Default value: 100
Local variable: T unit — the resource unit.
'Maintenance' may preempt
[Visible if Maintenance is enabled]
If selected, maintenance may preempt the currently performed task (if allowed in the task properties & the task priority is lower).
Value type: boolean
Local variable: T unit — the resource unit.
Maintenance type
[Visible if Maintenance is enabled]
Here you can choose how you simulate the maintenance: simply as a delay (Delay option), or as a complex process described by a specific flowchart (Send to flowchart option).
Syntax: ResourcePool.MaintenanceType maintenanceType
Valid values:
ResourcePool.MAINTENANCE_DELAY
ResourcePool.MAINTENANCE_FLOWCHART
Task start block (maintenance)
[Visible if Maintenance type is defined as Send to flowchart]
ResourceTaskStart block defining the start of the flowchart simulating the resource maintenance process.
Value type: ResourceTaskStart
Local variable: T unit — the resource unit.
Maintenance time
[Visible if Maintenance type is defined as Delay]
Maintenance time.
Value type: double
Local variable: T unit — the resource unit.
Usage statistics are
[Visible if Maintenance is enabled]
Here you choose whether you want to consider maintenance time in the collected usage statistics as “busy” time, “idle” time, or not take it into account at all.
Value type: ResourceUsageState
ResourcePool.USAGE_BUSY
ResourcePool.USAGE_IDLE
ResourcePool.USAGE_NOT_COUNTED
Local variable: T unit — the resource unit.
Failures / Repairs
[Visible and applies only if the Specified by: ResourcePool properties option is selected]
If selected, the resource units of this pool will have failures. The failures are configured using the properties below.
Syntax: boolean enableFailuresRepairs
Set new value at runtime: set_enableFailuresRepairs(new value)
Initial time to failure
[Visible if Failures / Repairs is enabled]
Time before the first failure.
Value type: double
Default value: uniform( 0, 1000 ) seconds
Local variable: T unit — the resource unit.
Time to next failure
[Visible if Failures / Repairs is enabled]
Time between failures (starts counting from the repair moment).
Value type: double
Local variable: T unit — the resource unit.
Count busy time only
If selected, the time between failures (time to failure) is counted only when the resource is busy with a task. Otherwise, the time to failure is counted unconditionally.
Syntax: boolean countBusyOnlyTimeToFailure
Repair type
[Visible if Failures / Repairs is enabled]
Here you can choose how you simulate the repair: simply as a delay (Delay option), or as a complex process described by a specific flowchart (Send to flowchart option).
Syntax: ResourcePool.RepairType repairType
Valid values:
ResourcePool.REPAIR_DELAY
ResourcePool.REPAIR_FLOWCHART
Task start block (repair)
[Visible if Repair type is defined as Send to flowchart]
ResourceTaskStart block defining the start of the flowchart simulating the resource repair process.
Value type: ResourceTaskStart
Local variable: T unit — the resource unit.
Time to repair
[Visible if Repair type is defined as Delay]
Time required to fix the failure.
Value type: double
Default value: triangularAV( 10, 0.1 ) seconds
Local variable: T unit — the resource unit.
Usage statistics are
[Visible if Failures / Repairs is enabled]
Here you choose whether you want to consider the failures in the collected usage statistics as “busy” time, “idle” time, or not take them into account at all.
Value type: ResourceUsageState
Valid values:
ResourcePool.USAGE_BUSY
ResourcePool.USAGE_IDLE
ResourcePool.USAGE_NOT_COUNTED
Local variable: T unit — the resource unit.
Breaks
[Visible and applies only if the Specified by: ResourcePool properties option is selected]
If selected, the resource units of this pool will have breaks. The breaks are configured using the properties below.
Syntax: boolean enableBreaks
Default value: false
Set new value at runtime: set_enableBreaks(new value)
Breaks schedule
[Visible if Breaks is enabled]
The schedule that defines the schedule of breaks for this resource pool (the schedule Type should be on/off).
Syntax: Schedule<boolean> breaksSchedule
'Break' priority
[Visible if Breaks is enabled]
The priority of the break task. Higher value means higher priority. It will be compared to other task priorities when making decisions what task may preempt other, and so on.
If a break has been defined by a schedule of any type and at the moment when it should start, the resource is still executing a task of a higher priority, then the break is delayed for as long as it takes the resource to complete the task of a higher priority.
Say, breaks are defined by an "on"/"off" schedule. The "on" interval defines the break and is set to 2 hours long. It repeats every 10 hours, therefore the "off" interval lasts for 8 hours. If a task with a higher priority takes up the first hour of the scheduled "on" interval, then the break will start from the second hour and last for the scheduled 2 hours. The "off" interval will decrease for the same amount of time that the higher priority task has taken up from the scheduled interval, and will last for 7 hours instead of 8.
Value type: double
Default value: 50
Local variable: T unit — the resource unit.
'Break' may preempt
[Visible if Breaks is enabled]
If selected, break may preempt the currently performed task (if allowed in the task properties & the task priority is lower).
Value type: boolean
Default value: false
Local variable: T unit — the resource unit.
'Break' preemption policy
[Visible if Breaks is enabled]
Here you can choose whether other tasks may terminate the current break (Terminate option), or not (No preemption option).
Value type: ResourcePreemptionPolicy
Valid values:
ResourcePool.PP_NO_PREEMPTION
ResourcePool.PP_TERMINATE
Local variable: T unit — the resource unit.
Usage statistics are
[Visible if Breaks is enabled]
Here you choose whether you consider breaks time in the collected usage statistics as “busy” time, “idle” time, or not take it into account at all.
Value type: ResourceUsageState
Valid values:
ResourcePool.USAGE_BUSY
ResourcePool.USAGE_IDLE
ResourcePool.USAGE_NOT_COUNTED
Local variable: T unit — the resource unit.
Custom tasks
[Visible and applies only if the Specified by: ResourcePool properties option is selected]
If selected, you can define more tasks for the resources with Downtime blocks. Use this option when your task cannot be defined with standard patterns provided for failures, breaks, maintenance.
Syntax: boolean enableCustomTasks
List of tasks
[Visible if Custom tasks is enabled]
The list of Downtime blocks of Custom type defining additional custom tasks for these resources.
Syntax: DowntimeDescriptor[] customTasks
Set new value at runtime: set_customTasks(new value)
'End of shift' priority
The priority of the shift schedule. Higher value means higher priority.
Value type: double
Default value: 100
Local variable: T unit — the resource unit.
'End of shift' may preempt
Sets whether End of shift task may preempt the task currently being executed, if any. In other words, true means that unit will “drop its work” right at the moment of its shift end. If false, then the unit will finish all its tasks with less priority.
Value type: boolean
Default value: false
Local variable: T unit — the resource unit.
'End of shift' preemption policy
Here you can choose whether other tasks may terminate the current task (Terminate option), or not (No preemption option).
Value type: ResourcePreemptionPolicy
Default value: No Preemption(ResourcePool.PP_NO_PREEMPTION)
Local variable: T unit — the resource unit.

Advanced

Customize request choice
If the option is selected, the resource units will take into account the specified Request choice condition when accepting the task.
Syntax: boolean customizeRequestChoice
Default value: false
Request choice condition
[Visible if Customize request choice is selected]
Here you can specify a boolean expression that will be checked before the resource unit(s) accepts the task. If none of the available tasks satisfy the specified condition (the condition returns false), the unit will remain idle. If the condition returns true, the resource unit will select the task with the highest priority.
Value type: boolean
Default value: true
Local variables:
agent — the agent.
unit — the resource unit.
self — the resource pool.
Add units to
Here you specify where the resource units created by this block will be stored: in the default population of the top-level agent of the model or in a custom population (specified below in the Population property). The default population (Java collection of type AgentList) contained in the top-level agent can be accessed with the function getDefaultPopulation().
Syntax: boolean addToCustomPopulation
Default value: default population (false)
Population
[Visible if Add units to: custom population]
The name of the agent population where the units created by this block will be stored.
Value type: AgentList
Local variable: T unit — the resource unit.
Force statistics collection
This block collects statistics, both for itself and the resource units it contains.
If the statistics collection is turned off for all Process Modeling Library blocks in the model by the PMLSettings, this option enables you to override this setting and collect the statistics for this specific block. Otherwise, the statistics will be collected regardless of this setting’s value.
For more information regarding the statistics collected by individual resource units, see the section on utilization statistics.
Syntax: boolean forceStatisticsCollection
Default value: false

Actions

On new unit
Code executed when a new resource unit is generated and can be used to do additional setup.
Local variable: T unit — a freshly created resource unit.
On destroy unit
Code executed when a resource unit is destroyed.
Local variable: T unit — the resource unit.
On seize
Code executed when a resource unit is seized.
Local variables:
T unit — the resource unit.
Agent agent — the agent that seized the unit.
On release
Code executed when a resource unit is released.
Local variables:
T unit — the resource unit.
Agent agent — the agent.
On wrap up
Code executed when a resource unit is wrapped up.
Local variables:
T unit — the resource unit.
Agent agent — the agent.
On unit state changed
Code executed when a resource unit changes its activity.
Local variables:
T unit — the resource unit.
boolean busy — true if the unit is busy (this doesn’t mean that it was idle before), false if idle.
ResourceTaskType type — type of task, if unit is busy, one of: TASK_ENTITY, TASK_END_OF_SHIFT, TASK_WRAP_UP, TASK_BREAK, TASK_REPAIR, TASK_MAINTENANCE, TASK_CUSTOM constants.
Agent agent — agent associated with this resource unit’s task. Actual for TASK_ENTITY type (where it is the agent possessing the unit) and for TASK_WRAP_UP (agent which previously used this unit and has recently released it).
Downtime task — task descriptor, this can be used in case of TASK_CUSTOM type: there will be a reference to Downtime block which represents the current task of the unit.
On maintenance start
[Visible if Maintenance is enabled]
Code executed when a resource unit starts maintenance task.
Local variable: T unit — the resource unit.
On maintenance end
[Visible if Maintenance is enabled]
Code executed when a resource unit finishes maintenance task.
Local variable: T unit — the resource unit.
On failure
[Visible if Failures / Repairs is enabled]
Code executed on when the failure task starts.
Local variable: T unit — the resource unit.
On repair
[Visible if Failures / Repairs is enabled]
Code executed when the repair task ends.
Local variable: T unit — the resource unit.
On break start
[Visible if Breaks is enabled]
Code executed when a resource unit starts break task.
Local variable: T unit — the resource unit.
On break end
[Visible if Breaks is enabled]
Code executed when a resource unit finishes break task.
Local variable: T unit — the resource unit.
On break terminated
[Visible if Breaks is enabled]
Code executed when break task is terminated.
Local variable: T unit — the resource unit.

Functions

Resources and their utilization
Function Description
int idle() Returns the number of currently idle resource units. Off-shift units aren’t counted.
int busy() Returns the number of busy units, including those who are in wrap-up/maintenance/break/failure. Off-shift units aren’t counted.
int size() Returns the total number of units in this resource pool (including those that are off shift).
int sizeActive() Returns the total number of resource units in the current shift.
boolean containsUnit(Agent unit) Checks whether the resource pool contains the specified unit. Returns true if it does, false otherwise.

unit — The agent (resource unit) to check for.
double utilization() Returns the utilization of this resource pool. The returned value is the mean over all individual unit utilization, calculated from the last resetStats() call to the current time. If the number and availability of resource units is defined by a schedule, the utilization is calculated only for the operating hours of the corresponding resource unit.
Collection<ResourceRequest> getRequests() Returns the current queue of requests for resource units of this pool, ordered by their priority.
This list is unmodifiable.
Iterator<Agent> iterator Returns the iterator over all units within this pool.
Shift groups
Function Description
void setShiftGroupCapacity(int id, int capacity) Sets new size of shift group. Does not destroy excess resource units, instead assigns them out-of-shift task to them (idle units are pushed out-of-shift first, followed by units with lower priority tasks).

id — The unique identifier of the shift group (1, 2, 3, …).
capacity — The new size of the shift group.
int sizeOfShiftGroup(int id) Returns the total number of units (including off-shift units) in the shift group with the given ID.

id — The unique identifier of the shift group (1, 2, 3, …).
Statistics
Function Description
boolean isStatisticsCollected() Returns true if the block collects statistics.
void resetStats() Resets the statistics collected for this block.
How can we improve this article?