# Complete GUROBIPY implementation - Retry Attempt 1

import gurobipy as gp
from gurobipy import GRB

def gas_station_allocation():
    # 1. MODEL & DATA SETUP
    model = gp.Model("gas_station_allocation")
    
    # Data from the database
    stations = [1, 2, 3]
    companies = [1, 2, 3]
    
    # Profit data: profit[s, c] = profit when station s is assigned to company c
    profit = {
        (1, 1): 5000.0,
        (2, 2): 7500.0,
        (3, 3): 10000.0
    }
    
    # Maximum rank data: max_rank[c] = maximum rank for company c
    max_rank = {
        1: 100,
        2: 150,
        3: 200
    }
    
    # CRITICAL: Validate array lengths before loops
    assert len(stations) == 3, "Stations array length mismatch"
    assert len(companies) == 3, "Companies array length mismatch"
    
    # 2. VARIABLES
    # Decision variables: x[s, c] = 1 if station s is assigned to company c, 0 otherwise
    x = model.addVars(stations, companies, vtype=GRB.BINARY, name="x")
    
    # 3. OBJECTIVE FUNCTION
    # Maximize total profit
    model.setObjective(gp.quicksum(profit[s, c] * x[s, c] for s in stations for c in companies), GRB.MAXIMIZE)
    
    # 4. CONSTRAINTS
    # Single Assignment Constraint: Each station can be assigned to at most one company
    for s in stations:
        model.addConstr(gp.quicksum(x[s, c] for c in companies) <= 1, name=f"single_assignment_{s}")
    
    # Maximum Rank Constraint: The total number of stations assigned to a company cannot exceed its maximum rank
    for c in companies:
        model.addConstr(gp.quicksum(x[s, c] for s in stations) <= max_rank[c], name=f"max_rank_{c}")
    
    # 5. SOLVING & RESULTS
    model.optimize()
    
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for s in stations:
            for c in companies:
                if x[s, c].x > 0.5:
                    print(f"Station {s} is assigned to Company {c}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")
    
    return model

# Execute the function
gas_station_allocation()