[SCENARIO]
Family: F1 (Core Operations)
Archetype: retail_f1_high_waste
Scenario ID: retail_f1_high_waste_v1

[BUSINESS DESCRIPTION]
Business narrative:
This scenario keeps the same basic single-echelon structure as the core operations baseline but represents categories where waste is extremely expensive, such as highly perishable or sensitive products. The retailer still serves exogenous seasonal demand from local inventories at distribution centers with no transshipment and no backorders. Any units that must be discarded because they are no longer usable incur a much higher penalty than in the baseline, creating strong pressure to avoid overstocking.

Structure cues:
- The network is the same as in retail_f1_base: multiple products, multiple locations that directly serve final demand, and per-product production capacities in each period.
- Inventory is held at each location, evolves from period to period by adding local production and subtracting sales and waste, and is never allowed to go negative. Unserved demand is treated as lost sales and penalized as in the baseline.
- Shelf life: Each product has a shelf life in periods. Inventory must be tracked by REMAINING LIFE.

  VARIABLE DEFINITION: I[p,l,t,r] = inventory at START of period t with r periods remaining.
  Convention: r=1 is OLDEST (sell first FIFO), r=shelf_life[p] is FRESHEST.

  KEY EQUATIONS - implement EXACTLY as written, do NOT add or remove terms:

  (1) Fresh inflow: I[p,l,t,SL] = Q[p,t] * demand_share[l]
      - This is ONLY the inflow from production. Do NOT subtract sales here!
      - Q is total production, demand_share distributes it to locations.

  (2) Aging: I[p,l,t+1,r] = I[p,l,t,r+1] - sales[p,l,t,r+1] for r=1..SL-1
      - Inventory tomorrow with r remaining = inventory today with r+1 remaining - sales

  (3) Waste: W[p,l,t] = I[p,l,t,1] - sales[p,l,t,1]
      - Items with r=1 that aren't sold become waste

  (4) Sales availability: sales[p,l,t,r] <= I[p,l,t,r]
      - Can only sell what you have in inventory

  (5) Inventory holding cost: charged on (I[p,l,t,r] - sales[p,l,t,r]) for r >= 2
      - Charge on END-of-period inventory (after sales), exclude expiring items (r=1)
- Storage capacity: sum over products of (cold_usage[p] * total_inventory[p,l,t]) <= cold_capacity[l]. These limits must be respected.
- The substitution pattern (Basic's demand served by Premium), absence of transshipment, zero lead times, and effectively non-binding labor capacities are the same as in the baseline scenario.
- The only intended structural change is in the cost weights: waste costs in the JSON are much larger, so discarding inventory is heavily discouraged, but the constraint system itself is not altered.
- The objective continues to minimize the sum of purchasing costs, holding costs, waste costs, and lost sales penalties over all products, locations, and periods.

[DATA SCHEMA]
{
  "name": str,                          # scenario identifier
  "periods": int,                       # number of time periods
  "products": [str, ...],               # list of product IDs
  "locations": [str, ...],              # list of location IDs

  "shelf_life": {p: int},               # shelf life in periods per product
  "lead_time": {p: int},                # order lead time per product (0 = same-period arrival)

  "demand_curve": {p: [float, ...]},    # demand per product per period (0-indexed list)
  "demand_share": {l: float},           # fraction of total demand at each location

  "production_cap": {p: [float, ...]},  # max production per product per period (0-indexed list)
  "cold_capacity": {l: float},          # storage capacity per location
  "cold_usage": {p: float},             # storage units per unit of product

  "labor_cap": {l: [float, ...]},       # labor hours per location per period (0-indexed list)
  "labor_usage": {p: float},            # labor hours per unit sold
  "return_rate": {p: float},            # fraction of sales returned next period

  "costs": {
    "purchasing": {p: float},           # cost per unit ordered
    "inventory": {p: float},            # holding cost per unit per period
    "waste": {p: float},                # cost per unit expired
    "lost_sales": {p: float},           # penalty per unit of unmet demand
    "fixed_order": float,               # fixed cost per order placed
    "transshipment": float              # cost per unit transshipped
  },

  "constraints": {
    "moq": float,                       # minimum order quantity (0 = no MOQ)
    "pack_size": int,                   # order must be multiple of this (1 = no constraint)
    "budget_per_period": float|null,    # max purchasing cost per period
    "waste_limit_pct": float|null       # max waste as fraction of total demand
  },

  "network": {
    "sub_edges": [[p_from, p_to], ...], # substitution: p_from's demand can be served by p_to
    "trans_edges": [[l_from, l_to], ...]# transshipment: can ship from l_from to l_to
  }
}

[DATA ACCESS]
- The variable `data` is pre-loaded. Do NOT use file I/O.
- Lists are 0-indexed (period t in model uses index [t-1] in data arrays)

CRITICAL - Network edges require tuple conversion for Gurobi:
  sub_edges = [tuple(e) for e in data.get('network', {}).get('sub_edges', [])]
  trans_edges = [tuple(e) for e in data.get('network', {}).get('trans_edges', [])]

[OUTPUT FORMAT]
- Import: import gurobipy as gp; from gurobipy import GRB
- Set Gurobi params: m.Params.OutputFlag = 0; m.Params.Threads = 1; m.Params.Seed = 0
- Print at end:
  print(f"status: {{m.Status}}")
  if m.Status == 2:
      print(f"objective: {{m.ObjVal}}")
- Output ONLY executable Python code. No markdown, no explanations.

[TASK]
Write a GurobiPy script that models and solves this optimization problem.

[SCENARIO]
Family: F1 (Core Operations)
Archetype: retail_f1_high_waste
Scenario ID: retail_f1_high_waste_v1

[BUSINESS DESCRIPTION]
Business narrative:
This scenario keeps the same basic single-echelon structure as the core operations baseline but represents categories where waste is extremely expensive, such as highly perishable or sensitive products. The retailer still serves exogenous seasonal demand from local inventories at distribution centers with no transshipment and no backorders. Any units that must be discarded because they are no longer usable incur a much higher penalty than in the baseline, creating strong pressure to avoid overstocking.

Structure cues:
- The network is the same as in retail_f1_base: multiple products, multiple locations that directly serve final demand, and per-product production capacities in each period.
- Inventory is held at each location, evolves from period to period by adding local production and subtracting sales and waste, and is never allowed to go negative. Unserved demand is treated as lost sales and penalized as in the baseline.
- Shelf life: Each product has a shelf life in periods. Inventory must be tracked by REMAINING LIFE.

  VARIABLE DEFINITION: I[p,l,t,r] = inventory at START of period t with r periods remaining.
  Convention: r=1 is OLDEST (sell first FIFO), r=shelf_life[p] is FRESHEST.

  KEY EQUATIONS - implement EXACTLY as written, do NOT add or remove terms:

  (1) Fresh inflow: I[p,l,t,SL] = Q[p,t] * demand_share[l]
      - This is ONLY the inflow from production. Do NOT subtract sales here!
      - Q is total production, demand_share distributes it to locations.

  (2) Aging: I[p,l,t+1,r] = I[p,l,t,r+1] - sales[p,l,t,r+1] for r=1..SL-1
      - Inventory tomorrow with r remaining = inventory today with r+1 remaining - sales

  (3) Waste: W[p,l,t] = I[p,l,t,1] - sales[p,l,t,1]
      - Items with r=1 that aren't sold become waste

  (4) Sales availability: sales[p,l,t,r] <= I[p,l,t,r]
      - Can only sell what you have in inventory

  (5) Inventory holding cost: charged on (I[p,l,t,r] - sales[p,l,t,r]) for r >= 2
      - Charge on END-of-period inventory (after sales), exclude expiring items (r=1)
- Storage capacity: sum over products of (cold_usage[p] * total_inventory[p,l,t]) <= cold_capacity[l]. These limits must be respected.
- The substitution pattern (Basic's demand served by Premium), absence of transshipment, zero lead times, and effectively non-binding labor capacities are the same as in the baseline scenario.
- The only intended structural change is in the cost weights: waste costs in the JSON are much larger, so discarding inventory is heavily discouraged, but the constraint system itself is not altered.
- The objective continues to minimize the sum of purchasing costs, holding costs, waste costs, and lost sales penalties over all products, locations, and periods.

[DATA]
The following JSON contains all instance data. Parse it directly in your code.

```json
{
  "name": "retail_f1_high_waste_v1",
  "description": "Standard seasonal retail scenario.",
  "periods": 20,
  "products": [
    "SKU_Basic",
    "SKU_Premium",
    "SKU_ShortLife"
  ],
  "locations": [
    "DC1",
    "DC2",
    "DC3",
    "DC4",
    "DC5"
  ],
  "shelf_life": {
    "SKU_Basic": 10,
    "SKU_Premium": 8,
    "SKU_ShortLife": 4
  },
  "lead_time": {
    "SKU_Basic": 0,
    "SKU_Premium": 0,
    "SKU_ShortLife": 0
  },
  "cold_capacity": {
    "DC1": 4374.126676532868,
    "DC2": 4009.3552443495837,
    "DC3": 3127.8288463783015,
    "DC4": 3346.928548537924,
    "DC5": 2760.3224302412423
  },
  "cold_usage": {
    "SKU_Basic": 1.0,
    "SKU_Premium": 3.0,
    "SKU_ShortLife": 1.2
  },
  "production_cap": {
    "SKU_Basic": [
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800
    ],
    "SKU_Premium": [
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400
    ],
    "SKU_ShortLife": [
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500
    ]
  },
  "labor_cap": {
    "DC1": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC2": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC3": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC4": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC5": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ]
  },
  "labor_usage": {
    "SKU_Basic": 0.0,
    "SKU_Premium": 0.0,
    "SKU_ShortLife": 0.0
  },
  "return_rate": {
    "SKU_Basic": 0.0,
    "SKU_Premium": 0.0,
    "SKU_ShortLife": 0.0
  },
  "demand_curve": {
    "SKU_Basic": [
      270,
      269,
      299,
      334,
      482,
      504,
      632,
      782,
      1058,
      1218,
      1360,
      1352,
      1230,
      810,
      787,
      567,
      374,
      338,
      289,
      334
    ],
    "SKU_Premium": [
      145,
      140,
      160,
      175,
      234,
      311,
      382,
      407,
      559,
      545,
      651,
      567,
      498,
      404,
      324,
      237,
      206,
      161,
      183,
      171
    ],
    "SKU_ShortLife": [
      107,
      135,
      134,
      154,
      178,
      220,
      246,
      367,
      485,
      429,
      556,
      499,
      405,
      403,
      265,
      217,
      197,
      163,
      135,
      112
    ]
  },
  "demand_share": {
    "DC1": 0.25,
    "DC2": 0.2,
    "DC3": 0.2,
    "DC4": 0.2,
    "DC5": 0.15
  },
  "costs": {
    "lost_sales": {
      "SKU_Basic": 50.0,
      "SKU_Premium": 80.0,
      "SKU_ShortLife": 40.0
    },
    "inventory": {
      "SKU_Basic": 1.0,
      "SKU_Premium": 1.5,
      "SKU_ShortLife": 1.0
    },
    "waste": {
      "SKU_Basic": 40.0,
      "SKU_Premium": 60.0,
      "SKU_ShortLife": 40.0
    },
    "fixed_order": 0.0,
    "transshipment": 0.5,
    "purchasing": {
      "SKU_Basic": 10.0,
      "SKU_Premium": 20.0,
      "SKU_ShortLife": 15.0
    }
  },
  "constraints": {
    "moq": 0,
    "pack_size": 1,
    "budget_per_period": null,
    "waste_limit_pct": null
  },
  "network": {
    "sub_edges": [
      [
        "SKU_Basic",
        "SKU_Premium"
      ]
    ],
    "trans_edges": []
  }
}
```

[OUTPUT FORMAT]
- Import: import gurobipy as gp; from gurobipy import GRB; import json
- Set Gurobi params: m.Params.OutputFlag = 0; m.Params.Threads = 1; m.Params.Seed = 0
- Print at end:
  print(f"status: {{m.Status}}")
  if m.Status == 2:
      print(f"objective: {{m.ObjVal}}")
- Output ONLY executable Python code. No markdown, no explanations.

[TASK]
Write a GurobiPy script that:
1. Parses the JSON data above (use json.loads on the string)
2. Models and solves the optimization problem
3. Prints status and objective value

Standard seasonal retail scenario.


[SCENARIO]
Family: F1 (Core Operations)
Archetype: retail_f1_high_waste
Scenario ID: retail_f1_high_waste_v2

[BUSINESS DESCRIPTION]
Business narrative:
This scenario keeps the same basic single-echelon structure as the core operations baseline but represents categories where waste is extremely expensive, such as highly perishable or sensitive products. The retailer still serves exogenous seasonal demand from local inventories at distribution centers with no transshipment and no backorders. Any units that must be discarded because they are no longer usable incur a much higher penalty than in the baseline, creating strong pressure to avoid overstocking.

Structure cues:
- The network is the same as in retail_f1_base: multiple products, multiple locations that directly serve final demand, and per-product production capacities in each period.
- Inventory is held at each location, evolves from period to period by adding local production and subtracting sales and waste, and is never allowed to go negative. Unserved demand is treated as lost sales and penalized as in the baseline.
- Shelf life: Each product has a shelf life in periods. Inventory must be tracked by REMAINING LIFE.

  VARIABLE DEFINITION: I[p,l,t,r] = inventory at START of period t with r periods remaining.
  Convention: r=1 is OLDEST (sell first FIFO), r=shelf_life[p] is FRESHEST.

  KEY EQUATIONS - implement EXACTLY as written, do NOT add or remove terms:

  (1) Fresh inflow: I[p,l,t,SL] = Q[p,t] * demand_share[l]
      - This is ONLY the inflow from production. Do NOT subtract sales here!
      - Q is total production, demand_share distributes it to locations.

  (2) Aging: I[p,l,t+1,r] = I[p,l,t,r+1] - sales[p,l,t,r+1] for r=1..SL-1
      - Inventory tomorrow with r remaining = inventory today with r+1 remaining - sales

  (3) Waste: W[p,l,t] = I[p,l,t,1] - sales[p,l,t,1]
      - Items with r=1 that aren't sold become waste

  (4) Sales availability: sales[p,l,t,r] <= I[p,l,t,r]
      - Can only sell what you have in inventory

  (5) Inventory holding cost: charged on (I[p,l,t,r] - sales[p,l,t,r]) for r >= 2
      - Charge on END-of-period inventory (after sales), exclude expiring items (r=1)
- Storage capacity: sum over products of (cold_usage[p] * total_inventory[p,l,t]) <= cold_capacity[l]. These limits must be respected.
- The substitution pattern (Basic's demand served by Premium), absence of transshipment, zero lead times, and effectively non-binding labor capacities are the same as in the baseline scenario.
- The only intended structural change is in the cost weights: waste costs in the JSON are much larger, so discarding inventory is heavily discouraged, but the constraint system itself is not altered.
- The objective continues to minimize the sum of purchasing costs, holding costs, waste costs, and lost sales penalties over all products, locations, and periods.

[DATA SCHEMA]
{
  "name": str,                          # scenario identifier
  "periods": int,                       # number of time periods
  "products": [str, ...],               # list of product IDs
  "locations": [str, ...],              # list of location IDs

  "shelf_life": {p: int},               # shelf life in periods per product
  "lead_time": {p: int},                # order lead time per product (0 = same-period arrival)

  "demand_curve": {p: [float, ...]},    # demand per product per period (0-indexed list)
  "demand_share": {l: float},           # fraction of total demand at each location

  "production_cap": {p: [float, ...]},  # max production per product per period (0-indexed list)
  "cold_capacity": {l: float},          # storage capacity per location
  "cold_usage": {p: float},             # storage units per unit of product

  "labor_cap": {l: [float, ...]},       # labor hours per location per period (0-indexed list)
  "labor_usage": {p: float},            # labor hours per unit sold
  "return_rate": {p: float},            # fraction of sales returned next period

  "costs": {
    "purchasing": {p: float},           # cost per unit ordered
    "inventory": {p: float},            # holding cost per unit per period
    "waste": {p: float},                # cost per unit expired
    "lost_sales": {p: float},           # penalty per unit of unmet demand
    "fixed_order": float,               # fixed cost per order placed
    "transshipment": float              # cost per unit transshipped
  },

  "constraints": {
    "moq": float,                       # minimum order quantity (0 = no MOQ)
    "pack_size": int,                   # order must be multiple of this (1 = no constraint)
    "budget_per_period": float|null,    # max purchasing cost per period
    "waste_limit_pct": float|null       # max waste as fraction of total demand
  },

  "network": {
    "sub_edges": [[p_from, p_to], ...], # substitution: p_from's demand can be served by p_to
    "trans_edges": [[l_from, l_to], ...]# transshipment: can ship from l_from to l_to
  }
}

[DATA ACCESS]
- The variable `data` is pre-loaded. Do NOT use file I/O.
- Lists are 0-indexed (period t in model uses index [t-1] in data arrays)

CRITICAL - Network edges require tuple conversion for Gurobi:
  sub_edges = [tuple(e) for e in data.get('network', {}).get('sub_edges', [])]
  trans_edges = [tuple(e) for e in data.get('network', {}).get('trans_edges', [])]

[OUTPUT FORMAT]
- Import: import gurobipy as gp; from gurobipy import GRB
- Set Gurobi params: m.Params.OutputFlag = 0; m.Params.Threads = 1; m.Params.Seed = 0
- Print at end:
  print(f"status: {{m.Status}}")
  if m.Status == 2:
      print(f"objective: {{m.ObjVal}}")
- Output ONLY executable Python code. No markdown, no explanations.

[TASK]
Write a GurobiPy script that models and solves this optimization problem.

[SCENARIO]
Family: F1 (Core Operations)
Archetype: retail_f1_high_waste
Scenario ID: retail_f1_high_waste_v2

[BUSINESS DESCRIPTION]
Business narrative:
This scenario keeps the same basic single-echelon structure as the core operations baseline but represents categories where waste is extremely expensive, such as highly perishable or sensitive products. The retailer still serves exogenous seasonal demand from local inventories at distribution centers with no transshipment and no backorders. Any units that must be discarded because they are no longer usable incur a much higher penalty than in the baseline, creating strong pressure to avoid overstocking.

Structure cues:
- The network is the same as in retail_f1_base: multiple products, multiple locations that directly serve final demand, and per-product production capacities in each period.
- Inventory is held at each location, evolves from period to period by adding local production and subtracting sales and waste, and is never allowed to go negative. Unserved demand is treated as lost sales and penalized as in the baseline.
- Shelf life: Each product has a shelf life in periods. Inventory must be tracked by REMAINING LIFE.

  VARIABLE DEFINITION: I[p,l,t,r] = inventory at START of period t with r periods remaining.
  Convention: r=1 is OLDEST (sell first FIFO), r=shelf_life[p] is FRESHEST.

  KEY EQUATIONS - implement EXACTLY as written, do NOT add or remove terms:

  (1) Fresh inflow: I[p,l,t,SL] = Q[p,t] * demand_share[l]
      - This is ONLY the inflow from production. Do NOT subtract sales here!
      - Q is total production, demand_share distributes it to locations.

  (2) Aging: I[p,l,t+1,r] = I[p,l,t,r+1] - sales[p,l,t,r+1] for r=1..SL-1
      - Inventory tomorrow with r remaining = inventory today with r+1 remaining - sales

  (3) Waste: W[p,l,t] = I[p,l,t,1] - sales[p,l,t,1]
      - Items with r=1 that aren't sold become waste

  (4) Sales availability: sales[p,l,t,r] <= I[p,l,t,r]
      - Can only sell what you have in inventory

  (5) Inventory holding cost: charged on (I[p,l,t,r] - sales[p,l,t,r]) for r >= 2
      - Charge on END-of-period inventory (after sales), exclude expiring items (r=1)
- Storage capacity: sum over products of (cold_usage[p] * total_inventory[p,l,t]) <= cold_capacity[l]. These limits must be respected.
- The substitution pattern (Basic's demand served by Premium), absence of transshipment, zero lead times, and effectively non-binding labor capacities are the same as in the baseline scenario.
- The only intended structural change is in the cost weights: waste costs in the JSON are much larger, so discarding inventory is heavily discouraged, but the constraint system itself is not altered.
- The objective continues to minimize the sum of purchasing costs, holding costs, waste costs, and lost sales penalties over all products, locations, and periods.

[DATA]
The following JSON contains all instance data. Parse it directly in your code.

```json
{
  "name": "retail_f1_high_waste_v2",
  "description": "Standard seasonal retail scenario.",
  "periods": 20,
  "products": [
    "SKU_Basic",
    "SKU_Premium",
    "SKU_ShortLife"
  ],
  "locations": [
    "DC1",
    "DC2",
    "DC3",
    "DC4",
    "DC5"
  ],
  "shelf_life": {
    "SKU_Basic": 10,
    "SKU_Premium": 8,
    "SKU_ShortLife": 4
  },
  "lead_time": {
    "SKU_Basic": 0,
    "SKU_Premium": 0,
    "SKU_ShortLife": 0
  },
  "cold_capacity": {
    "DC1": 4239.5437634365735,
    "DC2": 3281.1772732001004,
    "DC3": 3309.019640012453,
    "DC4": 3287.5725035998616,
    "DC5": 2148.382238669537
  },
  "cold_usage": {
    "SKU_Basic": 1.0,
    "SKU_Premium": 3.0,
    "SKU_ShortLife": 1.2
  },
  "production_cap": {
    "SKU_Basic": [
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800
    ],
    "SKU_Premium": [
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400
    ],
    "SKU_ShortLife": [
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500
    ]
  },
  "labor_cap": {
    "DC1": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC2": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC3": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC4": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC5": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ]
  },
  "labor_usage": {
    "SKU_Basic": 0.0,
    "SKU_Premium": 0.0,
    "SKU_ShortLife": 0.0
  },
  "return_rate": {
    "SKU_Basic": 0.0,
    "SKU_Premium": 0.0,
    "SKU_ShortLife": 0.0
  },
  "demand_curve": {
    "SKU_Basic": [
      278,
      266,
      291,
      364,
      400,
      472,
      773,
      1023,
      1239,
      1320,
      1122,
      1132,
      1070,
      934,
      754,
      549,
      378,
      355,
      348,
      338
    ],
    "SKU_Premium": [
      165,
      135,
      184,
      172,
      198,
      258,
      311,
      464,
      515,
      625,
      645,
      701,
      585,
      465,
      368,
      256,
      208,
      178,
      157,
      170
    ],
    "SKU_ShortLife": [
      136,
      114,
      119,
      127,
      157,
      199,
      289,
      382,
      489,
      570,
      447,
      462,
      465,
      338,
      324,
      216,
      162,
      156,
      136,
      122
    ]
  },
  "demand_share": {
    "DC1": 0.25,
    "DC2": 0.2,
    "DC3": 0.2,
    "DC4": 0.2,
    "DC5": 0.15
  },
  "costs": {
    "lost_sales": {
      "SKU_Basic": 50.0,
      "SKU_Premium": 80.0,
      "SKU_ShortLife": 40.0
    },
    "inventory": {
      "SKU_Basic": 1.0,
      "SKU_Premium": 1.5,
      "SKU_ShortLife": 1.0
    },
    "waste": {
      "SKU_Basic": 40.0,
      "SKU_Premium": 60.0,
      "SKU_ShortLife": 40.0
    },
    "fixed_order": 0.0,
    "transshipment": 0.5,
    "purchasing": {
      "SKU_Basic": 10.0,
      "SKU_Premium": 20.0,
      "SKU_ShortLife": 15.0
    }
  },
  "constraints": {
    "moq": 0,
    "pack_size": 1,
    "budget_per_period": null,
    "waste_limit_pct": null
  },
  "network": {
    "sub_edges": [
      [
        "SKU_Basic",
        "SKU_Premium"
      ]
    ],
    "trans_edges": []
  }
}
```

[OUTPUT FORMAT]
- Import: import gurobipy as gp; from gurobipy import GRB; import json
- Set Gurobi params: m.Params.OutputFlag = 0; m.Params.Threads = 1; m.Params.Seed = 0
- Print at end:
  print(f"status: {{m.Status}}")
  if m.Status == 2:
      print(f"objective: {{m.ObjVal}}")
- Output ONLY executable Python code. No markdown, no explanations.

[TASK]
Write a GurobiPy script that:
1. Parses the JSON data above (use json.loads on the string)
2. Models and solves the optimization problem
3. Prints status and objective value

Standard seasonal retail scenario.


[SCENARIO]
Family: F1 (Core Operations)
Archetype: retail_f1_high_waste
Scenario ID: retail_f1_high_waste_v3

[BUSINESS DESCRIPTION]
Business narrative:
This scenario keeps the same basic single-echelon structure as the core operations baseline but represents categories where waste is extremely expensive, such as highly perishable or sensitive products. The retailer still serves exogenous seasonal demand from local inventories at distribution centers with no transshipment and no backorders. Any units that must be discarded because they are no longer usable incur a much higher penalty than in the baseline, creating strong pressure to avoid overstocking.

Structure cues:
- The network is the same as in retail_f1_base: multiple products, multiple locations that directly serve final demand, and per-product production capacities in each period.
- Inventory is held at each location, evolves from period to period by adding local production and subtracting sales and waste, and is never allowed to go negative. Unserved demand is treated as lost sales and penalized as in the baseline.
- Shelf life: Each product has a shelf life in periods. Inventory must be tracked by REMAINING LIFE.

  VARIABLE DEFINITION: I[p,l,t,r] = inventory at START of period t with r periods remaining.
  Convention: r=1 is OLDEST (sell first FIFO), r=shelf_life[p] is FRESHEST.

  KEY EQUATIONS - implement EXACTLY as written, do NOT add or remove terms:

  (1) Fresh inflow: I[p,l,t,SL] = Q[p,t] * demand_share[l]
      - This is ONLY the inflow from production. Do NOT subtract sales here!
      - Q is total production, demand_share distributes it to locations.

  (2) Aging: I[p,l,t+1,r] = I[p,l,t,r+1] - sales[p,l,t,r+1] for r=1..SL-1
      - Inventory tomorrow with r remaining = inventory today with r+1 remaining - sales

  (3) Waste: W[p,l,t] = I[p,l,t,1] - sales[p,l,t,1]
      - Items with r=1 that aren't sold become waste

  (4) Sales availability: sales[p,l,t,r] <= I[p,l,t,r]
      - Can only sell what you have in inventory

  (5) Inventory holding cost: charged on (I[p,l,t,r] - sales[p,l,t,r]) for r >= 2
      - Charge on END-of-period inventory (after sales), exclude expiring items (r=1)
- Storage capacity: sum over products of (cold_usage[p] * total_inventory[p,l,t]) <= cold_capacity[l]. These limits must be respected.
- The substitution pattern (Basic's demand served by Premium), absence of transshipment, zero lead times, and effectively non-binding labor capacities are the same as in the baseline scenario.
- The only intended structural change is in the cost weights: waste costs in the JSON are much larger, so discarding inventory is heavily discouraged, but the constraint system itself is not altered.
- The objective continues to minimize the sum of purchasing costs, holding costs, waste costs, and lost sales penalties over all products, locations, and periods.

[DATA SCHEMA]
{
  "name": str,                          # scenario identifier
  "periods": int,                       # number of time periods
  "products": [str, ...],               # list of product IDs
  "locations": [str, ...],              # list of location IDs

  "shelf_life": {p: int},               # shelf life in periods per product
  "lead_time": {p: int},                # order lead time per product (0 = same-period arrival)

  "demand_curve": {p: [float, ...]},    # demand per product per period (0-indexed list)
  "demand_share": {l: float},           # fraction of total demand at each location

  "production_cap": {p: [float, ...]},  # max production per product per period (0-indexed list)
  "cold_capacity": {l: float},          # storage capacity per location
  "cold_usage": {p: float},             # storage units per unit of product

  "labor_cap": {l: [float, ...]},       # labor hours per location per period (0-indexed list)
  "labor_usage": {p: float},            # labor hours per unit sold
  "return_rate": {p: float},            # fraction of sales returned next period

  "costs": {
    "purchasing": {p: float},           # cost per unit ordered
    "inventory": {p: float},            # holding cost per unit per period
    "waste": {p: float},                # cost per unit expired
    "lost_sales": {p: float},           # penalty per unit of unmet demand
    "fixed_order": float,               # fixed cost per order placed
    "transshipment": float              # cost per unit transshipped
  },

  "constraints": {
    "moq": float,                       # minimum order quantity (0 = no MOQ)
    "pack_size": int,                   # order must be multiple of this (1 = no constraint)
    "budget_per_period": float|null,    # max purchasing cost per period
    "waste_limit_pct": float|null       # max waste as fraction of total demand
  },

  "network": {
    "sub_edges": [[p_from, p_to], ...], # substitution: p_from's demand can be served by p_to
    "trans_edges": [[l_from, l_to], ...]# transshipment: can ship from l_from to l_to
  }
}

[DATA ACCESS]
- The variable `data` is pre-loaded. Do NOT use file I/O.
- Lists are 0-indexed (period t in model uses index [t-1] in data arrays)

CRITICAL - Network edges require tuple conversion for Gurobi:
  sub_edges = [tuple(e) for e in data.get('network', {}).get('sub_edges', [])]
  trans_edges = [tuple(e) for e in data.get('network', {}).get('trans_edges', [])]

[OUTPUT FORMAT]
- Import: import gurobipy as gp; from gurobipy import GRB
- Set Gurobi params: m.Params.OutputFlag = 0; m.Params.Threads = 1; m.Params.Seed = 0
- Print at end:
  print(f"status: {{m.Status}}")
  if m.Status == 2:
      print(f"objective: {{m.ObjVal}}")
- Output ONLY executable Python code. No markdown, no explanations.

[TASK]
Write a GurobiPy script that models and solves this optimization problem.

[SCENARIO]
Family: F1 (Core Operations)
Archetype: retail_f1_high_waste
Scenario ID: retail_f1_high_waste_v3

[BUSINESS DESCRIPTION]
Business narrative:
This scenario keeps the same basic single-echelon structure as the core operations baseline but represents categories where waste is extremely expensive, such as highly perishable or sensitive products. The retailer still serves exogenous seasonal demand from local inventories at distribution centers with no transshipment and no backorders. Any units that must be discarded because they are no longer usable incur a much higher penalty than in the baseline, creating strong pressure to avoid overstocking.

Structure cues:
- The network is the same as in retail_f1_base: multiple products, multiple locations that directly serve final demand, and per-product production capacities in each period.
- Inventory is held at each location, evolves from period to period by adding local production and subtracting sales and waste, and is never allowed to go negative. Unserved demand is treated as lost sales and penalized as in the baseline.
- Shelf life: Each product has a shelf life in periods. Inventory must be tracked by REMAINING LIFE.

  VARIABLE DEFINITION: I[p,l,t,r] = inventory at START of period t with r periods remaining.
  Convention: r=1 is OLDEST (sell first FIFO), r=shelf_life[p] is FRESHEST.

  KEY EQUATIONS - implement EXACTLY as written, do NOT add or remove terms:

  (1) Fresh inflow: I[p,l,t,SL] = Q[p,t] * demand_share[l]
      - This is ONLY the inflow from production. Do NOT subtract sales here!
      - Q is total production, demand_share distributes it to locations.

  (2) Aging: I[p,l,t+1,r] = I[p,l,t,r+1] - sales[p,l,t,r+1] for r=1..SL-1
      - Inventory tomorrow with r remaining = inventory today with r+1 remaining - sales

  (3) Waste: W[p,l,t] = I[p,l,t,1] - sales[p,l,t,1]
      - Items with r=1 that aren't sold become waste

  (4) Sales availability: sales[p,l,t,r] <= I[p,l,t,r]
      - Can only sell what you have in inventory

  (5) Inventory holding cost: charged on (I[p,l,t,r] - sales[p,l,t,r]) for r >= 2
      - Charge on END-of-period inventory (after sales), exclude expiring items (r=1)
- Storage capacity: sum over products of (cold_usage[p] * total_inventory[p,l,t]) <= cold_capacity[l]. These limits must be respected.
- The substitution pattern (Basic's demand served by Premium), absence of transshipment, zero lead times, and effectively non-binding labor capacities are the same as in the baseline scenario.
- The only intended structural change is in the cost weights: waste costs in the JSON are much larger, so discarding inventory is heavily discouraged, but the constraint system itself is not altered.
- The objective continues to minimize the sum of purchasing costs, holding costs, waste costs, and lost sales penalties over all products, locations, and periods.

[DATA]
The following JSON contains all instance data. Parse it directly in your code.

```json
{
  "name": "retail_f1_high_waste_v3",
  "description": "Standard seasonal retail scenario.",
  "periods": 20,
  "products": [
    "SKU_Basic",
    "SKU_Premium",
    "SKU_ShortLife"
  ],
  "locations": [
    "DC1",
    "DC2",
    "DC3",
    "DC4",
    "DC5"
  ],
  "shelf_life": {
    "SKU_Basic": 10,
    "SKU_Premium": 8,
    "SKU_ShortLife": 4
  },
  "lead_time": {
    "SKU_Basic": 0,
    "SKU_Premium": 0,
    "SKU_ShortLife": 0
  },
  "cold_capacity": {
    "DC1": 4401.3951355135505,
    "DC2": 3048.001515599564,
    "DC3": 3055.142380942407,
    "DC4": 3274.881736277081,
    "DC5": 2129.7650931970747
  },
  "cold_usage": {
    "SKU_Basic": 1.0,
    "SKU_Premium": 3.0,
    "SKU_ShortLife": 1.2
  },
  "production_cap": {
    "SKU_Basic": [
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800
    ],
    "SKU_Premium": [
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400
    ],
    "SKU_ShortLife": [
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500
    ]
  },
  "labor_cap": {
    "DC1": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC2": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC3": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC4": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC5": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ]
  },
  "labor_usage": {
    "SKU_Basic": 0.0,
    "SKU_Premium": 0.0,
    "SKU_ShortLife": 0.0
  },
  "return_rate": {
    "SKU_Basic": 0.0,
    "SKU_Premium": 0.0,
    "SKU_ShortLife": 0.0
  },
  "demand_curve": {
    "SKU_Basic": [
      319,
      288,
      305,
      364,
      447,
      587,
      638,
      778,
      1105,
      1197,
      1283,
      1219,
      1261,
      873,
      673,
      528,
      463,
      314,
      336,
      350
    ],
    "SKU_Premium": [
      130,
      155,
      185,
      187,
      223,
      282,
      337,
      499,
      485,
      684,
      727,
      538,
      574,
      406,
      334,
      235,
      208,
      169,
      176,
      147
    ],
    "SKU_ShortLife": [
      121,
      135,
      114,
      132,
      172,
      222,
      322,
      388,
      455,
      453,
      518,
      546,
      483,
      371,
      301,
      207,
      194,
      139,
      133,
      126
    ]
  },
  "demand_share": {
    "DC1": 0.25,
    "DC2": 0.2,
    "DC3": 0.2,
    "DC4": 0.2,
    "DC5": 0.15
  },
  "costs": {
    "lost_sales": {
      "SKU_Basic": 50.0,
      "SKU_Premium": 80.0,
      "SKU_ShortLife": 40.0
    },
    "inventory": {
      "SKU_Basic": 1.0,
      "SKU_Premium": 1.5,
      "SKU_ShortLife": 1.0
    },
    "waste": {
      "SKU_Basic": 40.0,
      "SKU_Premium": 60.0,
      "SKU_ShortLife": 40.0
    },
    "fixed_order": 0.0,
    "transshipment": 0.5,
    "purchasing": {
      "SKU_Basic": 10.0,
      "SKU_Premium": 20.0,
      "SKU_ShortLife": 15.0
    }
  },
  "constraints": {
    "moq": 0,
    "pack_size": 1,
    "budget_per_period": null,
    "waste_limit_pct": null
  },
  "network": {
    "sub_edges": [
      [
        "SKU_Basic",
        "SKU_Premium"
      ]
    ],
    "trans_edges": []
  }
}
```

[OUTPUT FORMAT]
- Import: import gurobipy as gp; from gurobipy import GRB; import json
- Set Gurobi params: m.Params.OutputFlag = 0; m.Params.Threads = 1; m.Params.Seed = 0
- Print at end:
  print(f"status: {{m.Status}}")
  if m.Status == 2:
      print(f"objective: {{m.ObjVal}}")
- Output ONLY executable Python code. No markdown, no explanations.

[TASK]
Write a GurobiPy script that:
1. Parses the JSON data above (use json.loads on the string)
2. Models and solves the optimization problem
3. Prints status and objective value

Standard seasonal retail scenario.


[SCENARIO]
Family: F1 (Core Operations)
Archetype: retail_f1_high_waste
Scenario ID: retail_f1_high_waste_v4

[BUSINESS DESCRIPTION]
Business narrative:
This scenario keeps the same basic single-echelon structure as the core operations baseline but represents categories where waste is extremely expensive, such as highly perishable or sensitive products. The retailer still serves exogenous seasonal demand from local inventories at distribution centers with no transshipment and no backorders. Any units that must be discarded because they are no longer usable incur a much higher penalty than in the baseline, creating strong pressure to avoid overstocking.

Structure cues:
- The network is the same as in retail_f1_base: multiple products, multiple locations that directly serve final demand, and per-product production capacities in each period.
- Inventory is held at each location, evolves from period to period by adding local production and subtracting sales and waste, and is never allowed to go negative. Unserved demand is treated as lost sales and penalized as in the baseline.
- Shelf life: Each product has a shelf life in periods. Inventory must be tracked by REMAINING LIFE.

  VARIABLE DEFINITION: I[p,l,t,r] = inventory at START of period t with r periods remaining.
  Convention: r=1 is OLDEST (sell first FIFO), r=shelf_life[p] is FRESHEST.

  KEY EQUATIONS - implement EXACTLY as written, do NOT add or remove terms:

  (1) Fresh inflow: I[p,l,t,SL] = Q[p,t] * demand_share[l]
      - This is ONLY the inflow from production. Do NOT subtract sales here!
      - Q is total production, demand_share distributes it to locations.

  (2) Aging: I[p,l,t+1,r] = I[p,l,t,r+1] - sales[p,l,t,r+1] for r=1..SL-1
      - Inventory tomorrow with r remaining = inventory today with r+1 remaining - sales

  (3) Waste: W[p,l,t] = I[p,l,t,1] - sales[p,l,t,1]
      - Items with r=1 that aren't sold become waste

  (4) Sales availability: sales[p,l,t,r] <= I[p,l,t,r]
      - Can only sell what you have in inventory

  (5) Inventory holding cost: charged on (I[p,l,t,r] - sales[p,l,t,r]) for r >= 2
      - Charge on END-of-period inventory (after sales), exclude expiring items (r=1)
- Storage capacity: sum over products of (cold_usage[p] * total_inventory[p,l,t]) <= cold_capacity[l]. These limits must be respected.
- The substitution pattern (Basic's demand served by Premium), absence of transshipment, zero lead times, and effectively non-binding labor capacities are the same as in the baseline scenario.
- The only intended structural change is in the cost weights: waste costs in the JSON are much larger, so discarding inventory is heavily discouraged, but the constraint system itself is not altered.
- The objective continues to minimize the sum of purchasing costs, holding costs, waste costs, and lost sales penalties over all products, locations, and periods.

[DATA SCHEMA]
{
  "name": str,                          # scenario identifier
  "periods": int,                       # number of time periods
  "products": [str, ...],               # list of product IDs
  "locations": [str, ...],              # list of location IDs

  "shelf_life": {p: int},               # shelf life in periods per product
  "lead_time": {p: int},                # order lead time per product (0 = same-period arrival)

  "demand_curve": {p: [float, ...]},    # demand per product per period (0-indexed list)
  "demand_share": {l: float},           # fraction of total demand at each location

  "production_cap": {p: [float, ...]},  # max production per product per period (0-indexed list)
  "cold_capacity": {l: float},          # storage capacity per location
  "cold_usage": {p: float},             # storage units per unit of product

  "labor_cap": {l: [float, ...]},       # labor hours per location per period (0-indexed list)
  "labor_usage": {p: float},            # labor hours per unit sold
  "return_rate": {p: float},            # fraction of sales returned next period

  "costs": {
    "purchasing": {p: float},           # cost per unit ordered
    "inventory": {p: float},            # holding cost per unit per period
    "waste": {p: float},                # cost per unit expired
    "lost_sales": {p: float},           # penalty per unit of unmet demand
    "fixed_order": float,               # fixed cost per order placed
    "transshipment": float              # cost per unit transshipped
  },

  "constraints": {
    "moq": float,                       # minimum order quantity (0 = no MOQ)
    "pack_size": int,                   # order must be multiple of this (1 = no constraint)
    "budget_per_period": float|null,    # max purchasing cost per period
    "waste_limit_pct": float|null       # max waste as fraction of total demand
  },

  "network": {
    "sub_edges": [[p_from, p_to], ...], # substitution: p_from's demand can be served by p_to
    "trans_edges": [[l_from, l_to], ...]# transshipment: can ship from l_from to l_to
  }
}

[DATA ACCESS]
- The variable `data` is pre-loaded. Do NOT use file I/O.
- Lists are 0-indexed (period t in model uses index [t-1] in data arrays)

CRITICAL - Network edges require tuple conversion for Gurobi:
  sub_edges = [tuple(e) for e in data.get('network', {}).get('sub_edges', [])]
  trans_edges = [tuple(e) for e in data.get('network', {}).get('trans_edges', [])]

[OUTPUT FORMAT]
- Import: import gurobipy as gp; from gurobipy import GRB
- Set Gurobi params: m.Params.OutputFlag = 0; m.Params.Threads = 1; m.Params.Seed = 0
- Print at end:
  print(f"status: {{m.Status}}")
  if m.Status == 2:
      print(f"objective: {{m.ObjVal}}")
- Output ONLY executable Python code. No markdown, no explanations.

[TASK]
Write a GurobiPy script that models and solves this optimization problem.

[SCENARIO]
Family: F1 (Core Operations)
Archetype: retail_f1_high_waste
Scenario ID: retail_f1_high_waste_v4

[BUSINESS DESCRIPTION]
Business narrative:
This scenario keeps the same basic single-echelon structure as the core operations baseline but represents categories where waste is extremely expensive, such as highly perishable or sensitive products. The retailer still serves exogenous seasonal demand from local inventories at distribution centers with no transshipment and no backorders. Any units that must be discarded because they are no longer usable incur a much higher penalty than in the baseline, creating strong pressure to avoid overstocking.

Structure cues:
- The network is the same as in retail_f1_base: multiple products, multiple locations that directly serve final demand, and per-product production capacities in each period.
- Inventory is held at each location, evolves from period to period by adding local production and subtracting sales and waste, and is never allowed to go negative. Unserved demand is treated as lost sales and penalized as in the baseline.
- Shelf life: Each product has a shelf life in periods. Inventory must be tracked by REMAINING LIFE.

  VARIABLE DEFINITION: I[p,l,t,r] = inventory at START of period t with r periods remaining.
  Convention: r=1 is OLDEST (sell first FIFO), r=shelf_life[p] is FRESHEST.

  KEY EQUATIONS - implement EXACTLY as written, do NOT add or remove terms:

  (1) Fresh inflow: I[p,l,t,SL] = Q[p,t] * demand_share[l]
      - This is ONLY the inflow from production. Do NOT subtract sales here!
      - Q is total production, demand_share distributes it to locations.

  (2) Aging: I[p,l,t+1,r] = I[p,l,t,r+1] - sales[p,l,t,r+1] for r=1..SL-1
      - Inventory tomorrow with r remaining = inventory today with r+1 remaining - sales

  (3) Waste: W[p,l,t] = I[p,l,t,1] - sales[p,l,t,1]
      - Items with r=1 that aren't sold become waste

  (4) Sales availability: sales[p,l,t,r] <= I[p,l,t,r]
      - Can only sell what you have in inventory

  (5) Inventory holding cost: charged on (I[p,l,t,r] - sales[p,l,t,r]) for r >= 2
      - Charge on END-of-period inventory (after sales), exclude expiring items (r=1)
- Storage capacity: sum over products of (cold_usage[p] * total_inventory[p,l,t]) <= cold_capacity[l]. These limits must be respected.
- The substitution pattern (Basic's demand served by Premium), absence of transshipment, zero lead times, and effectively non-binding labor capacities are the same as in the baseline scenario.
- The only intended structural change is in the cost weights: waste costs in the JSON are much larger, so discarding inventory is heavily discouraged, but the constraint system itself is not altered.
- The objective continues to minimize the sum of purchasing costs, holding costs, waste costs, and lost sales penalties over all products, locations, and periods.

[DATA]
The following JSON contains all instance data. Parse it directly in your code.

```json
{
  "name": "retail_f1_high_waste_v4",
  "description": "Standard seasonal retail scenario.",
  "periods": 20,
  "products": [
    "SKU_Basic",
    "SKU_Premium",
    "SKU_ShortLife"
  ],
  "locations": [
    "DC1",
    "DC2",
    "DC3",
    "DC4",
    "DC5"
  ],
  "shelf_life": {
    "SKU_Basic": 10,
    "SKU_Premium": 8,
    "SKU_ShortLife": 4
  },
  "lead_time": {
    "SKU_Basic": 0,
    "SKU_Premium": 0,
    "SKU_ShortLife": 0
  },
  "cold_capacity": {
    "DC1": 3430.373920082548,
    "DC2": 3117.199409297448,
    "DC3": 3249.5025472470406,
    "DC4": 3171.7893883100883,
    "DC5": 2551.077956769335
  },
  "cold_usage": {
    "SKU_Basic": 1.0,
    "SKU_Premium": 3.0,
    "SKU_ShortLife": 1.2
  },
  "production_cap": {
    "SKU_Basic": [
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800
    ],
    "SKU_Premium": [
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400
    ],
    "SKU_ShortLife": [
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500
    ]
  },
  "labor_cap": {
    "DC1": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC2": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC3": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC4": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC5": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ]
  },
  "labor_usage": {
    "SKU_Basic": 0.0,
    "SKU_Premium": 0.0,
    "SKU_ShortLife": 0.0
  },
  "return_rate": {
    "SKU_Basic": 0.0,
    "SKU_Premium": 0.0,
    "SKU_ShortLife": 0.0
  },
  "demand_curve": {
    "SKU_Basic": [
      262,
      292,
      343,
      318,
      463,
      621,
      802,
      881,
      1159,
      1300,
      1128,
      1311,
      1145,
      1022,
      667,
      619,
      484,
      329,
      279,
      281
    ],
    "SKU_Premium": [
      172,
      140,
      172,
      181,
      221,
      267,
      396,
      481,
      483,
      665,
      646,
      685,
      501,
      500,
      329,
      270,
      209,
      176,
      171,
      142
    ],
    "SKU_ShortLife": [
      109,
      126,
      143,
      134,
      192,
      241,
      257,
      332,
      438,
      474,
      467,
      491,
      503,
      397,
      265,
      220,
      150,
      165,
      116,
      141
    ]
  },
  "demand_share": {
    "DC1": 0.25,
    "DC2": 0.2,
    "DC3": 0.2,
    "DC4": 0.2,
    "DC5": 0.15
  },
  "costs": {
    "lost_sales": {
      "SKU_Basic": 50.0,
      "SKU_Premium": 80.0,
      "SKU_ShortLife": 40.0
    },
    "inventory": {
      "SKU_Basic": 1.0,
      "SKU_Premium": 1.5,
      "SKU_ShortLife": 1.0
    },
    "waste": {
      "SKU_Basic": 40.0,
      "SKU_Premium": 60.0,
      "SKU_ShortLife": 40.0
    },
    "fixed_order": 0.0,
    "transshipment": 0.5,
    "purchasing": {
      "SKU_Basic": 10.0,
      "SKU_Premium": 20.0,
      "SKU_ShortLife": 15.0
    }
  },
  "constraints": {
    "moq": 0,
    "pack_size": 1,
    "budget_per_period": null,
    "waste_limit_pct": null
  },
  "network": {
    "sub_edges": [
      [
        "SKU_Basic",
        "SKU_Premium"
      ]
    ],
    "trans_edges": []
  }
}
```

[OUTPUT FORMAT]
- Import: import gurobipy as gp; from gurobipy import GRB; import json
- Set Gurobi params: m.Params.OutputFlag = 0; m.Params.Threads = 1; m.Params.Seed = 0
- Print at end:
  print(f"status: {{m.Status}}")
  if m.Status == 2:
      print(f"objective: {{m.ObjVal}}")
- Output ONLY executable Python code. No markdown, no explanations.

[TASK]
Write a GurobiPy script that:
1. Parses the JSON data above (use json.loads on the string)
2. Models and solves the optimization problem
3. Prints status and objective value

Standard seasonal retail scenario.


[SCENARIO]
Family: F1 (Core Operations)
Archetype: retail_f1_jit_logic
Scenario ID: retail_f1_jit_logic_v0

[BUSINESS DESCRIPTION]
Business narrative:
This scenario represents a just-in-time regime where holding inventory is very expensive. The retailer still faces exogenous seasonal demand at each location, cannot backorder customers, and has limited per-product production capacity per period. Because holding costs are high, the retailer is incentivized to keep inventories as lean as possible while still avoiding excessive lost sales.

Structure cues:
- The physical network and decision timing are the same as in retail_f1_base: single-echelon, multi-product, multi-location, with local demand and local inventory.
- Inventory at each location carries over from the previous period, is increased by local production that arrives without delay, and is reduced by sales and any intentional waste. Stock levels must remain non-negative, and any demand in excess of available stock is treated as lost sales.
- Shelf life: Each product has a shelf life in periods. Inventory must be tracked by REMAINING LIFE.

  VARIABLE DEFINITION: I[p,l,t,r] = inventory at START of period t with r periods remaining.
  Convention: r=1 is OLDEST (sell first FIFO), r=shelf_life[p] is FRESHEST.

  KEY EQUATIONS - implement EXACTLY as written, do NOT add or remove terms:

  (1) Fresh inflow: I[p,l,t,SL] = Q[p,t] * demand_share[l]
      - This is ONLY the inflow from production. Do NOT subtract sales here!
      - Q is total production, demand_share distributes it to locations.

  (2) Aging: I[p,l,t+1,r] = I[p,l,t,r+1] - sales[p,l,t,r+1] for r=1..SL-1
      - Inventory tomorrow with r remaining = inventory today with r+1 remaining - sales

  (3) Waste: W[p,l,t] = I[p,l,t,1] - sales[p,l,t,1]
      - Items with r=1 that aren't sold become waste

  (4) Sales availability: sales[p,l,t,r] <= I[p,l,t,r]
      - Can only sell what you have in inventory

  (5) Inventory holding cost: charged on (I[p,l,t,r] - sales[p,l,t,r]) for r >= 2
      - Charge on END-of-period inventory (after sales), exclude expiring items (r=1)
- Storage capacity: sum over products of (cold_usage[p] * total_inventory[p,l,t]) <= cold_capacity[l]. These limits must be respected.
- Substitution behavior (Basic's demand served by Premium), absence of transshipment, and zero lead times all match the baseline archetype.
- Holding cost coefficients in the JSON are scaled up substantially compared with retail_f1_base, making on-hand inventory much more expensive relative to lost sales. The underlying constraint structure is unchanged.
- The objective is to minimize total cost including purchasing, holding, waste, and lost sales, with the higher holding cost forcing a just-in-time style of operation.

[DATA SCHEMA]
{
  "name": str,                          # scenario identifier
  "periods": int,                       # number of time periods
  "products": [str, ...],               # list of product IDs
  "locations": [str, ...],              # list of location IDs

  "shelf_life": {p: int},               # shelf life in periods per product
  "lead_time": {p: int},                # order lead time per product (0 = same-period arrival)

  "demand_curve": {p: [float, ...]},    # demand per product per period (0-indexed list)
  "demand_share": {l: float},           # fraction of total demand at each location

  "production_cap": {p: [float, ...]},  # max production per product per period (0-indexed list)
  "cold_capacity": {l: float},          # storage capacity per location
  "cold_usage": {p: float},             # storage units per unit of product

  "labor_cap": {l: [float, ...]},       # labor hours per location per period (0-indexed list)
  "labor_usage": {p: float},            # labor hours per unit sold
  "return_rate": {p: float},            # fraction of sales returned next period

  "costs": {
    "purchasing": {p: float},           # cost per unit ordered
    "inventory": {p: float},            # holding cost per unit per period
    "waste": {p: float},                # cost per unit expired
    "lost_sales": {p: float},           # penalty per unit of unmet demand
    "fixed_order": float,               # fixed cost per order placed
    "transshipment": float              # cost per unit transshipped
  },

  "constraints": {
    "moq": float,                       # minimum order quantity (0 = no MOQ)
    "pack_size": int,                   # order must be multiple of this (1 = no constraint)
    "budget_per_period": float|null,    # max purchasing cost per period
    "waste_limit_pct": float|null       # max waste as fraction of total demand
  },

  "network": {
    "sub_edges": [[p_from, p_to], ...], # substitution: p_from's demand can be served by p_to
    "trans_edges": [[l_from, l_to], ...]# transshipment: can ship from l_from to l_to
  }
}

[DATA ACCESS]
- The variable `data` is pre-loaded. Do NOT use file I/O.
- Lists are 0-indexed (period t in model uses index [t-1] in data arrays)

CRITICAL - Network edges require tuple conversion for Gurobi:
  sub_edges = [tuple(e) for e in data.get('network', {}).get('sub_edges', [])]
  trans_edges = [tuple(e) for e in data.get('network', {}).get('trans_edges', [])]

[OUTPUT FORMAT]
- Import: import gurobipy as gp; from gurobipy import GRB
- Set Gurobi params: m.Params.OutputFlag = 0; m.Params.Threads = 1; m.Params.Seed = 0
- Print at end:
  print(f"status: {{m.Status}}")
  if m.Status == 2:
      print(f"objective: {{m.ObjVal}}")
- Output ONLY executable Python code. No markdown, no explanations.

[TASK]
Write a GurobiPy script that models and solves this optimization problem.

[SCENARIO]
Family: F1 (Core Operations)
Archetype: retail_f1_jit_logic
Scenario ID: retail_f1_jit_logic_v0

[BUSINESS DESCRIPTION]
Business narrative:
This scenario represents a just-in-time regime where holding inventory is very expensive. The retailer still faces exogenous seasonal demand at each location, cannot backorder customers, and has limited per-product production capacity per period. Because holding costs are high, the retailer is incentivized to keep inventories as lean as possible while still avoiding excessive lost sales.

Structure cues:
- The physical network and decision timing are the same as in retail_f1_base: single-echelon, multi-product, multi-location, with local demand and local inventory.
- Inventory at each location carries over from the previous period, is increased by local production that arrives without delay, and is reduced by sales and any intentional waste. Stock levels must remain non-negative, and any demand in excess of available stock is treated as lost sales.
- Shelf life: Each product has a shelf life in periods. Inventory must be tracked by REMAINING LIFE.

  VARIABLE DEFINITION: I[p,l,t,r] = inventory at START of period t with r periods remaining.
  Convention: r=1 is OLDEST (sell first FIFO), r=shelf_life[p] is FRESHEST.

  KEY EQUATIONS - implement EXACTLY as written, do NOT add or remove terms:

  (1) Fresh inflow: I[p,l,t,SL] = Q[p,t] * demand_share[l]
      - This is ONLY the inflow from production. Do NOT subtract sales here!
      - Q is total production, demand_share distributes it to locations.

  (2) Aging: I[p,l,t+1,r] = I[p,l,t,r+1] - sales[p,l,t,r+1] for r=1..SL-1
      - Inventory tomorrow with r remaining = inventory today with r+1 remaining - sales

  (3) Waste: W[p,l,t] = I[p,l,t,1] - sales[p,l,t,1]
      - Items with r=1 that aren't sold become waste

  (4) Sales availability: sales[p,l,t,r] <= I[p,l,t,r]
      - Can only sell what you have in inventory

  (5) Inventory holding cost: charged on (I[p,l,t,r] - sales[p,l,t,r]) for r >= 2
      - Charge on END-of-period inventory (after sales), exclude expiring items (r=1)
- Storage capacity: sum over products of (cold_usage[p] * total_inventory[p,l,t]) <= cold_capacity[l]. These limits must be respected.
- Substitution behavior (Basic's demand served by Premium), absence of transshipment, and zero lead times all match the baseline archetype.
- Holding cost coefficients in the JSON are scaled up substantially compared with retail_f1_base, making on-hand inventory much more expensive relative to lost sales. The underlying constraint structure is unchanged.
- The objective is to minimize total cost including purchasing, holding, waste, and lost sales, with the higher holding cost forcing a just-in-time style of operation.

[DATA]
The following JSON contains all instance data. Parse it directly in your code.

```json
{
  "name": "retail_f1_jit_logic_v0",
  "description": "Standard seasonal retail scenario.",
  "periods": 20,
  "products": [
    "SKU_Basic",
    "SKU_Premium",
    "SKU_ShortLife"
  ],
  "locations": [
    "DC1",
    "DC2",
    "DC3",
    "DC4",
    "DC5"
  ],
  "shelf_life": {
    "SKU_Basic": 10,
    "SKU_Premium": 8,
    "SKU_ShortLife": 4
  },
  "lead_time": {
    "SKU_Basic": 0,
    "SKU_Premium": 0,
    "SKU_ShortLife": 0
  },
  "cold_capacity": {
    "DC1": 4000,
    "DC2": 3500,
    "DC3": 3000,
    "DC4": 3000,
    "DC5": 2500
  },
  "cold_usage": {
    "SKU_Basic": 1.0,
    "SKU_Premium": 3.0,
    "SKU_ShortLife": 1.2
  },
  "production_cap": {
    "SKU_Basic": [
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800
    ],
    "SKU_Premium": [
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400
    ],
    "SKU_ShortLife": [
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500
    ]
  },
  "labor_cap": {
    "DC1": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC2": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC3": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC4": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC5": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ]
  },
  "labor_usage": {
    "SKU_Basic": 0.0,
    "SKU_Premium": 0.0,
    "SKU_ShortLife": 0.0
  },
  "return_rate": {
    "SKU_Basic": 0.0,
    "SKU_Premium": 0.0,
    "SKU_ShortLife": 0.0
  },
  "demand_curve": {
    "SKU_Basic": [
      303,
      311,
      328,
      365,
      435,
      549,
      711,
      906,
      1100,
      1245,
      1300,
      1245,
      1100,
      906,
      711,
      549,
      435,
      365,
      328,
      311
    ],
    "SKU_Premium": [
      151,
      155,
      164,
      182,
      217,
      274,
      355,
      453,
      550,
      622,
      650,
      622,
      550,
      453,
      355,
      274,
      217,
      182,
      164,
      155
    ],
    "SKU_ShortLife": [
      121,
      124,
      131,
      146,
      174,
      219,
      284,
      362,
      440,
      498,
      520,
      498,
      440,
      362,
      284,
      219,
      174,
      146,
      131,
      124
    ]
  },
  "demand_share": {
    "DC1": 0.25,
    "DC2": 0.2,
    "DC3": 0.2,
    "DC4": 0.2,
    "DC5": 0.15
  },
  "costs": {
    "lost_sales": {
      "SKU_Basic": 50.0,
      "SKU_Premium": 80.0,
      "SKU_ShortLife": 40.0
    },
    "inventory": {
      "SKU_Basic": 20.0,
      "SKU_Premium": 30.0,
      "SKU_ShortLife": 20.0
    },
    "waste": {
      "SKU_Basic": 2.0,
      "SKU_Premium": 3.0,
      "SKU_ShortLife": 2.0
    },
    "fixed_order": 0.0,
    "transshipment": 0.5,
    "purchasing": {
      "SKU_Basic": 10.0,
      "SKU_Premium": 20.0,
      "SKU_ShortLife": 15.0
    }
  },
  "constraints": {
    "moq": 0,
    "pack_size": 1,
    "budget_per_period": null,
    "waste_limit_pct": null
  },
  "network": {
    "sub_edges": [
      [
        "SKU_Basic",
        "SKU_Premium"
      ]
    ],
    "trans_edges": []
  }
}
```

[OUTPUT FORMAT]
- Import: import gurobipy as gp; from gurobipy import GRB; import json
- Set Gurobi params: m.Params.OutputFlag = 0; m.Params.Threads = 1; m.Params.Seed = 0
- Print at end:
  print(f"status: {{m.Status}}")
  if m.Status == 2:
      print(f"objective: {{m.ObjVal}}")
- Output ONLY executable Python code. No markdown, no explanations.

[TASK]
Write a GurobiPy script that:
1. Parses the JSON data above (use json.loads on the string)
2. Models and solves the optimization problem
3. Prints status and objective value

Standard seasonal retail scenario.


[SCENARIO]
Family: F1 (Core Operations)
Archetype: retail_f1_jit_logic
Scenario ID: retail_f1_jit_logic_v1

[BUSINESS DESCRIPTION]
Business narrative:
This scenario represents a just-in-time regime where holding inventory is very expensive. The retailer still faces exogenous seasonal demand at each location, cannot backorder customers, and has limited per-product production capacity per period. Because holding costs are high, the retailer is incentivized to keep inventories as lean as possible while still avoiding excessive lost sales.

Structure cues:
- The physical network and decision timing are the same as in retail_f1_base: single-echelon, multi-product, multi-location, with local demand and local inventory.
- Inventory at each location carries over from the previous period, is increased by local production that arrives without delay, and is reduced by sales and any intentional waste. Stock levels must remain non-negative, and any demand in excess of available stock is treated as lost sales.
- Shelf life: Each product has a shelf life in periods. Inventory must be tracked by REMAINING LIFE.

  VARIABLE DEFINITION: I[p,l,t,r] = inventory at START of period t with r periods remaining.
  Convention: r=1 is OLDEST (sell first FIFO), r=shelf_life[p] is FRESHEST.

  KEY EQUATIONS - implement EXACTLY as written, do NOT add or remove terms:

  (1) Fresh inflow: I[p,l,t,SL] = Q[p,t] * demand_share[l]
      - This is ONLY the inflow from production. Do NOT subtract sales here!
      - Q is total production, demand_share distributes it to locations.

  (2) Aging: I[p,l,t+1,r] = I[p,l,t,r+1] - sales[p,l,t,r+1] for r=1..SL-1
      - Inventory tomorrow with r remaining = inventory today with r+1 remaining - sales

  (3) Waste: W[p,l,t] = I[p,l,t,1] - sales[p,l,t,1]
      - Items with r=1 that aren't sold become waste

  (4) Sales availability: sales[p,l,t,r] <= I[p,l,t,r]
      - Can only sell what you have in inventory

  (5) Inventory holding cost: charged on (I[p,l,t,r] - sales[p,l,t,r]) for r >= 2
      - Charge on END-of-period inventory (after sales), exclude expiring items (r=1)
- Storage capacity: sum over products of (cold_usage[p] * total_inventory[p,l,t]) <= cold_capacity[l]. These limits must be respected.
- Substitution behavior (Basic's demand served by Premium), absence of transshipment, and zero lead times all match the baseline archetype.
- Holding cost coefficients in the JSON are scaled up substantially compared with retail_f1_base, making on-hand inventory much more expensive relative to lost sales. The underlying constraint structure is unchanged.
- The objective is to minimize total cost including purchasing, holding, waste, and lost sales, with the higher holding cost forcing a just-in-time style of operation.

[DATA SCHEMA]
{
  "name": str,                          # scenario identifier
  "periods": int,                       # number of time periods
  "products": [str, ...],               # list of product IDs
  "locations": [str, ...],              # list of location IDs

  "shelf_life": {p: int},               # shelf life in periods per product
  "lead_time": {p: int},                # order lead time per product (0 = same-period arrival)

  "demand_curve": {p: [float, ...]},    # demand per product per period (0-indexed list)
  "demand_share": {l: float},           # fraction of total demand at each location

  "production_cap": {p: [float, ...]},  # max production per product per period (0-indexed list)
  "cold_capacity": {l: float},          # storage capacity per location
  "cold_usage": {p: float},             # storage units per unit of product

  "labor_cap": {l: [float, ...]},       # labor hours per location per period (0-indexed list)
  "labor_usage": {p: float},            # labor hours per unit sold
  "return_rate": {p: float},            # fraction of sales returned next period

  "costs": {
    "purchasing": {p: float},           # cost per unit ordered
    "inventory": {p: float},            # holding cost per unit per period
    "waste": {p: float},                # cost per unit expired
    "lost_sales": {p: float},           # penalty per unit of unmet demand
    "fixed_order": float,               # fixed cost per order placed
    "transshipment": float              # cost per unit transshipped
  },

  "constraints": {
    "moq": float,                       # minimum order quantity (0 = no MOQ)
    "pack_size": int,                   # order must be multiple of this (1 = no constraint)
    "budget_per_period": float|null,    # max purchasing cost per period
    "waste_limit_pct": float|null       # max waste as fraction of total demand
  },

  "network": {
    "sub_edges": [[p_from, p_to], ...], # substitution: p_from's demand can be served by p_to
    "trans_edges": [[l_from, l_to], ...]# transshipment: can ship from l_from to l_to
  }
}

[DATA ACCESS]
- The variable `data` is pre-loaded. Do NOT use file I/O.
- Lists are 0-indexed (period t in model uses index [t-1] in data arrays)

CRITICAL - Network edges require tuple conversion for Gurobi:
  sub_edges = [tuple(e) for e in data.get('network', {}).get('sub_edges', [])]
  trans_edges = [tuple(e) for e in data.get('network', {}).get('trans_edges', [])]

[OUTPUT FORMAT]
- Import: import gurobipy as gp; from gurobipy import GRB
- Set Gurobi params: m.Params.OutputFlag = 0; m.Params.Threads = 1; m.Params.Seed = 0
- Print at end:
  print(f"status: {{m.Status}}")
  if m.Status == 2:
      print(f"objective: {{m.ObjVal}}")
- Output ONLY executable Python code. No markdown, no explanations.

[TASK]
Write a GurobiPy script that models and solves this optimization problem.

[SCENARIO]
Family: F1 (Core Operations)
Archetype: retail_f1_jit_logic
Scenario ID: retail_f1_jit_logic_v1

[BUSINESS DESCRIPTION]
Business narrative:
This scenario represents a just-in-time regime where holding inventory is very expensive. The retailer still faces exogenous seasonal demand at each location, cannot backorder customers, and has limited per-product production capacity per period. Because holding costs are high, the retailer is incentivized to keep inventories as lean as possible while still avoiding excessive lost sales.

Structure cues:
- The physical network and decision timing are the same as in retail_f1_base: single-echelon, multi-product, multi-location, with local demand and local inventory.
- Inventory at each location carries over from the previous period, is increased by local production that arrives without delay, and is reduced by sales and any intentional waste. Stock levels must remain non-negative, and any demand in excess of available stock is treated as lost sales.
- Shelf life: Each product has a shelf life in periods. Inventory must be tracked by REMAINING LIFE.

  VARIABLE DEFINITION: I[p,l,t,r] = inventory at START of period t with r periods remaining.
  Convention: r=1 is OLDEST (sell first FIFO), r=shelf_life[p] is FRESHEST.

  KEY EQUATIONS - implement EXACTLY as written, do NOT add or remove terms:

  (1) Fresh inflow: I[p,l,t,SL] = Q[p,t] * demand_share[l]
      - This is ONLY the inflow from production. Do NOT subtract sales here!
      - Q is total production, demand_share distributes it to locations.

  (2) Aging: I[p,l,t+1,r] = I[p,l,t,r+1] - sales[p,l,t,r+1] for r=1..SL-1
      - Inventory tomorrow with r remaining = inventory today with r+1 remaining - sales

  (3) Waste: W[p,l,t] = I[p,l,t,1] - sales[p,l,t,1]
      - Items with r=1 that aren't sold become waste

  (4) Sales availability: sales[p,l,t,r] <= I[p,l,t,r]
      - Can only sell what you have in inventory

  (5) Inventory holding cost: charged on (I[p,l,t,r] - sales[p,l,t,r]) for r >= 2
      - Charge on END-of-period inventory (after sales), exclude expiring items (r=1)
- Storage capacity: sum over products of (cold_usage[p] * total_inventory[p,l,t]) <= cold_capacity[l]. These limits must be respected.
- Substitution behavior (Basic's demand served by Premium), absence of transshipment, and zero lead times all match the baseline archetype.
- Holding cost coefficients in the JSON are scaled up substantially compared with retail_f1_base, making on-hand inventory much more expensive relative to lost sales. The underlying constraint structure is unchanged.
- The objective is to minimize total cost including purchasing, holding, waste, and lost sales, with the higher holding cost forcing a just-in-time style of operation.

[DATA]
The following JSON contains all instance data. Parse it directly in your code.

```json
{
  "name": "retail_f1_jit_logic_v1",
  "description": "Standard seasonal retail scenario.",
  "periods": 20,
  "products": [
    "SKU_Basic",
    "SKU_Premium",
    "SKU_ShortLife"
  ],
  "locations": [
    "DC1",
    "DC2",
    "DC3",
    "DC4",
    "DC5"
  ],
  "shelf_life": {
    "SKU_Basic": 10,
    "SKU_Premium": 8,
    "SKU_ShortLife": 4
  },
  "lead_time": {
    "SKU_Basic": 0,
    "SKU_Premium": 0,
    "SKU_ShortLife": 0
  },
  "cold_capacity": {
    "DC1": 4227.503985981191,
    "DC2": 3175.2200216676033,
    "DC3": 2994.148110462189,
    "DC4": 3096.259483977715,
    "DC5": 2402.735217991342
  },
  "cold_usage": {
    "SKU_Basic": 1.0,
    "SKU_Premium": 3.0,
    "SKU_ShortLife": 1.2
  },
  "production_cap": {
    "SKU_Basic": [
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800
    ],
    "SKU_Premium": [
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400
    ],
    "SKU_ShortLife": [
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500
    ]
  },
  "labor_cap": {
    "DC1": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC2": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC3": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC4": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC5": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ]
  },
  "labor_usage": {
    "SKU_Basic": 0.0,
    "SKU_Premium": 0.0,
    "SKU_ShortLife": 0.0
  },
  "return_rate": {
    "SKU_Basic": 0.0,
    "SKU_Premium": 0.0,
    "SKU_ShortLife": 0.0
  },
  "demand_curve": {
    "SKU_Basic": [
      309,
      303,
      337,
      340,
      452,
      609,
      663,
      844,
      1155,
      1285,
      1418,
      1103,
      1209,
      843,
      806,
      541,
      375,
      330,
      357,
      321
    ],
    "SKU_Premium": [
      165,
      151,
      157,
      154,
      209,
      280,
      385,
      478,
      620,
      635,
      609,
      667,
      566,
      451,
      357,
      266,
      204,
      188,
      146,
      169
    ],
    "SKU_ShortLife": [
      104,
      132,
      122,
      155,
      162,
      226,
      288,
      334,
      421,
      514,
      527,
      527,
      434,
      326,
      251,
      232,
      151,
      130,
      114,
      122
    ]
  },
  "demand_share": {
    "DC1": 0.25,
    "DC2": 0.2,
    "DC3": 0.2,
    "DC4": 0.2,
    "DC5": 0.15
  },
  "costs": {
    "lost_sales": {
      "SKU_Basic": 50.0,
      "SKU_Premium": 80.0,
      "SKU_ShortLife": 40.0
    },
    "inventory": {
      "SKU_Basic": 20.0,
      "SKU_Premium": 30.0,
      "SKU_ShortLife": 20.0
    },
    "waste": {
      "SKU_Basic": 2.0,
      "SKU_Premium": 3.0,
      "SKU_ShortLife": 2.0
    },
    "fixed_order": 0.0,
    "transshipment": 0.5,
    "purchasing": {
      "SKU_Basic": 10.0,
      "SKU_Premium": 20.0,
      "SKU_ShortLife": 15.0
    }
  },
  "constraints": {
    "moq": 0,
    "pack_size": 1,
    "budget_per_period": null,
    "waste_limit_pct": null
  },
  "network": {
    "sub_edges": [
      [
        "SKU_Basic",
        "SKU_Premium"
      ]
    ],
    "trans_edges": []
  }
}
```

[OUTPUT FORMAT]
- Import: import gurobipy as gp; from gurobipy import GRB; import json
- Set Gurobi params: m.Params.OutputFlag = 0; m.Params.Threads = 1; m.Params.Seed = 0
- Print at end:
  print(f"status: {{m.Status}}")
  if m.Status == 2:
      print(f"objective: {{m.ObjVal}}")
- Output ONLY executable Python code. No markdown, no explanations.

[TASK]
Write a GurobiPy script that:
1. Parses the JSON data above (use json.loads on the string)
2. Models and solves the optimization problem
3. Prints status and objective value

Standard seasonal retail scenario.


[SCENARIO]
Family: F1 (Core Operations)
Archetype: retail_f1_jit_logic
Scenario ID: retail_f1_jit_logic_v2

[BUSINESS DESCRIPTION]
Business narrative:
This scenario represents a just-in-time regime where holding inventory is very expensive. The retailer still faces exogenous seasonal demand at each location, cannot backorder customers, and has limited per-product production capacity per period. Because holding costs are high, the retailer is incentivized to keep inventories as lean as possible while still avoiding excessive lost sales.

Structure cues:
- The physical network and decision timing are the same as in retail_f1_base: single-echelon, multi-product, multi-location, with local demand and local inventory.
- Inventory at each location carries over from the previous period, is increased by local production that arrives without delay, and is reduced by sales and any intentional waste. Stock levels must remain non-negative, and any demand in excess of available stock is treated as lost sales.
- Shelf life: Each product has a shelf life in periods. Inventory must be tracked by REMAINING LIFE.

  VARIABLE DEFINITION: I[p,l,t,r] = inventory at START of period t with r periods remaining.
  Convention: r=1 is OLDEST (sell first FIFO), r=shelf_life[p] is FRESHEST.

  KEY EQUATIONS - implement EXACTLY as written, do NOT add or remove terms:

  (1) Fresh inflow: I[p,l,t,SL] = Q[p,t] * demand_share[l]
      - This is ONLY the inflow from production. Do NOT subtract sales here!
      - Q is total production, demand_share distributes it to locations.

  (2) Aging: I[p,l,t+1,r] = I[p,l,t,r+1] - sales[p,l,t,r+1] for r=1..SL-1
      - Inventory tomorrow with r remaining = inventory today with r+1 remaining - sales

  (3) Waste: W[p,l,t] = I[p,l,t,1] - sales[p,l,t,1]
      - Items with r=1 that aren't sold become waste

  (4) Sales availability: sales[p,l,t,r] <= I[p,l,t,r]
      - Can only sell what you have in inventory

  (5) Inventory holding cost: charged on (I[p,l,t,r] - sales[p,l,t,r]) for r >= 2
      - Charge on END-of-period inventory (after sales), exclude expiring items (r=1)
- Storage capacity: sum over products of (cold_usage[p] * total_inventory[p,l,t]) <= cold_capacity[l]. These limits must be respected.
- Substitution behavior (Basic's demand served by Premium), absence of transshipment, and zero lead times all match the baseline archetype.
- Holding cost coefficients in the JSON are scaled up substantially compared with retail_f1_base, making on-hand inventory much more expensive relative to lost sales. The underlying constraint structure is unchanged.
- The objective is to minimize total cost including purchasing, holding, waste, and lost sales, with the higher holding cost forcing a just-in-time style of operation.

[DATA SCHEMA]
{
  "name": str,                          # scenario identifier
  "periods": int,                       # number of time periods
  "products": [str, ...],               # list of product IDs
  "locations": [str, ...],              # list of location IDs

  "shelf_life": {p: int},               # shelf life in periods per product
  "lead_time": {p: int},                # order lead time per product (0 = same-period arrival)

  "demand_curve": {p: [float, ...]},    # demand per product per period (0-indexed list)
  "demand_share": {l: float},           # fraction of total demand at each location

  "production_cap": {p: [float, ...]},  # max production per product per period (0-indexed list)
  "cold_capacity": {l: float},          # storage capacity per location
  "cold_usage": {p: float},             # storage units per unit of product

  "labor_cap": {l: [float, ...]},       # labor hours per location per period (0-indexed list)
  "labor_usage": {p: float},            # labor hours per unit sold
  "return_rate": {p: float},            # fraction of sales returned next period

  "costs": {
    "purchasing": {p: float},           # cost per unit ordered
    "inventory": {p: float},            # holding cost per unit per period
    "waste": {p: float},                # cost per unit expired
    "lost_sales": {p: float},           # penalty per unit of unmet demand
    "fixed_order": float,               # fixed cost per order placed
    "transshipment": float              # cost per unit transshipped
  },

  "constraints": {
    "moq": float,                       # minimum order quantity (0 = no MOQ)
    "pack_size": int,                   # order must be multiple of this (1 = no constraint)
    "budget_per_period": float|null,    # max purchasing cost per period
    "waste_limit_pct": float|null       # max waste as fraction of total demand
  },

  "network": {
    "sub_edges": [[p_from, p_to], ...], # substitution: p_from's demand can be served by p_to
    "trans_edges": [[l_from, l_to], ...]# transshipment: can ship from l_from to l_to
  }
}

[DATA ACCESS]
- The variable `data` is pre-loaded. Do NOT use file I/O.
- Lists are 0-indexed (period t in model uses index [t-1] in data arrays)

CRITICAL - Network edges require tuple conversion for Gurobi:
  sub_edges = [tuple(e) for e in data.get('network', {}).get('sub_edges', [])]
  trans_edges = [tuple(e) for e in data.get('network', {}).get('trans_edges', [])]

[OUTPUT FORMAT]
- Import: import gurobipy as gp; from gurobipy import GRB
- Set Gurobi params: m.Params.OutputFlag = 0; m.Params.Threads = 1; m.Params.Seed = 0
- Print at end:
  print(f"status: {{m.Status}}")
  if m.Status == 2:
      print(f"objective: {{m.ObjVal}}")
- Output ONLY executable Python code. No markdown, no explanations.

[TASK]
Write a GurobiPy script that models and solves this optimization problem.

[SCENARIO]
Family: F1 (Core Operations)
Archetype: retail_f1_jit_logic
Scenario ID: retail_f1_jit_logic_v2

[BUSINESS DESCRIPTION]
Business narrative:
This scenario represents a just-in-time regime where holding inventory is very expensive. The retailer still faces exogenous seasonal demand at each location, cannot backorder customers, and has limited per-product production capacity per period. Because holding costs are high, the retailer is incentivized to keep inventories as lean as possible while still avoiding excessive lost sales.

Structure cues:
- The physical network and decision timing are the same as in retail_f1_base: single-echelon, multi-product, multi-location, with local demand and local inventory.
- Inventory at each location carries over from the previous period, is increased by local production that arrives without delay, and is reduced by sales and any intentional waste. Stock levels must remain non-negative, and any demand in excess of available stock is treated as lost sales.
- Shelf life: Each product has a shelf life in periods. Inventory must be tracked by REMAINING LIFE.

  VARIABLE DEFINITION: I[p,l,t,r] = inventory at START of period t with r periods remaining.
  Convention: r=1 is OLDEST (sell first FIFO), r=shelf_life[p] is FRESHEST.

  KEY EQUATIONS - implement EXACTLY as written, do NOT add or remove terms:

  (1) Fresh inflow: I[p,l,t,SL] = Q[p,t] * demand_share[l]
      - This is ONLY the inflow from production. Do NOT subtract sales here!
      - Q is total production, demand_share distributes it to locations.

  (2) Aging: I[p,l,t+1,r] = I[p,l,t,r+1] - sales[p,l,t,r+1] for r=1..SL-1
      - Inventory tomorrow with r remaining = inventory today with r+1 remaining - sales

  (3) Waste: W[p,l,t] = I[p,l,t,1] - sales[p,l,t,1]
      - Items with r=1 that aren't sold become waste

  (4) Sales availability: sales[p,l,t,r] <= I[p,l,t,r]
      - Can only sell what you have in inventory

  (5) Inventory holding cost: charged on (I[p,l,t,r] - sales[p,l,t,r]) for r >= 2
      - Charge on END-of-period inventory (after sales), exclude expiring items (r=1)
- Storage capacity: sum over products of (cold_usage[p] * total_inventory[p,l,t]) <= cold_capacity[l]. These limits must be respected.
- Substitution behavior (Basic's demand served by Premium), absence of transshipment, and zero lead times all match the baseline archetype.
- Holding cost coefficients in the JSON are scaled up substantially compared with retail_f1_base, making on-hand inventory much more expensive relative to lost sales. The underlying constraint structure is unchanged.
- The objective is to minimize total cost including purchasing, holding, waste, and lost sales, with the higher holding cost forcing a just-in-time style of operation.

[DATA]
The following JSON contains all instance data. Parse it directly in your code.

```json
{
  "name": "retail_f1_jit_logic_v2",
  "description": "Standard seasonal retail scenario.",
  "periods": 20,
  "products": [
    "SKU_Basic",
    "SKU_Premium",
    "SKU_ShortLife"
  ],
  "locations": [
    "DC1",
    "DC2",
    "DC3",
    "DC4",
    "DC5"
  ],
  "shelf_life": {
    "SKU_Basic": 10,
    "SKU_Premium": 8,
    "SKU_ShortLife": 4
  },
  "lead_time": {
    "SKU_Basic": 0,
    "SKU_Premium": 0,
    "SKU_ShortLife": 0
  },
  "cold_capacity": {
    "DC1": 4452.650038535987,
    "DC2": 3413.3710389191046,
    "DC3": 2793.7486082944533,
    "DC4": 2591.9222764205074,
    "DC5": 2357.3241337705263
  },
  "cold_usage": {
    "SKU_Basic": 1.0,
    "SKU_Premium": 3.0,
    "SKU_ShortLife": 1.2
  },
  "production_cap": {
    "SKU_Basic": [
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800,
      800
    ],
    "SKU_Premium": [
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400,
      400
    ],
    "SKU_ShortLife": [
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500,
      500
    ]
  },
  "labor_cap": {
    "DC1": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC2": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC3": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC4": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ],
    "DC5": [
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0,
      99999.0
    ]
  },
  "labor_usage": {
    "SKU_Basic": 0.0,
    "SKU_Premium": 0.0,
    "SKU_ShortLife": 0.0
  },
  "return_rate": {
    "SKU_Basic": 0.0,
    "SKU_Premium": 0.0,
    "SKU_ShortLife": 0.0
  },
  "demand_curve": {
    "SKU_Basic": [
      257,
      319,
      344,
      411,
      494,
      519,
      750,
      871,
      1258,
      1264,
      1196,
      1414,
      1086,
      927,
      638,
      584,
      419,
      392,
      323,
      350
    ],
    "SKU_Premium": [
      171,
      137,
      187,
      206,
      247,
      247,
      376,
      386,
      471,
      639,
      647,
      604,
      615,
      474,
      329,
      293,
      199,
      175,
      174,
      147
    ],
    "SKU_ShortLife": [
      136,
      128,
      119,
      161,
      173,
      193,
      251,
      393,
      442,
      527,
      542,
      453,
      435,
      385,
      250,
      219,
      153,
      163,
      122,
      110
    ]
  },
  "demand_share": {
    "DC1": 0.25,
    "DC2": 0.2,
    "DC3": 0.2,
    "DC4": 0.2,
    "DC5": 0.15
  },
  "costs": {
    "lost_sales": {
      "SKU_Basic": 50.0,
      "SKU_Premium": 80.0,
      "SKU_ShortLife": 40.0
    },
    "inventory": {
      "SKU_Basic": 20.0,
      "SKU_Premium": 30.0,
      "SKU_ShortLife": 20.0
    },
    "waste": {
      "SKU_Basic": 2.0,
      "SKU_Premium": 3.0,
      "SKU_ShortLife": 2.0
    },
    "fixed_order": 0.0,
    "transshipment": 0.5,
    "purchasing": {
      "SKU_Basic": 10.0,
      "SKU_Premium": 20.0,
      "SKU_ShortLife": 15.0
    }
  },
  "constraints": {
    "moq": 0,
    "pack_size": 1,
    "budget_per_period": null,
    "waste_limit_pct": null
  },
  "network": {
    "sub_edges": [
      [
        "SKU_Basic",
        "SKU_Premium"
      ]
    ],
    "trans_edges": []
  }
}
```

[OUTPUT FORMAT]
- Import: import gurobipy as gp; from gurobipy import GRB; import json
- Set Gurobi params: m.Params.OutputFlag = 0; m.Params.Threads = 1; m.Params.Seed = 0
- Print at end:
  print(f"status: {{m.Status}}")
  if m.Status == 2:
      print(f"objective: {{m.ObjVal}}")
- Output ONLY executable Python code. No markdown, no explanations.

[TASK]
Write a GurobiPy script that:
1. Parses the JSON data above (use json.loads on the string)
2. Models and solves the optimization problem
3. Prints status and objective value

Standard seasonal retail scenario.