# Complete GUROBIPY implementation - Retry Attempt 4

import gurobipy as gp
from gurobipy import GRB

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

    # Data from the problem statement
    players = [1, 2, 3]
    match_nums = [101, 102, 103]
    
    # Travel distances (player_id, match_num) -> distance
    travel_distances = {
        (1, 101): 12.5,
        (2, 102): 18.0,
        (3, 103): 8.0
    }
    
    # Player availability (player_id -> available_time)
    player_availability = {
        1: 150,
        2: 180,
        3: 120
    }
    
    # Match durations (match_num -> minutes)
    match_durations = {
        101: 90,
        102: 120,
        103: 60
    }
    
    # Validate array lengths
    assert len(travel_distances) == len(players), "Array length mismatch for travel distances"
    assert len(player_availability) == len(players), "Array length mismatch for player availability"
    assert len(match_durations) == len(match_nums), "Array length mismatch for match durations"

    # 2. VARIABLES
    # Decision variables: x[i,j] = 1 if player i is assigned to match j, 0 otherwise
    x = model.addVars(players, match_nums, vtype=GRB.BINARY, name="x")

    # 3. OBJECTIVE FUNCTION
    # Minimize total travel distance
    model.setObjective(
        gp.quicksum(travel_distances[i, j] * x[i, j] for i in players for j in match_nums),
        GRB.MINIMIZE
    )

    # 4. CONSTRAINTS
    # Player Time Availability Constraint
    for i in players:
        model.addConstr(
            gp.quicksum(match_durations[j] * x[i, j] for j in match_nums) <= player_availability[i],
            name=f"time_availability_{i}"
        )

    # Match Assignment Constraint
    for j in match_nums:
        model.addConstr(
            gp.quicksum(x[i, j] for i in players) == 1,
            name=f"match_assignment_{j}"
        )

    # 5. SOLVING & RESULTS
    model.optimize()

    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for i in players:
            for j in match_nums:
                if x[i, j].x > 0.5:  # Binary variable, so check if it's 1
                    print(f"Player {i} is assigned to match {j}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")

# Run the optimization
optimize_tennis_schedule()