# Complete DOCPLEX implementation - Retry Attempt 4

from docplex.mp.model import Model

def naval_optimization():
    """Optimizes ship assignments to minimize battle deaths."""
    
    # 1. MODEL & DATA SETUP
    mdl = Model(name="battle_death_minimization")
    
    # Data from the problem context
    ships = [1, 2, 3]
    battles = [101, 102, 103]
    deaths_data = {
        (1, 101): 15,
        (2, 102): 25,
        (3, 103): 5
    }
    min_ships_required = {
        101: 3,
        102: 5,
        103: 2
    }
    max_ships = 5  # Assumed maximum number of ships available
    
    # CRITICAL: Validate array lengths to prevent IndexError
    assert len(deaths_data) == len(ships), "Array length mismatch"
    
    # 2. VARIABLES
    # Binary decision variables for ship assignments
    x = {(i, j): mdl.binary_var(name=f"x_{i}_{j}") for i in ships for j in battles}
    
    # 3. OBJECTIVE FUNCTION
    # Minimize total deaths
    objective = mdl.sum(deaths_data.get((i, j), 0) * x[i, j] for i in ships for j in battles)
    mdl.minimize(objective)
    
    # 4. CONSTRAINTS
    
    # Each ship can be assigned to at most one battle
    for i in ships:
        mdl.add_constraint(mdl.sum(x[i, j] for j in battles) <= 1, ctname=f"ship_{i}_assignment")
    
    # Each battle must receive at least the minimum required number of ships
    for j in battles:
        mdl.add_constraint(mdl.sum(x[i, j] for i in ships) >= min_ships_required[j], ctname=f"battle_{j}_min_ships")
    
    # The total number of ships assigned cannot exceed the maximum number available
    mdl.add_constraint(mdl.sum(x[i, j] for i in ships for j in battles) <= max_ships, ctname="max_ships_limit")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for i in ships:
            for j in battles:
                if solution.get_value(x[i, j]) > 0.5:  # Binary variable threshold
                    print(f"Ship {i} assigned to Battle {j}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")

# Execute the optimization
naval_optimization()