Example: Capacity Planning

Simple capacity planing example that shows how a supply chain solver consumes capacity

Purpose

Capacity planning is where supply chain solvers get complicated, but it's also where they prove their value. It's easy to calculate material needs in an unconstrained world: multiply demand for finished goods by material usage rates on the BOMs. This is essential for materials replenishment planning, but what happens when you need to consider constraints? Supply Planners rely on capacity solvers to answer:

With the above info, supply planners can try to resolve capacity constraints before they materialize or at least inform Sales and Leadership that the current demand plan isn't attainable without major investments or adjustments.

About Example

In this example, the production of one unit of finished good, fg_1, uses:

The solver plans for 4 demands and gets different outputs:

Final Notes from Bill

This is a more complicated example, so take your time to review. Getting capacity planning to work in the chaos solver and digital twin visualizer was way more complex than I planned, but it looks elegant now. The ability for the solver to replan the BOM based on constraints to any inputs, allows the solver to avoid over planning need for materials or capacity when even one input constrains.


bom_capacity

bom_id capacity_id capacity_usage_rate
1 labour_hours 2
1 machine_hours 8

bom_ids

bom_id location lead_time_days
1 factory_1 5

bom_inputs

bom_id input_item input_qty
1 rm_1 1.0
1 rm_2 2.0
1 rm_3 0.5

bom_outputs

bom_id output_item output_qty
1 fg_1 1

capacity_quantities

capacity_id start end capacity_qty note
labour_hours 4/14/2024 4/21/2024 40 tracked in weeks
labour_hours 4/21/2024 4/28/2024 40 NaN
labour_hours 4/28/2024 5/5/2024 40 NaN
labour_hours 5/5/2024 5/12/2024 40 NaN
labour_hours 5/12/2024 5/19/2024 40 NaN
labour_hours 5/19/2024 5/26/2024 40 NaN
labour_hours 5/26/2024 6/2/2024 40 NaN
labour_hours 6/2/2024 6/9/2024 40 NaN
labour_hours 6/9/2024 6/16/2024 40 NaN
machine_hours 4/1/2024 5/1/2024 100 tracked in months
machine_hours 5/1/2024 6/1/2024 100 NaN

demand

location item need_date demand_qty demand_key
factory_1 fg_1 5/30/2024 1 2024
factory_1 fg_1 5/30/2023 1 2023
factory_1 fg_1 5/30/2025 1 2025
factory_1 fg_1 5/30/2024 100 2024_large

item_location

item location genesis
rm_1 factory_1 True
rm_2 factory_1 True
rm_3 factory_1 True

capacity_pegging

capacity_id consumption_date capacity_consumed_qty bom_id demand_key
machine_hours 2024-05-25 8.0 1 2024
machine_hours 2024-05-25 92.0 1 2024_large
labour_hours 2024-05-25 2.0 1 2024
labour_hours 2024-05-25 23.0 1 2024_large

capacity_utilization

capacity_id start end capacity_qty capacity_consumed_qty capacity_utilization
labour_hours 2024-04-14 2024-04-21 40 0 0.000
labour_hours 2024-04-21 2024-04-28 40 0 0.000
labour_hours 2024-04-28 2024-05-05 40 0 0.000
labour_hours 2024-05-05 2024-05-12 40 0 0.000
labour_hours 2024-05-12 2024-05-19 40 0 0.000
labour_hours 2024-05-19 2024-05-26 40 25 0.625
labour_hours 2024-05-26 2024-06-02 40 0 0.000
labour_hours 2024-06-02 2024-06-09 40 0 0.000
labour_hours 2024-06-09 2024-06-16 40 0 0.000
machine_hours 2024-04-01 2024-05-01 100 0 0.000
machine_hours 2024-05-01 2024-06-01 100 100 1.000

item_location_peggings

item location activity activity_date pegged_qty demand_key
rm_1 factory_1 0_item_genesis 2024-05-25 1.00 2024
rm_2 factory_1 0_item_genesis 2024-05-25 2.00 2024
rm_3 factory_1 0_item_genesis 2024-05-25 0.50 2024
rm_1 factory_1 0_item_genesis 2024-05-25 11.50 2024_large
rm_2 factory_1 0_item_genesis 2024-05-25 23.00 2024_large
rm_3 factory_1 0_item_genesis 2024-05-25 5.75 2024_large
rm_1 factory_1 6_BOM_input 2024-05-25 1.00 2024
rm_2 factory_1 6_BOM_input 2024-05-25 2.00 2024
rm_3 factory_1 6_BOM_input 2024-05-25 0.50 2024
rm_1 factory_1 6_BOM_input 2024-05-25 11.50 2024_large
rm_2 factory_1 6_BOM_input 2024-05-25 23.00 2024_large
rm_3 factory_1 6_BOM_input 2024-05-25 5.75 2024_large
fg_1 factory_1 3_BOM_output 2024-05-30 1.00 2024
fg_1 factory_1 3_BOM_output 2024-05-30 11.50 2024_large

shipments

level from_location to_location item ship_date arrival_date shipment_qty demand_key

Loading Supply Chain Network from Files
Running obo Solver
***Starting to plan for demand key 2024***
At factory_1 on 2024-05-30: Searching inventory for 1 units of fg_1
At factory_1: No inventory for fg_1
At factory_1: Searching BomOutputEdge BOM-1 to fg_1-factory_1 with LT 5.0 days
--At BOM 1 capacity 1/2: Requesting for 2 units of capacity
----At CapacityNode-labour_hours on 2024-05-25: Searching for 2 units of capacity
----At CapacityNode-labour_hours: 40 available during period 2024-05-19 to 2024-05-26
----At CapacityNode-labour_hours: All 2 capacity exists
--At BOM 1 capacity 1/2: Found all needed capacity
--At BOM 1 capacity 2/2: Requesting for 8 units of capacity
----At CapacityNode-machine_hours on 2024-05-25: Searching for 8 units of capacity
----At CapacityNode-machine_hours: 100 available during period 2024-05-01 to 2024-06-01
----At CapacityNode-machine_hours: All 8 capacity exists
--At BOM 1 capacity 2/2: Found all needed capacity
--At BOM 1 input 1/3: Searching for 1.0 of rm_1
----At factory_1 on 2024-05-25: Genesis Node for rm_1. All 1.0 need satisfied
--At BOM 1 input 1/3: Found all supply for rm_1
--At BOM 1 input 2/3: Searching for 2.0 of rm_2
----At factory_1 on 2024-05-25: Genesis Node for rm_2. All 2.0 need satisfied
--At BOM 1 input 2/3: Found all supply for rm_2
--At BOM 1 input 3/3: Searching for 0.5 of rm_3
----At factory_1 on 2024-05-25: Genesis Node for rm_3. All 0.5 need satisfied
--At BOM 1 input 3/3: Found all supply for rm_3
--At BOM 1: Done searching all inputs
At factory_1: Found 1/1 on edge BOM-1 to fg_1-factory_1
At factory_1: Found all supply. Done searching edges of fg_1-factory_1
***Found 100.00% supply for demand key 2024***
***Starting to plan for demand key 2023***
At factory_1 on 2023-05-30: Searching inventory for 1 units of fg_1
At factory_1: No inventory for fg_1
At factory_1: Searching BomOutputEdge BOM-1 to fg_1-factory_1 with LT 5.0 days
--At BOM 1 capacity 1/2: Requesting for 2 units of capacity
----At CapacityNode-labour_hours on 2023-05-25: Searching for 2 units of capacity
----At CapacityNode-labour_hours: no capacity exists during 2023-05-25 00:00:00. Failed to gather capacity
--At BOM 1 capacity 1/2: No capacity found... can't plan BOM
At factory_1: No supply found upstream of BOM-1 to fg_1-factory_1
***Found 0.00% supply for demand key 2023***
***Starting to plan for demand key 2025***
At factory_1 on 2025-05-30: Searching inventory for 1 units of fg_1
At factory_1: No inventory for fg_1
At factory_1: Searching BomOutputEdge BOM-1 to fg_1-factory_1 with LT 5.0 days
--At BOM 1 capacity 1/2: Requesting for 2 units of capacity
----At CapacityNode-labour_hours on 2025-05-25: Searching for 2 units of capacity
----At CapacityNode-labour_hours: no capacity exists during 2025-05-25 00:00:00. Failed to gather capacity
--At BOM 1 capacity 1/2: No capacity found... can't plan BOM
At factory_1: No supply found upstream of BOM-1 to fg_1-factory_1
***Found 0.00% supply for demand key 2025***
***Starting to plan for demand key 2024_large***
At factory_1 on 2024-05-30: Searching inventory for 100 units of fg_1
At factory_1: No inventory for fg_1
At factory_1: Searching BomOutputEdge BOM-1 to fg_1-factory_1 with LT 5.0 days
--At BOM 1 capacity 1/2: Requesting for 200 units of capacity
----At CapacityNode-labour_hours on 2024-05-25: Searching for 200 units of capacity
----At CapacityNode-labour_hours: 38 available during period 2024-05-19 to 2024-05-26
----At CapacityNode-labour_hours: Only 38/200 capacity exists
--At BOM 1 capacity 1/2: Found only 19.00% of the capacity requested
--At BOM 1 capacity 2/2: Requesting for 152.0 units of capacity
----At CapacityNode-machine_hours on 2024-05-25: Searching for 152.0 units of capacity
----At CapacityNode-machine_hours: 92 available during period 2024-05-01 to 2024-06-01
----At CapacityNode-machine_hours: Only 92/152.0 capacity exists
--At BOM 1 capacity 2/2: Found only 60.53% of the capacity requested
--At BOM 1: Replanning BOM for just 11.5 qty
--At BOM 1 capacity 1/2: Requesting for 23.0 units of capacity
----At CapacityNode-labour_hours on 2024-05-25: Searching for 23.0 units of capacity
----At CapacityNode-labour_hours: 38 available during period 2024-05-19 to 2024-05-26
----At CapacityNode-labour_hours: All 23.0 capacity exists
--At BOM 1 capacity 1/2: Found all needed capacity
--At BOM 1 capacity 2/2: Requesting for 92.0 units of capacity
----At CapacityNode-machine_hours on 2024-05-25: Searching for 92.0 units of capacity
----At CapacityNode-machine_hours: 92 available during period 2024-05-01 to 2024-06-01
----At CapacityNode-machine_hours: All 92.0 capacity exists
--At BOM 1 capacity 2/2: Found all needed capacity
--At BOM 1 input 1/3: Searching for 11.5 of rm_1
----At factory_1 on 2024-05-25: Genesis Node for rm_1. All 11.5 need satisfied
--At BOM 1 input 1/3: Found all supply for rm_1
--At BOM 1 input 2/3: Searching for 23.0 of rm_2
----At factory_1 on 2024-05-25: Genesis Node for rm_2. All 23.0 need satisfied
--At BOM 1 input 2/3: Found all supply for rm_2
--At BOM 1 input 3/3: Searching for 5.75 of rm_3
----At factory_1 on 2024-05-25: Genesis Node for rm_3. All 5.75 need satisfied
--At BOM 1 input 3/3: Found all supply for rm_3
--At BOM 1: Done searching all inputs
At factory_1: Found 11.5/100 on edge BOM-1 to fg_1-factory_1
***Found 11.50% supply for demand key 2024_large***
Solver complete. Writing output

Created by Bill Ulrich
See the About page for more details