# Complete DOCPLEX implementation

from docplex.mp.model import Model

def classroom_assignment_optimization():
    """Optimize student assignments to classrooms to minimize the maximum number of students in any classroom."""
    
    # 1. MODEL & DATA SETUP
    mdl = Model(name="classroom_assignment")
    
    # Data: Number of students and classrooms
    students = [1, 2, 3, 4, 5]
    classrooms = [101, 102, 103]
    
    # Classroom capacities
    classroom_capacities = {101: 25, 102: 30, 103: 35}
    
    # Validate data lengths
    assert len(classrooms) == len(classroom_capacities), "Mismatch in classroom data lengths"
    
    # Safe range for classrooms
    safe_classroom_range = range(len(classrooms))
    
    # 2. VARIABLES
    # Decision variables: x[i][j] = 1 if student i is assigned to classroom j, 0 otherwise
    x = {(i, j): mdl.binary_var(name=f"x_{i}_{j}") for i in students for j in classrooms}
    
    # Auxiliary variable for the maximum number of students in any classroom
    M = mdl.continuous_var(name="M", lb=0)
    
    # 3. OBJECTIVE FUNCTION
    # Minimize the maximum number of students in any classroom
    mdl.minimize(M)
    
    # 4. CONSTRAINTS
    
    # Classroom capacity constraints
    for j in classrooms:
        mdl.add_constraint(mdl.sum(x[i, j] for i in students) <= classroom_capacities[j], ctname=f"capacity_{j}")
    
    # Student assignment constraints
    for i in students:
        mdl.add_constraint(mdl.sum(x[i, j] for j in classrooms) == 1, ctname=f"assignment_{i}")
    
    # Maximum students constraint
    for j in classrooms:
        mdl.add_constraint(mdl.sum(x[i, j] for i in students) <= M, ctname=f"max_students_{j}")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for i in students:
            for j in classrooms:
                if solution.get_value(x[i, j]) > 0.5:  # Check if student i is assigned to classroom j
                    print(f"Student {i} is assigned to classroom {j}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")
    
    return mdl

# Run the optimization
classroom_assignment_optimization()