您的问题可以用混合整数问题建模。如果你的集合不是太大(比如几百个值),我会使用这个模型,因为在标准 lp 文件中编写它比对启发式编程和参数化更容易。
您可以将此问题交给混合整数问题求解器:
- 硬币或(免费),
- Cplex(商业和广阔,除非你是学者),
- 古罗比(商业),
- GLPK(免费,但速度慢)...
我在下面用伪数学语言写了两个模型(注意这不是 LP 格式)。
硬边界
让 N 是您的对象的集合,X_min 和 Y_min 是您需要达到的下限,ZZ 是 Z 值的平均下限。我使用一个二进制变量 s_i,如果对象 i 被选中,它的值为 1,否则为 0。确切的问题可以写成:
Minimize sum_{i in N} s_i
Subject to:
sum_{i in N} X_i s_i >= X_min
sum_{i in N} Y_i s_i >= Y_min
sum_{i in N} (Z_i - ZZ) s_i >= 0
foreach i in N, s_i in {0, 1}
多目标
请注意,正如 Andreas 的回答所述,还有其他方法可以做到这一点。这是一种更容易(在我看来)确定目标优先级和“放松”问题的方法,您可以使用上面的线性求解器。
您添加三个松弛变量 dX、dY、dZ 和三个(正)权重系数 wX、wY、wZ。变量 dX、dY 和 dZ 将代表违反约束,而“权重”代表您对违反约束的重视程度。
然后你可以把问题写成:
Minimize sum_{i in N} s_i + wX dX + wY dY + wZ dZ
Subject to:
dX >= sum_{i in N} X_i s_i - X_min
dY >= sum_{i in N} Y_i s_i - Y_min
dZ >= sum_{i in N} (Z_i - ZZ) s_i
foreach i in N, s_i in {0, 1}
dX, dY, dZ >= 0
然后,您可以对 wX、wY 和 wZ 进行参数化,以便确定目标的优先级:例如,对于较大的权重值,模型将返回“硬绑定”解决方案(如果存在);那么,与另一个相比,具有较高权重的约束“不太可能”被违反(当然,它并不完全那么简单,只是给出一个想法)。