You are in charge of a taxi company, managing its fleet during the evening peak hours. The company needs to dispatch its idle taxis from 3 areas to 3 passenger demand hotspots. To improve profitability, in addition to setting a dynamic surcharge for each hotspot to incentivize drivers, the company has also established a fixed base fare of ¥15 for every successful dispatch. The supply of drivers willing to go to a certain hotspot is proportional to the square of the surcharge, with a coefficient of 0.5. The company's objective is to set the surcharges and plan the vehicle dispatch to maximize total profit. Total profit is calculated as (total base fare revenue + total surcharge revenue - total deadheading costs). Through operational optimization, the company has reduced its deadheading costs by 20%. The number of available taxis in each area, the passenger demand at each hotspot, and the adjusted deadheading costs from each area to each hotspot are shown in the table below.

Table 1: Adjusted Taxi Dispatch Data 

| Attribute | H1 | H2 | H3 | Available Taxis |
|:---:|:---:|:---:|:---:|:---:|
| Demand | 30  | 50  | 40  | - |
| Deadheading Cost from A1 | 16 | 28 | 24 | 25  |
| Deadheading Cost from A2 | 20 | 12 | 32 | 40  |
| Deadheading Cost from A3 | 24 | 20 | 16 | 35  |

How can the taxi company set its dynamic surcharges and dispatch plan to maximize its total profit while satisfying all supply and demand constraints?

Problem type: NLP (Small: 15 variables, 9 constraints, 24 nonzeros)

Mathematical model:
Set:
1.  Area
    [cite_start]The set of areas with available taxis, \( A = \{1, 2, 3\} \) # 1: A1, 2: A2, 3: A3 [cite: 12]
2.  Hotspot
    [cite_start]The set of passenger demand hotspots, \( H = \{1, 2, 3\} \) # 1: H1, 2: H2, 3: H3 [cite: 12]

Parameter:
1.  AvailableTaxis
   [25, 40, 35] # number of available taxis in each area 
2.  Demand
    [30, 50, 40] # number of passengers demanding taxis at each hotspot 
3.  DeadheadingCost
    [16, 28, 24], [20, 12, 32], [24, 20, 16] # cost to dispatch a taxi from an area to a hotspot
    # The deadheading costs data in the table is already adjusted to reflect a 20% reduction.
4.  SurchargeCoefficient
    0.5 # coefficient relating driver supply to the square of the surcharge 
5.  BaseFare 
    15.0 # fixed base fare for each successful dispatch

Decision variable:
1.  DispatchAmount
Integer variable, \( DispatchAmount[a][h] \forall a \in A, h \in H \), the number of taxis dispatched from area \( a \) to hotspot \( h \).
2.  Surcharge
Continuous variable, \( Surcharge[h] \forall h \in H \), the dynamic surcharge set for hotspot \( h \). 

Objective:
1.  Maximize the total profit. 
    max: \( \sum_{h \in H} ((BaseFare + Surcharge[h]) * \sum_{a \in A} DispatchAmount[a][h]) - \sum_{a \in A} \sum_{h \in H} (DeadheadingCost[a][h] * DispatchAmount[a][h]) \)

Constraint:
1.  Area supply constraint.
 \sum_{h \in H} DispatchAmount[a][h] \leq AvailableTaxis[a] \forall a \in A \
2.  Hotspot demand constraint.
\sum_{a \in A} DispatchAmount[a][h] \leq Demand[h] \forall h \in H \
3.  Surcharge-supply relationship constraint.
 \sum_{a \in A} DispatchAmount[a][h] = SurchargeCoefficient * Surcharge[h]^2 \forall h \in H \
4.  Non-negativity constraint.
   DispatchAmount[a][h] \geq 0 \forall a \in A, h \in H \
   Surcharge[h] \geq 0 \forall h \in H \

Type:
Mixed, Non-linear, Non-linear
NLP

Gurobi implementation:
import gurobipy as gp
from gurobipy import GRB
import math

def solve_profitable_taxi_dispatch(
    areas=["A1", "A2", "A3"],
    hotspots=["H1", "H2", "H3"],
    demand={"H1": 30, "H2": 50, "H3": 40},
    available_taxis={"A1": 25, "A2": 40, "A3": 35},
    base_fare=15.0,
    deadheading_costs_data={
        ("A1", "H1"): 16, ("A1", "H2"): 28, ("A1", "H3"): 24,
        ("A2", "H1"): 20, ("A2", "H2"): 12, ("A2", "H3"): 32,
        ("A3", "H1"): 24, ("A3", "H2"): 20, ("A3", "H3"): 16,
    }
):
    """
    Solves the adjusted (profitable) taxi dispatch optimization problem using Gurobi.
    This model includes a base fare and reduced deadheading costs.
    """
    # Create a new model
    model = gp.Model("ProfitableTaxiDispatch")

    deadheading_costs = gp.tupledict(deadheading_costs_data)

    # --- Decision Variables ---
    # dispatch_plan[i, j]: Number of taxis dispatched from area i to hotspot j
    dispatch_plan = model.addVars(areas, hotspots, vtype=GRB.INTEGER, name="DispatchPlan", lb=0)

    # supply[j]: Total number of taxis arriving at hotspot j
    supply = model.addVars(hotspots, name="Supply", lb=0)
    
    # revenue_calc_surcharge[j]: Auxiliary variable for the non-linear surcharge revenue term, representing supply[j]^1.5
    revenue_calc_surcharge = model.addVars(hotspots, name="SurchargeRevenueCalc", lb=0)

    # --- Objective Function: Maximize Total Profit ---
    total_base_fare_revenue = base_fare * gp.quicksum(supply[j] for j in hotspots)
    
    total_surcharge_revenue = math.sqrt(2) * gp.quicksum(revenue_calc_surcharge[j] for j in hotspots)

    total_revenue = total_base_fare_revenue + total_surcharge_revenue

    total_deadheading_cost = dispatch_plan.prod(deadheading_costs)

    model.setObjective(total_revenue - total_deadheading_cost, GRB.MAXIMIZE)

    # --- Constraints ---
    # 1. Supply definition constraint
    for j in hotspots:
        model.addConstr(supply[j] == gp.quicksum(dispatch_plan[i, j] for i in areas),
                        name=f"SupplyDef_{j}")

    # 2. Surcharge revenue calculation (non-linear power constraint)
    for j in hotspots:
        model.addGenConstrPow(supply[j], revenue_calc_surcharge[j], 1.5, name=f"RevenuePow_{j}")

    # 3. Hotspot demand constraint
    for j in hotspots:
        model.addConstr(supply[j] <= demand[j], name=f"Demand_{j}")

    # 4. Area availability constraint
    for i in areas:
        model.addConstr(dispatch_plan.sum(i, '*') <= available_taxis[i], name=f"Availability_{i}")
    
    # Optimize the model
    model.optimize()

    # --- Return Results ---
    if model.status == GRB.OPTIMAL:
        return {"status": "optimal", "obj": model.objVal}
    else:
        return {"status": f"{model.status}"}


# Run the solver function
if __name__ == '__main__':
    result = solve_profitable_taxi_dispatch()
    print(result)

Solution status: OPTIMAL
Optimal objective value: 887.3785809835297