# Complete GUROBIPY implementation - Retry Attempt 1

import gurobipy as gp
from gurobipy import GRB

def optimize_budget_allocation():
    # 1. MODEL & DATA SETUP
    model = gp.Model("department_budget_allocation")
    
    # Department data
    departments = [1, 2, 3]
    minimum_budgets = {1: 100000, 2: 80000, 3: 50000}
    maximum_budgets = {1: 300000, 2: 250000, 3: 200000}
    rankings = {1: 10, 2: 8, 3: 6}  # Example rankings
    employees = {1: 50, 2: 40, 3: 30}  # Example number of employees
    
    # Efficiency weights
    ranking_weight = 0.7
    employees_weight = 0.3
    
    # Total budget
    total_budget = 1000000
    
    # Validate array lengths
    assert len(departments) == len(minimum_budgets) == len(maximum_budgets) == len(rankings) == len(employees), "Array length mismatch"
    
    # 2. VARIABLES
    x = {i: model.addVar(vtype=GRB.CONTINUOUS, name=f"x_{i}", lb=minimum_budgets[i], ub=maximum_budgets[i]) for i in departments}
    
    # 3. OBJECTIVE FUNCTION
    # Calculate coefficients c_i = 0.7 * ranking_i + 0.3 * employees_i
    c = {i: ranking_weight * rankings[i] + employees_weight * employees[i] for i in departments}
    
    # Maximize the overall efficiency score
    model.setObjective(gp.quicksum(c[i] * x[i] for i in departments), GRB.MAXIMIZE)
    
    # 4. CONSTRAINTS
    # Total Budget Constraint
    model.addConstr(gp.quicksum(x[i] for i in departments) <= total_budget, name="total_budget_constraint")
    
    # 5. SOLVING & RESULTS
    model.optimize()
    
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for i in departments:
            print(f"Allocated budget for department {i}: {x[i].x:.2f}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")
    
    return model

# Execute the optimization
optimize_budget_allocation()