#!/usr/bin/env python3
"""
Gurobipy 12.0.2 Implementation for Voter Optimization Problem
"""

import gurobipy as gp
from gurobipy import GRB

def voter_optimization():
    """Optimize promotional budget allocation to maximize votes."""
    
    # 1. MODEL & DATA SETUP
    model = gp.Model("voter_optimization")
    
    # Contestants and states
    contestants = [1, 2, 3]
    states = ['CA', 'TX', 'NY']
    
    # Conversion rate
    conversion_rate = 0.6
    
    # Total budget and state-level budget limit
    total_budget = 150000
    state_budget_limit = 25000
    
    # 2. VARIABLES
    # Decision variable: promotional budget allocated to each contestant in each state
    x = model.addVars(contestants, states, vtype=GRB.CONTINUOUS, name="x", lb=0)
    
    # 3. OBJECTIVE FUNCTION
    # Maximize total votes received
    model.setObjective(gp.quicksum(conversion_rate * x[i, j] for i in contestants for j in states), GRB.MAXIMIZE)
    
    # 4. CONSTRAINTS
    
    # Total Budget Constraint
    model.addConstr(gp.quicksum(x[i, j] for i in contestants for j in states) <= total_budget, name="total_budget")
    
    # State-Level Budget Constraint
    for i in contestants:
        for j in states:
            model.addConstr(x[i, j] <= state_budget_limit, name=f"state_budget_{i}_{j}")
    
    # 5. SOLVING & RESULTS
    model.optimize()
    
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for i in contestants:
            for j in states:
                if x[i, j].x > 1e-6:
                    print(f"x[{i}, {j}] = {x[i, j].x:.3f}")
    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__":
    voter_optimization()