# Complete DOCPLEX implementation

from docplex.mp.model import Model

def election_optimization():
    """Optimize resource allocation for maximizing votes in an election"""

    # 1. MODEL & DATA SETUP
    mdl = Model(name="election_optimization")

    # Data: Coefficients and constraints
    votes_coefficients = [0.6, 1.5, 0.9]
    min_allocations = [500, 1000, 600]
    max_allocations = [1000, 2000, 1200]
    total_budget = 3000

    # CRITICAL: Validate array lengths to prevent IndexError
    assert len(votes_coefficients) == len(min_allocations) == len(max_allocations), "Array length mismatch"
    safe_range = range(len(votes_coefficients))  # Safe indexing

    # 2. VARIABLES
    # Variable dictionaries (most common)
    resource_allocation = {i: mdl.continuous_var(name=f"x_{i}", lb=min_allocations[i], ub=max_allocations[i]) for i in safe_range}

    # 3. OBJECTIVE FUNCTION
    # Use mdl.sum() for summations (DOCplex specific)
    objective = mdl.sum(votes_coefficients[i] * resource_allocation[i] for i in safe_range)
    mdl.maximize(objective)

    # 4. CONSTRAINTS - CORRECT SYNTAX PATTERNS

    # Total budget constraint
    total_usage = mdl.sum(resource_allocation[i] for i in safe_range)
    mdl.add_constraint(total_usage <= total_budget, ctname="total_budget")

    # 5. SOLVING & RESULTS
    solution = mdl.solve()

    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for i in safe_range:
            value = solution.get_value(resource_allocation[i])
            print(f"Resource allocation for county {i+1}: {value:.3f}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")

    return mdl

# Run the optimization
election_optimization()