# Complete GUROBIPY implementation - Retry Attempt 4

import gurobipy as gp
from gurobipy import GRB

def dorm_optimization():
    """Optimize student-dorm assignments using Gurobi"""
    
    # 1. MODEL & DATA SETUP
    model = gp.Model("dorm_optimization")
    
    # Example data setup
    students = [1, 2, 3]
    dorms = [101, 102, 103]
    capacities = {101: 1, 102: 1, 103: 1}
    gender_match = {(1, 101): 1, (2, 102): 1, (3, 103): 1}
    
    # Objective coefficients from the database
    coefficients = {
        (1, 101): 1.0,
        (2, 102): 1.0,
        (3, 103): 0.5
    }
    
    # CRITICAL: Validate data completeness
    assert all((i, j) in coefficients for i in students for j in dorms if (i, j) in gender_match), "Coefficient data missing"
    
    # 2. VARIABLES
    x = model.addVars(students, dorms, vtype=GRB.BINARY, name="x")
    
    # 3. OBJECTIVE FUNCTION
    model.setObjective(gp.quicksum(coefficients[i, j] * x[i, j] for i in students for j in dorms if (i, j) in coefficients), GRB.MAXIMIZE)
    
    # 4. CONSTRAINTS
    
    # Capacity constraints
    for j in dorms:
        model.addConstr(gp.quicksum(x[i, j] for i in students if (i, j) in gender_match) <= capacities[j], name=f"capacity_{j}")
    
    # Gender compatibility constraints
    for i in students:
        for j in dorms:
            if (i, j) in gender_match:
                model.addConstr(x[i, j] <= gender_match[i, j], name=f"gender_match_{i}_{j}")
    
    # Assignment constraints
    for i in students:
        model.addConstr(gp.quicksum(x[i, j] for j in dorms if (i, j) in gender_match) == 1, name=f"assignment_{i}")
    
    # 5. SOLVING & RESULTS
    model.optimize()
    
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for i in students:
            for j in dorms:
                if (i, j) in gender_match and x[i, j].x > 1e-6:
                    print(f"Student {i} assigned to Dorm {j}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")

# Run the optimization
dorm_optimization()