# Complete GUROBIPY implementation - Retry Attempt 4

import gurobipy as gp
from gurobipy import GRB

def allergy_accommodation_optimization():
    # 1. MODEL & DATA SETUP
    model = gp.Model("allergy_accommodation")
    
    # Define allergy types and cities
    allergy_types = ['peanut', 'dairy', 'gluten']
    cities = ['NYC', 'LA', 'CHI']
    
    # Cost data for each allergy type and city
    costs = {
        ('peanut', 'NYC'): 120.0,
        ('dairy', 'LA'): 100.0,
        ('gluten', 'CHI'): 90.0
    }
    
    # Validate that all allergy-city pairs have cost data
    for i in allergy_types:
        for j in cities:
            if (i, j) not in costs:
                raise ValueError(f"Missing cost data for {i} in {j}")
    
    # Budget and minimum resource requirement
    budget = 500000
    min_resource = 5
    
    # 2. VARIABLES
    x = model.addVars(allergy_types, cities, vtype=GRB.CONTINUOUS, name="x", lb=min_resource)
    
    # 3. OBJECTIVE FUNCTION
    model.setObjective(gp.quicksum(costs[i, j] * x[i, j] for i in allergy_types for j in cities), GRB.MINIMIZE)
    
    # 4. CONSTRAINTS
    # Budget constraint
    model.addConstr(gp.quicksum(costs[i, j] * x[i, j] for i in allergy_types for j in cities) <= budget, name="budget_constraint")
    
    # Minimum resource requirement (already handled by variable lower bounds)
    
    # 5. SOLVING & RESULTS
    model.optimize()
    
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for i in allergy_types:
            for j in cities:
                print(f"x[{i}, {j}] = {x[i, j].x:.3f}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")
    
    return model

# Execute the optimization
allergy_accommodation_optimization()