# Complete DOCPLEX implementation - Retry Attempt 1

from docplex.mp.model import Model

def gas_station_allocation():
    # 1. MODEL & DATA SETUP
    mdl = Model(name="gas_station_allocation")
    
    # Data from the database
    stations = [1, 2, 3]
    companies = [1, 2, 3]
    
    # Profit data: (station_id, company_id) -> profit
    profit = {
        (1, 1): 5000.0,
        (2, 2): 7500.0,
        (3, 3): 10000.0
    }
    
    # Maximum rank data: company_id -> max_rank
    max_rank = {
        1: 100,
        2: 150,
        3: 200
    }
    
    # 2. VARIABLES
    # Decision variables: x[s, c] = 1 if station s is assigned to company c, 0 otherwise
    x = mdl.binary_var_dict([(s, c) for s in stations for c in companies], name="x")
    
    # 3. OBJECTIVE FUNCTION
    # Maximize total profit
    objective = mdl.sum(profit[(s, c)] * x[(s, c)] for s in stations for c in companies if (s, c) in profit)
    mdl.maximize(objective)
    
    # 4. CONSTRAINTS
    
    # Single Assignment Constraint: Each station can be assigned to at most one company
    for s in stations:
        mdl.add_constraint(mdl.sum(x[(s, c)] for c in companies if (s, c) in profit) <= 1, ctname=f"single_assignment_{s}")
    
    # Maximum Rank Constraint: Each company cannot exceed its maximum rank
    for c in companies:
        mdl.add_constraint(mdl.sum(x[(s, c)] for s in stations if (s, c) in profit) <= max_rank[c], ctname=f"max_rank_{c}")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for s in stations:
            for c in companies:
                if (s, c) in x and solution.get_value(x[(s, c)]) > 0:
                    print(f"Station {s} is assigned to Company {c}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")
    
    return mdl

# Execute the function
gas_station_allocation()