# Complete GUROBIPY implementation - Retry Attempt 4

import gurobipy as gp
from gurobipy import GRB

def pilot_assignment_optimization():
    # 1. MODEL & DATA SETUP
    model = gp.Model("pilot_assignment")

    # Define sets
    pilots = [1, 2, 3]
    aircraft = [101, 102, 103]

    # Cost coefficients
    cost_coefficients = {
        (1, 101): 2.55,
        (2, 102): 3.4,
        (3, 103): 4.25
    }

    # Pilot qualifications
    pilot_qualifications = {
        (1, 101): 1,
        (2, 102): 1,
        (3, 103): 0
    }

    # Validate data consistency
    assert all((p, a) in cost_coefficients for p in pilots for a in aircraft), "Missing cost coefficients"
    assert all((p, a) in pilot_qualifications for p in pilots for a in aircraft), "Missing pilot qualifications"

    # 2. VARIABLES
    x = model.addVars(pilots, aircraft, vtype=GRB.BINARY, name="x")

    # 3. OBJECTIVE FUNCTION
    model.setObjective(gp.quicksum(cost_coefficients[p, a] * x[p, a] for p in pilots for a in aircraft), GRB.MINIMIZE)

    # 4. CONSTRAINTS

    # Pilot Assignment Limit
    for p in pilots:
        model.addConstr(gp.quicksum(x[p, a] for a in aircraft) <= 1, name=f"pilot_limit_{p}")

    # Aircraft Assignment Requirement
    for a in aircraft:
        model.addConstr(gp.quicksum(x[p, a] for p in pilots) == 1, name=f"aircraft_requirement_{a}")

    # Pilot Qualifications
    for p in pilots:
        for a in aircraft:
            model.addConstr(x[p, a] <= pilot_qualifications[p, a], name=f"qualification_{p}_{a}")

    # 5. SOLVING & RESULTS
    model.optimize()

    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for p in pilots:
            for a in aircraft:
                if x[p, a].x > 1e-6:
                    print(f"Pilot {p} assigned to Aircraft {a}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")

    return model

# Execute the optimization
pilot_assignment_optimization()