跳到主要内容
版本:v0.6.0

约束转化

OPTIMake中支持对约束进行软化、无效化与硬化的操作, 以满足不同的需求:

  • 约束软化为建模时指定约束为软约束, 以减少内存占用与计算时间
  • 约束无效化及硬化则为在求解时动态调整约束的有效性与软硬属性

约束软化

OPTIMake中内置了对约束软化的支持, 通过该接口能够减少内存占用与计算时间.

约束软化可分为对等式约束的软化与对不等式约束的软化, OPTIMake在以下接口中提供了约束软化支持:

  • variable (变量的上下限, 不等式约束)
  • inequality (不等式约束)
  • equality (等式约束)
  • start_equality (等式约束)
  • end_equality (等式约束)

软化的惩罚类型支持:

  • 'quadratic'
  • 'l1'

上面的问题定义章节中介绍了如何使用这些接口软化约束, 我们以以下的通用问题形式介绍OPTIMake中约束软化的问题设定. 需要注意的是, 下面的pp代表slack变量而非参数.

minvl(v)s.t.f(v)=0,g(v)0 \begin{split} \quad \quad &\quad \min_{v} l(v) \\ &\begin{split} \text{s.t.} \quad f(v) &= 0,\\ \quad g(v) &\geq 0 \end{split} \end{split}

等式约束软化

当软化的惩罚类型为'quadratic'时, 软化问题的定义如下 (wiw_i 为惩罚权重, pp为约束软化的slack变量):

minv,pl(v)+i12wipi2s.t.f(v)=p,g(v)0 \begin{split} \quad \quad &\quad \min_{v,p} l(v) + \sum_{i}\frac{1}{2}w_i p_i^2 \\ &\begin{split} \text{s.t.} \quad f(v) &= p,\\ \quad g(v) &\geq 0 \end{split} \end{split}

当软化的惩罚类型为'l1'时, 软化问题的定义如下 (wiw_i 为惩罚权重, p,np,n为约束软化的slack变量):

minv,p,nl(v)+iwi(pi+ni)s.t.f(v)=pn,g(v)0,p0,n0 \begin{split} \quad \quad &\quad \min_{v,p,n} l(v) + \sum_{i}w_i (p_i + n_i) \\ &\begin{split} \text{s.t.} \quad f(v) &= p - n,\\ \quad g(v) &\geq 0, \\ \quad p &\geq 0,\\ \quad n &\geq 0 \end{split} \end{split}

不等式约束软化

当软化的惩罚类型为'quadratic'时, 软化问题的定义如下 (wiw_i 为惩罚权重, pp为约束软化的slack变量):

minv,pl(v)+i12wipi2s.t.f(v)=0,g(v)+p0 \begin{split} \quad \quad &\quad \min_{v,p} l(v) + \sum_{i}\frac{1}{2}w_i p_i^2 \\ &\begin{split} \text{s.t.} \quad f(v) &= 0,\\ \quad g(v) + p &\geq 0 \end{split} \end{split}

当软化的惩罚类型为'l1'时, 软化问题的定义如下 (wiw_i 为惩罚权重, pp为约束软化的slack变量):

minv,p,nl(v)+iwipis.t.f(v)=0,g(v)+p0,p0 \begin{split} \quad \quad &\quad \min_{v,p,n} l(v) + \sum_{i}w_i p_i \\ &\begin{split} \text{s.t.} \quad f(v) &= 0,\\ \quad g(v) + p &\geq 0, \\ \quad p &\geq 0 \end{split} \end{split}

约束无效化

在建模时定义了某些约束, 但在求解时希望将其无效化, 使其不影响求解结果时, OPTIMake中支持以下类型的约束无效化:

  • 变量的硬上下界: 通过将下界设置为-inf或将上界设置为inf
  • 变量的软上下界: 通过将惩罚权重设置为0.0
  • 硬不等式约束g(v,p)0g(v,p)\geq 0: 通过参数将其initial guess对应的初始值g(v0,p)g(v^0,p)设置为inf (恒大于0)
  • 软不等式约束g(v,p)0g(v,p)\geq 0: 通过将惩罚权重设置为0.0, 或者通过参数将其initial guess对应的初始值g(v0,p)g(v^0,p)设置为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, 此时该软边界会与硬边界综合形成新的硬边界 (即取两者中更严格的一个)
  • 软不等式约束g(v,p)0g(v,p)\geq 0: 通过将惩罚权重设置为inf
  • 软等式约束f(v,p)=0f(v,p)=0: 通过将惩罚权重设置为inf