# Complete DOCPLEX implementation - Retry Attempt 4

from docplex.mp.model import Model

def optimize_player_allocation():
    # 1. MODEL & DATA SETUP
    mdl = Model(name="player_allocation")
    
    # Sample data based on the provided schema
    players = [1, 2, 3]
    teams = [1, 2, 3]
    positions = [1, 2, 3]
    
    historical_win_rates = {
        (1, 1): 0.75,
        (2, 2): 0.8,
        (3, 3): 0.85
    }
    
    min_players = {1: 5, 2: 6, 3: 7}
    max_players = {1: 10, 2: 11, 3: 12}
    league_capacity = 100
    
    # CRITICAL: Validate array lengths to prevent IndexError
    assert len(players) * len(teams) == len(historical_win_rates), "Historical win rates mismatch"
    
    # 2. VARIABLES
    x = {(p, t): mdl.binary_var(name=f"x_{p}_{t}") for p in players for t in teams}
    
    # 3. OBJECTIVE FUNCTION
    objective = mdl.sum(historical_win_rates.get((p, t), 0) * x[p, t] for p in players for t in teams)
    mdl.maximize(objective)
    
    # 4. CONSTRAINTS
    
    # Player Assignment Constraint: Each player can be assigned to at most one team
    for p in players:
        mdl.add_constraint(mdl.sum(x[p, t] for t in teams) <= 1, ctname=f"player_assignment_{p}")
    
    # Team Size Constraints: Each team must have at least the minimum number of players and no more than the maximum number of players
    for t in teams:
        mdl.add_constraint(mdl.sum(x[p, t] for p in players) >= min_players[t], ctname=f"min_players_{t}")
        mdl.add_constraint(mdl.sum(x[p, t] for p in players) <= max_players[t], ctname=f"max_players_{t}")
    
    # League Capacity Constraint: The total number of players assigned across all teams cannot exceed the league's capacity
    mdl.add_constraint(mdl.sum(x[p, t] for p in players for t in teams) <= league_capacity, ctname="league_capacity")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for p in players:
            for t in teams:
                if solution.get_value(x[p, t]) > 0:
                    print(f"Player {p} assigned to Team {t}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")
    
    return mdl

# Execute the optimization
optimize_player_allocation()