2. Priority-Based Resource Scheduling

2.1. Overview

In real-world project management, not all requests for resources are equal. Emergency repairs, critical work, and VIP tasks often need priority over routine operations. SimPM’s PriorityResource allows entities to request resources with different priority levels, ensuring that higher-priority work gets served first—regardless of arrival order.

This tutorial explores priority-based resource scheduling, showing you how to model scenarios where work importance matters as much as work timing.

2.1.1. Key Concepts

Priority Resource

A PriorityResource uses priority values to order requests in the queue. Higher priority requests are served before lower priority ones, even if they arrived later.

Priority Values
  • Positive values (1, 2, 3…): Standard priority; lower numbers = higher priority

  • Negative values (-1, -2, -3…): Higher priority; more negative = higher priority

  • Example: priority=-3 > priority=2 > priority=1

Service Order

When multiple entities request a resource, SimPM serves them in order of their priority values, not their arrival order. Once served, entities hold the resource until they release it.

2.1.2. Use Cases

Priority-based resources are essential for:

  • Emergency repairs – Broken equipment gets fixed before routine maintenance

  • Maintenance scheduling – Critical maintenance preempts regular work

  • Hospital operations – Emergency patients served before routine appointments

  • Construction site management – Safety issues get immediate crew attention

  • IT operations – Critical system failures get immediate technician response

2.2. Scenario: Equipment Supply Queue

Imagine a construction site with a limited equipment depot supplying trucks:

  • Depot capacity: 3 trucks available

  • Three contractors requesting trucks:

    • Contractor A (regular work): priority=1, needs 3 trucks

    • Contractor B (important project): priority=2, needs 2 trucks

    • Contractor C (urgent repair): priority=-3 (very high), needs 2 trucks, arrives late

  • Depot operator: Periodically releases trucks back to the depot (adds supply)

The question: In what order do contractors get served?

Answer: By priority! Contractor C (highest priority) gets trucks first, despite arriving last.

2.3. Detailed Code Example

Here’s the complete priority resource example with step-by-step explanation:

import simpm
from simpm.des import *

# ========================================
# 1. Define Process Functions
# ========================================

def contractor_a_process(env, entity, resource):
    """
    Contractor A: Regular work at priority 1 (low).
    Requests 3 trucks; will wait due to lower priority.
    """
    print(f'{env.now:.2f}: {entity.name} requests 3 trucks (priority 1)')
    yield entity.get(resource, 3, priority=1)
    print(f'{env.now:.2f}: {entity.name} got 3 trucks')

def contractor_b_process(env, entity, resource):
    """
    Contractor B: Important project at priority 2 (medium).
    Requests 2 trucks; served after high-priority work.
    """
    print(f'{env.now:.2f}: {entity.name} requests 2 trucks (priority 2)')
    yield entity.get(resource, 2, priority=2)
    print(f'{env.now:.2f}: {entity.name} got 2 trucks')

def contractor_c_process(env, entity, resource):
    """
    Contractor C: Urgent repair at priority -3 (highest).
    Waits 1 time unit, then requests; gets trucks FIRST due to high priority.
    """
    yield entity.do('wait', 1)
    print(f'{env.now:.2f}: {entity.name} requests 2 trucks (priority -3 - URGENT)')
    yield entity.get(resource, 2, priority=-3)
    print(f'{env.now:.2f}: {entity.name} got 2 trucks (SERVED FIRST)')

def depot_operator_process(env, operator, resource):
    """
    Depot Operator: Periodically releases trucks back to inventory.

    Schedule:
    - t=3: Return 3 trucks
    - t=6: Return 2 trucks
    - t=8: Return 3 trucks
    """
    yield operator.do('wait', 3)
    print(f'{env.now:.2f}: Depot returns 3 trucks')
    yield operator.add(resource, 3)

    yield operator.do('wait', 3)
    print(f'{env.now:.2f}: Depot returns 2 trucks')
    yield operator.add(resource, 2)

    yield operator.do('wait', 2)
    print(f'{env.now:.2f}: Depot returns 3 trucks')
    yield operator.add(resource, 3)

# ========================================
# 2. Set Up Simulation
# ========================================

env = Environment()

# Create entities (contractors and operator)
contractor_a = Entity(env, 'Contractor_A', log=True)
contractor_b = Entity(env, 'Contractor_B', log=True)
contractor_c = Entity(env, 'Contractor_C', log=True)
operator = Entity(env, 'Depot_Operator', log=True)

# Create PriorityResource (depot with limited trucks)
depot = PriorityResource(
    env,
    'Truck_Depot',
    init=0,              # Start empty (no trucks)
    capacity=3,          # Maximum 3 trucks
    print_actions=True,  # Print all get/add operations
    log=True             # Log all events
)

# ========================================
# 3. Start Processes
# ========================================

env.process(contractor_a_process(env, contractor_a, depot))
env.process(contractor_b_process(env, contractor_b, depot))
env.process(operator_process(env, operator, depot))
env.process(contractor_c_process(env, contractor_c, depot))

# ========================================
# 4. Run Simulation
# ========================================

simpm.run(env, dashboard=True)

2.3.1. How It Works

Timeline of Events:

t=0.00: Contractor_A requests 3 trucks (priority 1)
        → Waits (depot empty)

t=0.00: Contractor_B requests 2 trucks (priority 2)
        → Waits (depot empty, lower priority than C)

t=0.00: Depot_Operator starts work
        → Will return trucks at t=3, t=6, t=8

t=1.00: Contractor_C requests 2 trucks (priority -3 - HIGHEST)
        → Waits (depot empty, but is now first in queue)

t=3.00: Depot returns 3 trucks
        → Contractor_C gets 2 trucks FIRST (priority -3)
        → 1 truck remains in depot

t=6.00: Depot returns 2 trucks
        → 3 trucks now available
        → Contractor_B gets 2 trucks (priority 2)
        → 1 truck remains

t=8.00: Depot returns 3 trucks
        → 4 trucks available
        → Contractor_A gets 3 trucks (priority 1)
        → 1 truck remains

Key Observations:

  1. Priority overrides arrival order: Contractor C arrives at t=1, but gets trucks at t=3 when they become available, because priority=-3 > priority=2 > priority=1.

  2. Queue management: The resource automatically maintains a priority queue and serves highest-priority requests first when capacity becomes available.

  3. Waiting times: - Contractor A: Arrives t=0, served t=8 (waits 8 time units) - Contractor B: Arrives t=0, served t=6 (waits 6 time units) - Contractor C: Arrives t=1, served t=3 (waits only 2 time units, thanks to high priority!)

2.4. Advanced Topics

Multiple Priority Levels

You can use any integer priority value. For example, in a hospital:

routine_checkup = Priority(priority=10)      # Low priority
important_surgery = priority(priority=0)     # Medium priority
emergency_trauma = priority(priority=-100)   # Very high priority

Combining with Other Resource Types

Priority resources work alongside regular resources:

# Regular resource (FIFO queue)
general_crew = Resource(env, 'General_Crew', capacity=2)

# Priority resource (ordered by priority value)
emergency_crew = PriorityResource(env, 'Emergency_Crew', capacity=1)

# Entity requests both
yield entity.get(general_crew, 1)      # Gets in line, first come first served
yield entity.get(emergency_crew, 1)    # Gets in line by priority

Dynamic Priority Changes

Priorities can be adjusted during simulation based on conditions:

# Initial request at low priority
yield entity.get(resource, 1, priority=10)

# If conditions change, higher-priority request can interrupt (see PreemptiveResource)
yield entity.get(resource, 1, priority=-10, preempt=True)

2.5. Try It Yourself

Experiment 1: Change Priority Values

What happens if you change Contractor C’s priority from -3 to 3? Now it has the lowest priority! Try it and observe the new service order.

Experiment 2: Add More Contractors

Add a fourth contractor with priority=0 (between B and C). How does this change the service order?

Experiment 3: Increase Depot Capacity

Change capacity=3 to capacity=5. Do all contractors get served immediately when trucks are available?

Experiment 4: Use the Dashboard

Enable the dashboard (default: dashboard=True). Explore: - Timeline view: See when each contractor gets trucks - Queue view: See how the priority queue changes over time - Resource utilization: How many trucks are in use at each time?

2.6. Next Steps