约束转化
OPTIMake中支持对约束进行软化、无效化与硬化的操作, 以满足不同的需求:
- 约束软化为建模时指定约束为软约束, 以减少内存占用与计算时间
- 约束无效化及硬化则为在求解时动态调整约束的有效性与软硬属性
约束软化
OPTIMake中内置了对约束软化的支持, 通过该接口能够减少内存占用与计算时间.
约束软化可分为对等式约束的软化与对不等式约束的软化, OPTIMake在以下接口中 提供了约束软化支持:
variable(变量的上下限, 不等式约束)inequality(不等式约束)equality(等式约束)start_equality(等式约束)end_equality(等式约束)
软化的惩罚类型支持:
'quadratic''l1'
上面的问题定义章节中介绍了如何使用这些接口软化约束, 我们以以下的通用问题形式介绍OPTIMake中约束软化的问题设定. 需要注意的是, 下面的代表slack变量而非参数.
等式约束软化
当软化的惩罚类型为'quadratic'时, 软化问题的定义如下 ( 为惩罚权重, 为约束软化的slack变量):
当软化的惩罚类型为'l1'时, 软化问题的定义如下 ( 为惩罚权重, 为约束软化的slack变量):
不等式约束软化
当软化的惩罚类型为'quadratic'时, 软化问题的定义如下 ( 为惩罚权重, 为约束软化的slack变量):
当软化的惩罚类型为'l1'时, 软化问题的定义如下 ( 为惩罚权重, 为约束软化的slack变量):
约束无效化
在建模时定义了某些约束, 但在求解时希望将其无效化, 使其不影响求解结果时, OPTIMake中支持以下类型的约束无效化:
- 变量的硬上下界: 通过将下界设置为-inf或将上界设置为inf
- 变量的软上下界: 通过将惩罚权重设置为0.0
- 硬不等式约束: 通过参数将其initial guess对应的初始值设置为inf (恒大于0)
- 软不等式约束: 通过将惩罚权重设置为0.0, 或者通过参数将其initial guess对应的初始值设置为inf (恒大于0)
例如, 对于以下不等式约束:
# -bd <= x + y <= bd
xy_bd = prob.parameter('xy_bd', stage_dependent=False)
ineq = general_inequality(
expr = [x + y, x + y],
sign = ['>=', '<='],
bound = [-xy_bd, xy_bd])
prob.inequality(ineq)
当希望无效化该不等式约束时, 在求解前设置参数时, 可通过以下代码实现:
// HUGE_VAL is infinity in C
// In C++, you can use std::numeric_limits<double>::infinity()
prob.param[PARAM_XY_BD] = HUGE_VAL;
注意
OPTIMake暂时不支持对等式约束及二阶锥约束的无效化.
软约束硬化
当建模时指定了约束为软约束后, 但在求解时希望将其硬化, 使其变为硬约束时, OPTIMake中支持以下类型的软约束硬化:
- 变量的软上下界: 通过将惩罚权重设置为inf, 此时该软边界会与硬边界综合形成新的硬边界 (即取两者中更严格的一个)
- 软不等式约束: 通过将惩罚权重设置为inf
- 软等式约束: 通过将惩罚权重设置为inf