# Complete PYOMO implementation - Retry Attempt 4

import pyomo.environ as pyo
from pyomo.opt import SolverFactory

def conference_optimization():
    """Pyomo model for optimizing conference workshop submissions"""
    
    # 1. MODEL CREATION
    model = pyo.ConcreteModel()
    
    # 2. DATA SETUP
    # Assuming 5 submissions and 3 workshops based on the provided data
    n_submissions = 5
    n_workshops = 3
    
    # Scores for each submission
    scores = [8.5, 6.0, 9.2, 7.3, 5.5]
    
    # Workshop capacities
    capacities = {1: 50, 2: 100, 3: 150}
    
    # Minimum submissions required for each workshop
    min_submissions = {1: 3, 2: 5, 3: 7}
    
    # CRITICAL: Validate array lengths before indexing
    assert len(scores) == n_submissions, "Array length mismatch for scores"
    
    # 3. SETS
    model.Submissions = pyo.RangeSet(1, n_submissions)
    model.Workshops = pyo.RangeSet(1, n_workshops)
    
    # 4. PARAMETERS
    model.Scores = pyo.Param(model.Submissions, initialize={i+1: scores[i] for i in range(n_submissions)})
    model.Capacity = pyo.Param(model.Workshops, initialize=capacities)
    model.MinSubmissions = pyo.Param(model.Workshops, initialize=min_submissions)
    
    # 5. VARIABLES
    model.x = pyo.Var(model.Workshops, model.Submissions, within=pyo.Binary)
    
    # 6. OBJECTIVE FUNCTION
    def obj_rule(model):
        return sum(model.Scores[j] * model.x[i, j] for i in model.Workshops for j in model.Submissions)
    model.objective = pyo.Objective(rule=obj_rule, sense=pyo.maximize)
    
    # 7. CONSTRAINTS
    
    # Workshop Capacity Constraints
    def capacity_rule(model, i):
        return sum(model.x[i, j] for j in model.Submissions) <= model.Capacity[i]
    model.capacity_constraint = pyo.Constraint(model.Workshops, rule=capacity_rule)
    
    # Minimum Submissions Constraints
    def min_submissions_rule(model, i):
        return sum(model.x[i, j] for j in model.Submissions) >= model.MinSubmissions[i]
    model.min_submissions_constraint = pyo.Constraint(model.Workshops, rule=min_submissions_rule)
    
    # 8. SOLVING WITH GUROBI
    solver = SolverFactory('gurobi')
    
    # Optional: Set solver options
    solver.options['TimeLimit'] = 300  # 5 minutes
    solver.options['MIPGap'] = 0.01    # 1% gap
    
    # Solve the model
    results = solver.solve(model, tee=True)
    
    # 9. RESULT PROCESSING
    # Check solver status
    if results.solver.termination_condition == pyo.TerminationCondition.optimal:
        print("Optimal solution found!")
        print(f"Optimal value: {pyo.value(model.objective)}")
        
        # Extract variable values
        print("\nAccepted Submissions:")
        for i in model.Workshops:
            for j in model.Submissions:
                if pyo.value(model.x[i, j]) > 0.5:  # Binary variable, check if it's 1
                    print(f"Workshop {i}, Submission {j} accepted")
        
    elif results.solver.termination_condition == pyo.TerminationCondition.infeasible:
        print("Problem is infeasible")
    elif results.solver.termination_condition == pyo.TerminationCondition.unbounded:
        print("Problem is unbounded")
    else:
        print(f"Solver terminated with condition: {results.solver.termination_condition}")
    
    return model

# Execute the optimization
conference_optimization()