LogiFlow Solutions manages the distribution of two types of packages: Standard and Express. Each package must be transported entirely by air freight or entirely by ground shipping. A total of 150 cubic meters of air freight capacity and 210 cubic meters of ground shipping capacity are available. A Standard package requires either 17 cubic meters of air freight or 30 cubic meters of ground shipping, while an Express package requires either 5 cubic meters of air freight or 13 cubic meters of ground shipping. Each Standard package generates $40 in revenue, and each Express package generates $15 in revenue. How to maximize LogiFlow Solutions' total revenue from package distribution?

Problem type: ILP (Toy: 4 variables, 2 constraints, 4 nonzeros)

Mathematical model:
Set: 
1. Package
The set of packages, \( P = \{1, 2\} \)  # 1: Standard, 2: Express
2. ShippingMethod
The set of shipping methods, \( S = \{1, 2\} \)  # 1: Air freight, 2: Ground shipping

Parameter:
1. AirFreightCapacity
150  # in cubic meters
2. GroundShippingCapacity
210  # in cubic meters
3. AirFreightRequirement
[17, 5]  # in cubic meters
4. GroundShippingRequirement
[30, 13]  # in cubic meters
5. RevenuePerPackage
[40, 15]  # in dollars

Decision variable:
1. PackagesShipped
Integer variable, \( PackagesShipped[p][s] \forall p \in P, s \in S \), the number of packages shipped for package type \( p \) using shipping method \( s \).

Objective:
1. Maximize the total revenue.
max: \sum_{p \in P, s \in S} (PackagesShipped[p][s] * RevenuePerPackage[p])

Constraint:
1. Air freight capacity constraint.
\sum_{p \in P} (PackagesShipped[p][1] * AirFreightRequirement[p]) \leq AirFreightCapacity
2. Ground shipping capacity constraint.
\sum_{p \in P} (PackagesShipped[p][2] * GroundShippingRequirement[p]) \leq GroundShippingCapacity
3. Non-negativity constraint.
PackagesShipped[p][s] \geq 0 \forall p \in P, s \in S

Type:
Integer, Linear, Linear
ILP

Gurobi implementation:
import gurobipy as gp
from gurobipy import GRB


def solve_package_shipping_optimization(
    AirFreightCapacity=150,
    GroundShippingCapacity=210,
    AirFreightRequirement=[17, 5],
    GroundShippingRequirement=[30, 13],
    RevenuePerPackage=[40, 15]
):
    """
    Models and solves the package shipping optimization problem.
    """
    # Create a new model
    model = gp.Model("Package_Shipping_Optimization")

    # Sets
    P = range(len(RevenuePerPackage))  # Package types
    S = range(2)  # Shipping methods (0: Air freight, 1: Ground shipping)

    # Decision Variables
    PackagesShipped = model.addVars(P, S, vtype=GRB.INTEGER, lb=0, name="PackagesShipped")

    # Objective Function: Maximize total revenue
    revenue = gp.quicksum(PackagesShipped[p, s] * RevenuePerPackage[p] for p in P for s in S)
    model.setObjective(revenue, GRB.MAXIMIZE)

    # Constraints
    # 1. Air freight capacity constraint
    model.addConstr(
        gp.quicksum(PackagesShipped[p, 0] * AirFreightRequirement[p] for p in P) <= AirFreightCapacity,
        "AirFreightCapacity"
    )

    # 2. Ground shipping capacity constraint
    model.addConstr(
        gp.quicksum(PackagesShipped[p, 1] * GroundShippingRequirement[p] for p in P) <= GroundShippingCapacity,
        "GroundShippingCapacity"
    )

    # Optimize the model
    model.optimize()

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


if __name__ == "__main__":
    result = solve_package_shipping_optimization()
    print(result)


Solution status: OPTIMAL
Optimal objective value: 730