# Complete DOCPLEX implementation - Retry Attempt 4

from docplex.mp.model import Model

def optimize_tennis_schedule():
    # 1. MODEL & DATA SETUP
    mdl = Model(name="tennis_schedule_optimization")

    # Data from the problem statement
    players = [1, 2, 3]
    match_nums = [101, 102, 103]
    
    travel_distances = {
        (1, 101): 12.5,
        (2, 102): 18.0,
        (3, 103): 8.0
    }
    
    available_time = {
        1: 150,
        2: 180,
        3: 120
    }
    
    match_minutes = {
        101: 90,
        102: 120,
        103: 60
    }
    
    # CRITICAL: Validate array lengths to prevent IndexError
    assert len(travel_distances) == len(players), "Array length mismatch"
    assert len(available_time) == len(players), "Array length mismatch"
    assert len(match_minutes) == len(match_nums), "Array length mismatch"
    
    # 2. VARIABLES
    x = {(i, j): mdl.binary_var(name=f"x_{i}_{j}") for i in players for j in match_nums}

    # 3. OBJECTIVE FUNCTION
    objective = mdl.sum(travel_distances[i, j] * x[i, j] for i in players for j in match_nums if (i, j) in travel_distances)
    mdl.minimize(objective)

    # 4. CONSTRAINTS
    # Player Time Availability Constraint
    for i in players:
        mdl.add_constraint(mdl.sum(match_minutes[j] * x[i, j] for j in match_nums if (i, j) in x) <= available_time[i], ctname=f"time_avail_{i}")

    # Match Assignment Constraint
    for j in match_nums:
        mdl.add_constraint(mdl.sum(x[i, j] for i in players if (i, j) in x) == 1, ctname=f"match_assign_{j}")

    # 5. SOLVING & RESULTS
    solution = mdl.solve()

    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for i in players:
            for j in match_nums:
                if (i, j) in x:
                    value = solution.get_value(x[i, j])
                    if value > 1e-6:
                        print(f"x[{i},{j}] = {value:.3f}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")

    return mdl

# Run the optimization
optimize_tennis_schedule()