Configuring Parameters
This guide provides practical advice for tuning simulation parameters to model different banking scenarios and achieve desired system behaviors.
The Golden Rule: Traffic Intensity
Before configuring anything else, understand this fundamental relationship:
ρ = λ / (c * μ)
Where:
ρ (rho) = Traffic intensity (utilization)
λ (lambda) = arrival_rate (customers/second)
c = num_tellers
μ (mu) = service_rate = 1/service_mean (customers/second per teller)
Critical Rule: ρ must be < 1.0 for system stability!If ρ ≥ 1.0, queues will grow unbounded.
Target Utilization Ranges
ρ Range System State Recommendation < 0.3 Underutilized Reduce tellers or increase arrival rate 0.3-0.5 Light load Good for off-peak hours 0.5-0.7 Moderate load Optimal for most scenarios 0.7-0.85 Heavy load Peak hours, expect longer queues 0.85-0.95 Very heavy Stressful conditions, long waits > 0.95 Near saturation System barely stable ≥ 1.0 UNSTABLE Will fail - increase capacity!
Tuning Arrival Rate (λ)
Understanding Arrival Rate
From simulation_config.py:15:
"arrival_rate" : 1.0 # customers per second
Conversion reference:
# Convert between units
customers_per_second = arrival_rate
customers_per_minute = arrival_rate * 60
customers_per_hour = arrival_rate * 3600
# Examples:
λ = 0.5 → 0.5 / s = 30 / min = 1800 / hour
λ = 1.0 → 1.0 / s = 60 / min = 3600 / hour
λ = 2.0 → 2.0 / s = 120 / min = 7200 / hour
Scenario-Based Configuration
Off-Peak Hours
Normal Business Hours
Peak Hours (Lunch)
Special Event
Characteristics:
Few customers
Tellers often idle
Minimal wait times
arrival_config = {
"arrival_rate" : 0.3 , # 18 customers/minute
"arrival_dist" : "exponential" ,
"priority_weights" : [ 0.1 , 0.3 , 0.6 ]
}
num_tellers = 2
service_mean = 8.0
# Check: ρ = 0.3 / (2 * 1/8) = 0.3 / 0.25 = 1.2 ❌ UNSTABLE!
# Fix: Use 3 tellers
# ρ = 0.3 / (3 * 0.125) = 0.8 ✓
Characteristics:
Steady customer flow
Moderate queue lengths
Balanced utilization
arrival_config = {
"arrival_rate" : 1.0 , # 60 customers/minute
"arrival_dist" : "exponential" ,
"priority_weights" : [ 0.15 , 0.3 , 0.55 ]
}
num_tellers = 6
service_mean = 5.0
# Check: ρ = 1.0 / (6 * 0.2) = 1.0 / 1.2 = 0.83 ✓
Characteristics:
High customer volume
Long queues
All tellers busy
arrival_config = {
"arrival_rate" : 2.5 , # 150 customers/minute
"arrival_dist" : "exponential" ,
"priority_weights" : [ 0.2 , 0.35 , 0.45 ] # More high-priority
}
num_tellers = 15
service_mean = 6.0
# Check: ρ = 2.5 / (15 * 1/6) = 2.5 / 2.5 = 1.0 ⚠️ MARGINAL!
# Better: Use 18 tellers
# ρ = 2.5 / (18 * 1/6) = 2.5 / 3.0 = 0.83 ✓
Characteristics:
Extreme volume
Temporary surge
Maximum staffing
arrival_config = {
"arrival_rate" : 5.0 , # 300 customers/minute!
"arrival_dist" : "exponential" ,
"priority_weights" : [ 0.1 , 0.2 , 0.7 ]
}
num_tellers = 30
service_mean = 4.0
# Check: ρ = 5.0 / (30 * 0.25) = 5.0 / 7.5 = 0.67 ✓
Fine-Tuning Tips
When: Modeling busier periodsSteps:
Double arrival_rate
Recalculate ρ
If ρ > 0.85, increase num_tellers proportionally
Run simulation and observe queue length
# Before
λ = 1.0 , c = 3 , μ = 0.2 → ρ = 1.0 / 0.6 = 1.67 ❌
# After: Increase tellers
λ = 1.0 , c = 6 , μ = 0.2 → ρ = 1.0 / 1.2 = 0.83 ✓
When: Modeling slower periods or testing light loadEffect: Lower utilization, shorter queues, potential idle tellers# Can reduce tellers when arrival_rate drops
λ = 0.5 (was 1.0 ), c = 6 → ρ = 0.5 / 1.2 = 0.42
# Optimize: Use 3 tellers
λ = 0.5 , c = 3 → ρ = 0.5 / 0.6 = 0.83 ✓
If you have actual customer counts: # Example: Bank served 3,600 customers in 8 hours
total_customers = 3600
duration_seconds = 8 * 3600
observed_arrival_rate = total_customers / duration_seconds
# = 3600 / 28800 = 0.125 customers/second
# Use this as your arrival_rate
arrival_config = { "arrival_rate" : 0.125 }
Tuning Service Time
Understanding Service Mean
From simulation_config.py:21-22:
"service_mean" : 5.0 , # seconds per customer
"service_dist" : "exponential"
Service rate:
μ = 1 / service_mean
# Examples:
service_mean = 5.0 → μ = 0.2 customers / second per teller
service_mean = 10.0 → μ = 0.1 customers / second per teller
service_mean = 2.0 → μ = 0.5 customers / second per teller
Transaction Type Scenarios
ATM-like (Fast) service_config = {
"service_mean" : 2.0 ,
"service_dist" : "exponential"
}
Simple transactions: balance check, quick deposit
Standard Teller service_config = {
"service_mean" : 5.0 ,
"service_dist" : "exponential"
}
Typical transactions: deposits, withdrawals, transfers
Complex Service service_config = {
"service_mean" : 15.0 ,
"service_dist" : "normal" ,
"service_stddev" : 3.0
}
Account opening, loan inquiries
Loan Processing service_config = {
"service_mean" : 180.0 , # 3 minutes
"service_dist" : "normal" ,
"service_stddev" : 30.0
}
Detailed loan applications
Choosing Service Distribution
Exponential (Default)
Normal
Constant
service_config = {
"service_mean" : 5.0 ,
"service_dist" : "exponential"
}
Characteristics:
High variability (Coefficient of Variation = 1)
Some customers very quick (0.5s), others very slow (20s)
Memoryless property
Realistic for diverse transaction types
Use when: Modeling real-world heterogeneous transactionsservice_config = {
"service_mean" : 10.0 ,
"service_dist" : "normal" ,
"service_stddev" : 2.0 # CV = 0.2
}
Characteristics:
Moderate variability
Most customers near the mean (10±2 seconds)
More predictable than exponential
Minimum time enforced at 1.0 second
Use when: Transactions are relatively standardizedservice_config = {
"service_mean" : 5.0 ,
"service_dist" : "constant"
}
Characteristics:
Zero variability
Every customer takes exactly 5.0 seconds
Deterministic
Unrealistic but useful for testing
Use when: Theoretical analysis or debugging
Impact on System Capacity
# Scenario 1: Fast service
num_tellers = 3
service_mean = 3.0
system_capacity = 3 * ( 1 / 3.0 ) = 1.0 customers / second
# Can handle arrival_rate up to 0.75 (ρ = 0.75)
# Scenario 2: Slow service
num_tellers = 3
service_mean = 10.0
system_capacity = 3 * ( 1 / 10.0 ) = 0.3 customers / second
# Can only handle arrival_rate up to 0.225 (ρ = 0.75)
If you can’t add more tellers, reducing service_mean (faster service) increases capacity.
Tuning Number of Tellers
def calculate_required_tellers ( arrival_rate , service_mean , target_rho = 0.75 ):
"""
Calculate minimum tellers needed for target utilization.
"""
service_rate = 1.0 / service_mean
required = arrival_rate / (target_rho * service_rate)
return math.ceil(required)
# Example:
required_tellers = calculate_required_tellers(
arrival_rate = 2.0 ,
service_mean = 8.0 ,
target_rho = 0.75
)
# = ceil(2.0 / (0.75 * 0.125))
# = ceil(21.33)
# = 22 tellers
Practical Guidelines
Start with theoretical minimum
min_tellers = ceil(arrival_rate * service_mean)
# This gives ρ = 1.0 (unstable)
Add safety margin
# For ρ = 0.75 (recommended)
recommended_tellers = ceil(min_tellers / 0.75 )
# For ρ = 0.85 (high utilization)
high_util_tellers = ceil(min_tellers / 0.85 )
Account for variability
With exponential service times, add 10-20% more tellers than theoretical
Validate with simulation
Run simulation and check:
Queue length stays manageable (< 10)
Wait times acceptable (< 2 minutes)
Utilization in target range
Teller Allocation Scenarios
Small Branch Characteristics: 2-4 tellersconfig = SimulationConfig(
num_tellers = 3 ,
arrival_config = { "arrival_rate" : 0.4 },
service_config = { "service_mean" : 6.0 }
)
# ρ = 0.4 / (3 * 1/6) = 0.8
Medium Branch Characteristics: 5-8 tellersconfig = SimulationConfig(
num_tellers = 6 ,
arrival_config = { "arrival_rate" : 1.2 },
service_config = { "service_mean" : 5.0 }
)
# ρ = 1.2 / (6 * 0.2) = 1.0 ⚠️
# Use 8: ρ = 0.75 ✓
Large Branch Characteristics: 10-15 tellersconfig = SimulationConfig(
num_tellers = 12 ,
arrival_config = { "arrival_rate" : 2.0 },
service_config = { "service_mean" : 6.0 }
)
# ρ = 2.0 / (12 * 1/6) = 1.0 ⚠️
# Use 16: ρ = 0.75 ✓
Mega Branch Characteristics: 20+ tellersconfig = SimulationConfig(
num_tellers = 25 ,
arrival_config = { "arrival_rate" : 3.5 },
service_config = { "service_mean" : 8.0 }
)
# ρ = 3.5 / (25 * 0.125) = 1.12 ❌
# Use 40: ρ = 0.7 ✓
Tuning Priority Weights
Understanding Priority Distribution
From simulation_config.py:17:
"priority_weights" : [ 0.1 , 0.3 , 0.6 ] # [HIGH, MEDIUM, LOW]
Must sum to 1.0:
P( HIGH ) + P( MEDIUM ) + P( LOW ) = 1.0
0.1 + 0.3 + 0.6 = 1.0 ✓
Demographic-Based Scenarios
Impact on Wait Times
# Example simulation results with different priority_weights
# Scenario A: [0.1, 0.3, 0.6] (Default)
wait_times = {
"high" : 0.8 , # seconds
"medium" : 3.5 ,
"low" : 8.2
}
# Scenario B: [0.4, 0.3, 0.3] (Many high-priority)
wait_times = {
"high" : 2.1 , # Increased (more competition)
"medium" : 6.5 , # Increased (wait for high)
"low" : 15.3 # Significantly increased!
}
# Scenario C: [0.05, 0.15, 0.8] (Few high-priority)
wait_times = {
"high" : 0.2 , # Very low
"medium" : 2.8 ,
"low" : 5.1 # Improved (less preemption)
}
Starvation risk: If priority_weights[0] (HIGH) is too large and arrival_rate is high, low-priority customers may wait indefinitely!
Complete Configuration Examples
Example 1: Balanced Small Bank
config = SimulationConfig(
num_tellers = 4 ,
arrival_config = {
"arrival_rate" : 0.6 , # 36 customers/minute
"arrival_dist" : "exponential" ,
"priority_weights" : [ 0.1 , 0.3 , 0.6 ]
},
service_config = {
"service_mean" : 6.0 , # 6 seconds average
"service_dist" : "normal" ,
"service_stddev" : 1.5
},
max_simulation_time = 3600.0 , # 1 hour
max_queue_capacity = 50
)
# Analysis:
# ρ = 0.6 / (4 * 1/6) = 0.6 / 0.667 = 0.9 ⚠️ HIGH
# Recommendation: Use 5 tellers for ρ = 0.72 ✓
Example 2: Peak Hour Large Bank
config = SimulationConfig(
num_tellers = 20 ,
arrival_config = {
"arrival_rate" : 2.5 ,
"arrival_dist" : "exponential" ,
"priority_weights" : [ 0.2 , 0.35 , 0.45 ]
},
service_config = {
"service_mean" : 8.0 ,
"service_dist" : "exponential"
},
max_simulation_time = 7200.0 , # 2 hours
max_queue_capacity = 150
)
# Analysis:
# ρ = 2.5 / (20 * 0.125) = 2.5 / 2.5 = 1.0 ❌ MARGINAL
# Recommendation: Use 27 tellers for ρ = 0.74 ✓
Example 3: Stress Test
config = SimulationConfig(
num_tellers = 10 ,
arrival_config = {
"arrival_rate" : 3.0 , # Intentionally high
"arrival_dist" : "exponential" ,
"priority_weights" : [ 0.15 , 0.3 , 0.55 ]
},
service_config = {
"service_mean" : 10.0 , # Slow service
"service_dist" : "exponential"
},
max_simulation_time = 1800.0 , # 30 minutes
max_queue_capacity = 200
)
# Analysis:
# ρ = 3.0 / (10 * 0.1) = 3.0 ❌ VERY UNSTABLE
# Purpose: Observe system breakdown, queue explosion
Validation Checklist
Before running your simulation:
Calculate ρ
rho = arrival_rate / (num_tellers * ( 1 / service_mean))
Ensure ρ < 1.0 (preferably < 0.85)
Check priority weights sum
assert sum (priority_weights) == 1.0
Verify distributions
arrival_dist in [“exponential”, “fixed”]
service_dist in [“exponential”, “normal”, “constant”]
Sanity check values
arrival_rate > 0
service_mean > 0
num_tellers ≥ 1
max_simulation_time > 0
Further Reading
Configuration Reference Complete parameter documentation
Running Simulations Step-by-step execution guide
Interpreting Metrics Understanding simulation results
Advanced Scenarios Complex configuration patterns