# Complete GUROBIPY implementation

import gurobipy as gp
from gurobipy import GRB

def department_management_optimization():
    """Optimize budget allocation across departments to maximize ranking."""
    
    # 1. MODEL & DATA SETUP
    model = gp.Model("department_management")
    
    # Data from the problem context
    rankings = [1.8, 2.5, 3.2]
    budgets_in_billions = [0.6, 1.2, 1.8]
    total_budget = 3.0
    n_departments = len(rankings)
    
    # CRITICAL: Validate array lengths before loops
    assert len(rankings) == len(budgets_in_billions) == n_departments, "Array length mismatch"
    
    # 2. VARIABLES
    # Variable dictionaries for budget fractions
    fraction_allocated = {i: model.addVar(vtype=GRB.CONTINUOUS, name=f"fraction_allocated_{i}", lb=0, ub=1) 
                          for i in range(n_departments)}
    
    # 3. OBJECTIVE FUNCTION
    # Maximize the total weighted ranking of all departments
    model.setObjective(gp.quicksum(rankings[i] * fraction_allocated[i] for i in range(n_departments)), GRB.MAXIMIZE)
    
    # 4. CONSTRAINTS - CORRECT SYNTAX PATTERNS
    
    # Total budget allocation constraint
    model.addConstr(gp.quicksum(fraction_allocated[i] * budgets_in_billions[i] for i in range(n_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 range(n_departments):
            print(f"fraction_allocated[{i}] = {fraction_allocated[i].x:.3f}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")
    
    return model

# Run the optimization
department_management_optimization()