6.4. 多目标问题求解

当问题是线性问题时,用户想要同时优化多个目标的时候,可以使用多目标功能。

在大多数情况下,求解器并不能为所有的目标函数找到最优值,用户需要将各个目标函数按照优先级排序, 求解器将会优先保证重要的目标函数取得更优的值。

但这也不是一定的,用户可以配置一些参数,让“更重要” 的目标函数“适度”牺牲一些最优性,让后续“不重要”的目标函数能获得更大的优化自由度。

用户可以通过各SDK的API函数,或属性来使用多目标功能,具体SDK的API细节请参考API文档。

备注

多目标功能只支持线性规划,包括 LP 和 MILP。

6.4.1. 用户接口

6.4.1.1. 优先级

每一个目标函数,可以配置一个对应的优先级(属性 ObjNPriority ),求解器在求解多目标问题时, 往往会有多轮求解。求解顺序即是由“优先级”来确定的。

每一轮求解,都是在尽量不影响前续目标函数值的约束下,将当前目标函数优化到最优。

6.4.1.2. 权重

每一个目标函数,可以配置一个对应的权重(属性 ObjNWeight ),当有两个或两个以上的目标函数, 有相同的优先级时,他们会被合并为同一个目标,并只会求解一轮。合并后的新目标函数,就是原来每个 目标函数的加权和。

6.4.1.3. 容差

用户可以定义绝对容差(属性 ObjNAbsTol )和相对容差(属性 ObjNRelTol ),来“适度”的允许 之前那些“更重要”的目标函数值,有一定程度的下降。这样往往可以换取后续那些“不重要”的目标,其优化 程度得到显著的改善。

容差的定义和计算方式,将在下一节介绍。

6.4.2. 计算逻辑

6.4.2.1. 目标合并和排序

举个例子,有以下目标函数:

\[\begin{split}\begin{align*} &OBJ0 (Priority=1, Weight=2.0, AbsTol=1e-6, RelTol=0) \\ &OBJ1 (Priority=2, Weight=2.0, AbsTol=1e-5, RelTol=1e-5) \\ &OBJ2 (Priority=3, Weight=2.0, AbsTol=1e-6, RelTol=0) \\ &OBJ3 (Priority=2, Weight=1.0, AbsTol=1e-4, RelTol=1e-6) \end{align*}\end{split}\]

优先级排序后,为:

\[\begin{split}\begin{align*} &OBJ2 (Priority=3, Weight=2.0, AbsTol=1e-6, RelTol=0) \\ &OBJ1 (Priority=2, Weight=2.0, AbsTol=1e-5, RelTol=1e-5) \\ &OBJ3 (Priority=2, Weight=1.0, AbsTol=1e-4, RelTol=1e-6) \\ &OBJ0 (Priority=1, Weight=2.0, AbsTol=1e-6, RelTol=0) \end{align*}\end{split}\]

同优先级合并后,剩余3个目标函数:

\[\begin{split}\begin{align*} &OBJ2 (Priority=3, Weight=2.0, AbsTol=1e-6, RelTol=0) \\ &OBJ4 (Priority=2, Weight=1.0, AbsTol=1e-4, RelTol=1e-5) \\ &OBJ0 (Priority=1, Weight=2.0, AbsTol=1e-6, RelTol=0) \end{align*}\end{split}\]

其中:

\[OBJ4 = 2.0 \times OBJ1 + 1.0 \times OBJ3\]

注意,在合并的过程中,AbsTol和RelTol,取各个目标函数里最大的。

6.4.2.2. 求解过程

第一个目标的 AbsTolRelTol 将会被忽略。

对于后续的目标优化,将使用 AbsTolRelTol, 通过允许前续目标质量降低,来换取当前目标的优化 自由度。

如求解 \(OBJ4\),上一个目标为 \(OBJ2\)

  • 如果是MILP问题,将添加一条约束(假设是最小化问题):

    \[OBJ2 <= rhs\]

    其中 \(rhs\) 是上一轮的目标值,和 AbsTolRelTol 计算后,得到的最大松弛下界。

  • 如果是LP问题,将通过固定一些变量的方式,来保障前续的目标。LP问题将忽略 RelTol,只使用 AbsTol

    上一轮求解得到了各变量的 ReducedCost ,当一个变量满足 \(ReducedCost \le AbsTol\) 时,它会被固定在对应的边界上。

用户可以通过加入无用整型变量的方式,让多目标强制执行MILP的分支计算逻辑。