Cargo Airplane: Implementation in Python#

Modelling with Pyomo + HiGHS#

In order to model and solve the cargo airplane problem, we follow the following steps (Pyomo separates modeling from solving):

  1. Define the model container (ConcreteModel) This is an empty “box” that will hold all other components (sets, parameters, variables, objective, constraints).

  2. Define sets and parameters (Set and Param) Sets represent index collections and parameters represent fixed data such as profits, weights, volumes, and capacities.

  3. Define decision variables (Var) Decision variables represent the unknown quantities to be determined by the solver.

  4. Define the objective (Objective) The objective specifies what the model is optimizing.

  5. Add constraints (Constraint) Constraints represent the physical and operational limits of the problem.

  6. Call the solver (SolverFactory("highs").solve(m, tee=True or False)) This step sends the model to the HiGHS solver and triggers the optimization process.tee=True displays solver output, while tee=False suppresses it.

If you need help on a Pyomo component, use Python’s help:

import pyomo.environ as pyo
help(pyo.Var)
from pyomo.environ import (
    ConcreteModel, Set, Param, Var, Objective, Constraint,
    NonNegativeReals, SolverFactory, value, minimize, maximize
)

m = ConcreteModel()
cargo_types = ['Type1','Type2','Type3', 'Type4']
compartments = ['Front','Center','Rear']

# Cargo limits
cargo_weight = {  # weight per unit (e.g., tons)
    'Type1': 18,
    'Type2': 14,
    'Type3': 20,
    'Type4': 12,
}

cargo_volume = {  # volume per unit (e.g., m^3)
    'Type1': 180,
    'Type2': 250,
    'Type3': 300,
    'Type4': 80,
}

cargo_profit = {  # profit per unit (e.g., €)
    'Type1': 590,
    'Type2': 580,
    'Type3': 580,
    'Type4': 600,
}

# Compartment limits

compartment_weight_cap = {  # max weight per compartment
    'Front':  8,   
    'Center': 12,   
    'Rear':   14,   
}

compartment_volume_cap = {  # max volume per compartment
    'Front':  12000,   # example
    'Center': 10000,   # example
    'Rear':   6000,   # example
}

Sets and Parameters#

m.I = Set(initialize=cargo_types)
m.J = Set(initialize=compartments)

m.w = Param(m.I, initialize=cargo_weight)        # total available weight of cargo i
m.v = Param(m.I, initialize=cargo_volume)        # volume per unit weight of cargo i
m.p = Param(m.I, initialize=cargo_profit)        # profit per unit weight of cargo i
m.W = Param(m.J, initialize=compartment_weight_cap)  # weight capacity per compartment
m.V = Param(m.J, initialize=compartment_volume_cap)  # volume capacity per compartment

Decision Variables#

m.x = Var(m.I, m.J, domain=NonNegativeReals)

Objective#

m.obj = Objective(
    expr=sum(m.p[i] * m.x[i, j] for i in m.I for j in m.J),
    sense=maximize
)

Constraints#

# Availability constraint
m.availability = Constraint(
    m.I,
    expr={ i: sum(m.x[i, j] for j in m.J) <= m.w[i]  for i in m.I }
)

# Weight capacity
m.weight_cap = Constraint(
    m.J,
    expr={ j: sum(m.x[i, j] for i in m.I) <= m.W[j]  for j in m.J }
)

# Volume capacity
m.volume_cap = Constraint(
    m.J,
    expr={ j: sum(m.v[i] * m.x[i, j] for i in m.I) <= m.V[j]  for j in m.J }
)

Solve and Print Results#

res = SolverFactory("highs").solve(m, tee=False)

print("\nTotal Profit =", value(m.obj))
for i in m.I:
    for j in m.J:
        val = value(m.x[i,j])
        if val > 1e-8:
            print(f"x[{i},{j}] = {val:.3f}")
Total Profit = 20140.0
x[Type1,Center] = 8.000
x[Type1,Rear] = 10.000
x[Type3,Rear] = 4.000
x[Type4,Front] = 8.000
x[Type4,Center] = 4.000

Note that for this problem several solutions with the same objective function value exists