To optimize the design of multiple insulation layers, you can formulate a Mixed Integer Quadratic Constraint Optimization (MIQCO) problem. This approach handles the trade-off between annual energy costs and capital installation costs.
Mathematical Formulation
- Objective: Minimize $C = \alpha U + \beta \sum_{n=1}^N (a_n y_n + b_n x_n)$
- Variables:
- $x_n$: Continuous variable for thickness of layer $n$.
- $y_n$: Binary variable indicating if layer $n$ is included.
- $U$: Overall heat transfer coefficient (epigraph variable).
- $R$: Total thermal resistance.
- Constraints:
- $R = R_0 + \sum_{n=1}^N \frac{x_n}{k_n}$
- $x_n \leq T y_n$ (links thickness to binary inclusion)
- $\sum_{n=1}^N x_n \leq T$ (total thickness limit)
- $R \cdot U \geq 1$ (nonlinear relationship, modeled as a quadratic constraint or rotated cone)
Implementation Pattern
Use pyo.ConcreteModel to define the set of layers, decision variables (including pyo.Binary for $y_n$), and the quadratic constraint m.R * m.U >= 1 for SCIP.
def insulate(df, alpha, beta, R0, T):
m = pyo.ConcreteModel()
m.N = pyo.Set(initialize=df.index)
a, b, k = df["a"], df["b"], df["k"]
# decision variables and physical bounds
Rmax = R0 + T / k.min()
m.R = pyo.Var(bounds=(R0, Rmax))
m.U = pyo.Var(bounds=(1 / Rmax, 1 / R0))
m.x = pyo.Var(m.N, bounds=(0, T))
m.y = pyo.Var(m.N, domain=pyo.Binary)
m.cost = pyo.Objective(
expr=alpha * m.U + beta * sum(a[n] * m.y[n] + b[n] * m.x[n] for n in m.N)
)
m.insulation = pyo.Constraint(expr=m.R == R0 + sum(m.x[n] / k[n] for n in m.N))
m.thickness = pyo.Constraint(expr=sum(m.x[n] for n in m.N) <= T)
m.layers = pyo.Constraint(m.N, rule=lambda m, n: m.x[n] <= T * m.y[n])
m.q = pyo.Constraint(expr=m.R * m.U >= 1)
return m