#!/usr/bin/env python3
"""
Gurobipy Implementation for Voter Resource Allocation Optimization
"""

import gurobipy as gp
from gurobipy import GRB

def optimize_voter_resource_allocation():
    """Optimize resource allocation to maximize expected votes."""
    
    # 1. MODEL & DATA SETUP
    model = gp.Model("voter_resource_allocation")
    
    # Data from the problem
    majors = ['Computer Science', 'Biology', 'History']
    expected_votes = [150, 100, 80]
    number_of_students = [200, 150, 100]
    
    # Business configuration
    total_budget = 50000
    min_allocation = 500
    max_allocation = 5000
    units_per_student = 10
    
    # CRITICAL: Validate array lengths before loops
    assert len(majors) == len(expected_votes) == len(number_of_students), "Array length mismatch"
    
    # 2. VARIABLES
    # Resource allocation variables for each major
    x = {i: model.addVar(vtype=GRB.INTEGER, name=f"x_{majors[i]}", lb=min_allocation, ub=max_allocation) 
         for i in range(len(majors))}
    
    # 3. OBJECTIVE FUNCTION
    # Maximize the total expected votes
    model.setObjective(gp.quicksum(expected_votes[i] * x[i] for i in range(len(majors))), GRB.MAXIMIZE)
    
    # 4. CONSTRAINTS
    
    # Total Budget Constraint
    model.addConstr(gp.quicksum(x[i] for i in range(len(majors))) <= total_budget, name="total_budget")
    
    # Proportional Resource Allocation Constraint
    for i in range(len(majors)):
        model.addConstr(x[i] <= units_per_student * number_of_students[i], name=f"proportional_{majors[i]}")
    
    # 5. SOLVING & RESULTS
    model.optimize()
    
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for i in range(len(majors)):
            print(f"Resource allocation for {majors[i]}: {x[i].x}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")
    
    return model

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