# Complete DOCPLEX implementation - Retry Attempt 4

from docplex.mp.model import Model

def optimize_ship_captain_assignment():
    # 1. MODEL & DATA SETUP
    mdl = Model(name="ship_captain_assignment")
    
    # Data from the problem
    captains = [1, 2, 3]
    ships = [1, 2, 3]
    
    # Cost coefficients
    cost_coefficients = {
        (1, 1): 1200,
        (2, 2): 1500,
        (3, 3): 1000
    }
    
    # Compatibility rules
    compatibility_rules = {
        (1, 1): True,
        (2, 2): True,
        (3, 3): True,
        (1, 2): False,
        (1, 3): False,
        (2, 1): False,
        (2, 3): False,
        (3, 1): False,
        (3, 2): False
    }
    
    # Age rules
    age_rules = {
        (1, 1): True,
        (2, 2): True,
        (3, 3): True,
        (1, 2): False,
        (1, 3): False,
        (2, 1): False,
        (2, 3): False,
        (3, 1): False,
        (3, 2): False
    }
    
    # 2. VARIABLES
    x = mdl.binary_var_dict(keys=[(i, j) for i in captains for j in ships], name="x")
    
    # 3. OBJECTIVE FUNCTION
    objective = mdl.sum(cost_coefficients[(i, j)] * x[(i, j)] for i in captains for j in ships)
    mdl.minimize(objective)
    
    # 4. CONSTRAINTS
    
    # Ship Assignment Constraint: Each ship must be assigned exactly one captain
    for j in ships:
        mdl.add_constraint(mdl.sum(x[(i, j)] for i in captains) == 1, ctname=f"ship_assignment_{j}")
    
    # Captain Assignment Constraint: Each captain can be assigned to at most one ship
    for i in captains:
        mdl.add_constraint(mdl.sum(x[(i, j)] for j in ships) <= 1, ctname=f"captain_assignment_{i}")
    
    # Compatibility Constraint: A captain can only be assigned to a ship if their rank is compatible with the ship's type
    for i in captains:
        for j in ships:
            mdl.add_constraint(x[(i, j)] <= compatibility_rules[(i, j)], ctname=f"compatibility_{i}_{j}")
    
    # Age Constraint: A captain can only be assigned to a ship if the ship's age is acceptable for their rank
    for i in captains:
        for j in ships:
            mdl.add_constraint(x[(i, j)] <= age_rules[(i, j)], ctname=f"age_{i}_{j}")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for i in captains:
            for j in ships:
                if solution.get_value(x[(i, j)]) > 0.5:
                    print(f"Captain {i} assigned to Ship {j}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")
    
    return mdl

# Execute the optimization
optimize_ship_captain_assignment()