#!/usr/bin/env python3
"""
DOCplex 2.29.245 Implementation for Local Government in Alabama Event Allocation
"""

from docplex.mp.model import Model

def optimize_event_allocation():
    """Optimize participant allocation to events to maximize satisfaction."""
    
    # 1. MODEL & DATA SETUP
    mdl = Model(name="local_govt_in_alabama")
    
    # Data from the problem
    events = [1, 2, 3]
    participants = [101, 102, 103]
    
    # Satisfaction scores
    satisfaction_scores = {
        (1, 101): 0.85,
        (1, 102): 0.75,
        (1, 103): 0.65,
        (2, 101): 0.7,
        (2, 102): 0.9,
        (2, 103): 0.8,
        (3, 101): 0.6,
        (3, 102): 0.85,
        (3, 103): 0.95
    }
    
    # Event capacities
    event_capacities = {
        1: 50,
        2: 100,
        3: 75
    }
    
    # 2. VARIABLES
    # Binary decision variables: x[e, p] = 1 if participant p is assigned to event e, 0 otherwise
    x = {(e, p): mdl.binary_var(name=f"x_{e}_{p}") for e in events for p in participants}
    
    # 3. OBJECTIVE FUNCTION
    # Maximize total satisfaction score
    objective = mdl.sum(satisfaction_scores[e, p] * x[e, p] for e in events for p in participants)
    mdl.maximize(objective)
    
    # 4. CONSTRAINTS
    
    # Event Capacity Constraint: Sum of participants assigned to each event <= event capacity
    for e in events:
        mdl.add_constraint(mdl.sum(x[e, p] for p in participants) <= event_capacities[e], ctname=f"event_capacity_{e}")
    
    # Participant Assignment Constraint: Each participant can be assigned to at most one event
    for p in participants:
        mdl.add_constraint(mdl.sum(x[e, p] for e in events) <= 1, ctname=f"participant_assignment_{p}")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for e in events:
            for p in participants:
                if solution.get_value(x[e, p]) > 0.5:
                    print(f"Participant {p} assigned to Event {e}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")
    
    return mdl

# Execute the optimization
if __name__ == "__main__":
    optimize_event_allocation()