跳到正文
格致开物MATHWIKI

目标规划

目标规划(goal programming)先为若干指标指定期望水平,再最小化未达标或超标的偏差。它保留必须满足的硬约束,同时允许不同软目标之间妥协。目标值不是硬约束:偏离一个愿望可以支付代价,违反硬约束则仍不可行。

同时希望至少八件与至多六件

设生产量 x∈[0,10],上界是硬产能限制。交付目标希望 x≥8,费用目标经换算希望 x≤6。两愿望无法同时满足,定义不利偏差 d1−(x)=(8−x)+,d2+(x)=(x−6)+,a+=max⁡(a,0). 第一项是交付不足,第二项是超预算对应的数量。若取等权目标 P(x)=d1−(x)+d2+(x),当 x∈[6,8] 时,P=(8−x)+(x−6)=2;区间外则严格更大。所以整个区间都是最优解,软化冲突目标并不保证唯一解。

交付不足与超预算的两个不利偏差
六到八之间无法同时消去两种偏差,等权时二者之和恒为二。

例如x=7对应两种不利偏差均为一,x=8对应交付不足零、超预算二。两方案的罚值相同,不代表在实际业务中无区别;它只是当前模型明确表达的取舍。

偏差变量怎样变成等式

对指标 fi(x) 和目标水平 gi,引入非负变量并写 fi(x)+di−−di+=gi,di−,di+≥0. 若只是不希望低于目标,罚 di−;若只是不希望超过,罚 di+;希望尽量接近则可同时罚两侧,且可用不同权重。主例的两式分别是 x+d1−−d1+=8、x+d2−−d2+=6,仅将 d1− 与 d2+ 放进目标。

对给定x,若两偏差同时为正,可从二者各减去相同的较小值,等式不变。只要两者的罚权重之和为正,目标就严格下降。因此最优解中不会同时保留多余的正负偏差,最小偏差恰为正部公式。若两侧都不计代价,偏差变量可不唯一,但仍有这种规范表示。仿射指标、线性硬约束与线性偏差罚值构成线性规划;目标规划这个名称本身不要求所有模型都线性。[1]

加权与优先级是两种取舍

取 w1,w2>0,主例的罚值完整分段为 Pw(x)={w1(8−x),0≤x≤6,w1(8−x)+w2(x−6),6≤x≤8,w2(x−6),8≤x≤10. 左段严格递减、右段严格递增,中段斜率是 w2−w1,故 w1>w2 时唯一解为八,w1<w2 时唯一解为六,等权时解为整个[6,8]。这是覆盖连续可行区间的完整证明,检查少数整数本身不能得出该结论。

不同罚权重在同一连续区间上的比较
等权最优集为[6,8];交付不足权重更大时选八,超预算权重更大时选六。

有解变式:令交付不足的权重为三、超预算权重为一,解为八,罚值二;反过来解为六,罚值二。偏差采用不同单位时,直接相加没有稳定意义,应报告相应单位、尺度及换算权重。

优先级或字典序方法则先把第一偏差减到最小,再在第一偏差保持最优的集合内优化第二偏差。主例若交付优先,第一阶段将集合限制为[8,10],第二阶段选八;若预算优先,先限制到[0,6],再选六。一般形式是从 X0=X 开始,逐级计算 vj=minx∈Xj−1Pj(x)、Xj={x∈Xj−1:Pj(x)=vj},各阶段须有最小值才能继续。

一个很大的有限权重未必等同于字典序。若仅有两方案,偏差向量分别是(0,100)和(1,0),权重(10,1)选择后者,而第一偏差优先的字典序必选前者。把本例中的100换成更大的数,可击败任意预先指定的有限第一权重。若有离散的最小改进量与已知后级范围,才可另证某个大权重足够。

运行一个覆盖连续区间的计算

代码按上面已证的分段线性结构检查端点和折点,同时返回最优区间。只用 Python 3 标准库,输入两个正权重,输出最小罚值、最优区间和折点表,不改写输入,固定四个点的成本为常数。它专用于正文的两个目标和产能范围;新增软目标会引入新折点,不能原样套用这四点。

Python 3
import math

def production_goals(w1=1.0,w2=1.0):
    if not all(math.isfinite(v) and v > 0 for v in (w1,w2)):
        raise ValueError("positive finite weights required")
    penalty = lambda x:w1*max(8-x,0)+w2*max(x-6,0)
    table = [(x,max(8-x,0),max(x-6,0),penalty(x)) for x in (0,6,8,10)]
    if w1 > w2:
        interval = (8,8)
    elif w1 < w2:
        interval = (6,6)
    else:
        interval = (6,8)
    return penalty(interval[0]),interval,table

for weights in [(1,1),(3,1),(1,3)]:
    print(weights,production_goals(*weights))
print("delivery-first",8,"budget-first",6)
assert production_goals()[1] == (6,8)

输出等权时的最优区间为(6,8),权重(3,1)与(1,3)分别给(8,8)、(6,6)。硬约束本身若冲突仍可能无解;应由建模者决定哪些条件可以软化,而不是自动把所有约束改为愿望。若对超额完成也施罚,目标规划还可能选择被原始“越多越好”指标支配的点,不能无条件声称结果属于原多目标问题的帕累托前沿。

参考文献

  1. ↑ Schrage, Optimization Modeling with LINGO,第五版,§14.3软约束与§14.3.2优先级目标规划。