Simple capacity planing example that shows how a supply chain solver consumes capacity
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.
In this example, the production of one unit of finished good, fg_1, uses:
The solver plans for 4 demands and gets different outputs:
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_id | capacity_id | capacity_usage_rate |
|---|---|---|
| 1 | labour_hours | 2 |
| 1 | machine_hours | 8 |
| bom_id | location | lead_time_days |
|---|---|---|
| 1 | factory_1 | 5 |
| bom_id | input_item | input_qty |
|---|---|---|
| 1 | rm_1 | 1.0 |
| 1 | rm_2 | 2.0 |
| 1 | rm_3 | 0.5 |
| bom_id | output_item | output_qty |
|---|---|---|
| 1 | fg_1 | 1 |
| 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 |
| 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 | genesis |
|---|---|---|
| rm_1 | factory_1 | True |
| rm_2 | factory_1 | True |
| rm_3 | factory_1 | True |
| 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_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 | 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 |
| 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