最大化一个盒子的体积
这个例子改编自 Boyd, Kim, Vandenberghe, and Hassibi, “A Tutorial on Geometric Programming“.
在这个例子中,我们最大化一个高度为 \(h\),宽度为 \(w\),深度为 \(d\) 的盒子的形状,限制墙面面积为 \(2(hw + hd)\),地面面积为 \(wd\),并限制高宽比 \(h/w\) 和宽深比 \(w/d\)。优化问题为
\[\begin{split}\begin{array}{ll}
\mbox{maximize} & hwd \\
\mbox{subject to} & 2(hw + hd) \leq A_{\text wall}, \\
& wd \leq A_{\text flr}, \\
& \alpha \leq h/w \leq \beta, \\
& \gamma \leq d/w \leq \delta.
\end{array}\end{split}\]
import cvxpy as cp
# Problem data.
A_wall = 100
A_flr = 10
alpha = 0.5
beta = 2
gamma = 0.5
delta = 2
h = cp.Variable(pos=True, name="h")
w = cp.Variable(pos=True, name="w")
d = cp.Variable(pos=True, name="d")
volume = h * w * d
wall_area = 2 * (h * w + h * d)
flr_area = w * d
hw_ratio = h/w
dw_ratio = d/w
constraints = [
wall_area <= A_wall,
flr_area <= A_flr,
hw_ratio >= alpha,
hw_ratio <= beta,
dw_ratio >= gamma,
dw_ratio <= delta
]
problem = cp.Problem(cp.Maximize(volume), constraints)
print(problem)
maximize h * w * d
subject to 2.0 * (h * w + h * d) <= 100.0
w * d <= 10.0
0.5 <= h / w
h / w <= 2.0
0.5 <= d / w
d / w <= 2.0
assert not problem.is_dcp()
assert problem.is_dgp()
problem.solve(gp=True)
problem.value
77.45966630736292
h.value
7.7459666715289766
w.value
3.872983364643079
d.value
2.581988871583608
# 墙面空间允许的增加1%,应该能使最大值增加约0.83%。
constraints[0].dual_value
0.8333333206334043
# 允许墙壁空间增加 1% 应该大约会增加 0.66% 的最大值。
constraints[1].dual_value
0.6666666801983365