目标规划
目标规划(goal programming)先为若干指标指定期望水平,再最小化未达标或超标的偏差。它保留必须满足的硬约束,同时允许不同软目标之间妥协。目标值不是硬约束:偏离一个愿望可以支付代价,违反硬约束则仍不可行。
同时希望至少八件与至多六件
设生产量 ,上界是硬产能限制。交付目标希望 ,费用目标经换算希望 。两愿望无法同时满足,定义不利偏差 第一项是交付不足,第二项是超预算对应的数量。若取等权目标 ,当 时,;区间外则严格更大。所以整个区间都是最优解,软化冲突目标并不保证唯一解。
例如x=7对应两种不利偏差均为一,x=8对应交付不足零、超预算二。两方案的罚值相同,不代表在实际业务中无区别;它只是当前模型明确表达的取舍。
偏差变量怎样变成等式
对指标 和目标水平 ,引入非负变量并写 若只是不希望低于目标,罚 ;若只是不希望超过,罚 ;希望尽量接近则可同时罚两侧,且可用不同权重。主例的两式分别是 、,仅将 与 放进目标。
对给定x,若两偏差同时为正,可从二者各减去相同的较小值,等式不变。只要两者的罚权重之和为正,目标就严格下降。因此最优解中不会同时保留多余的正负偏差,最小偏差恰为正部公式。若两侧都不计代价,偏差变量可不唯一,但仍有这种规范表示。仿射指标、线性硬约束与线性偏差罚值构成线性规划;目标规划这个名称本身不要求所有模型都线性。[1]
加权与优先级是两种取舍
取 ,主例的罚值完整分段为 左段严格递减、右段严格递增,中段斜率是 ,故 时唯一解为八, 时唯一解为六,等权时解为整个[6,8]。这是覆盖连续可行区间的完整证明,检查少数整数本身不能得出该结论。
有解变式:令交付不足的权重为三、超预算权重为一,解为八,罚值二;反过来解为六,罚值二。偏差采用不同单位时,直接相加没有稳定意义,应报告相应单位、尺度及换算权重。
优先级或字典序方法则先把第一偏差减到最小,再在第一偏差保持最优的集合内优化第二偏差。主例若交付优先,第一阶段将集合限制为[8,10],第二阶段选八;若预算优先,先限制到[0,6],再选六。一般形式是从 开始,逐级计算 、,各阶段须有最小值才能继续。
一个很大的有限权重未必等同于字典序。若仅有两方案,偏差向量分别是(0,100)和(1,0),权重(10,1)选择后者,而第一偏差优先的字典序必选前者。把本例中的100换成更大的数,可击败任意预先指定的有限第一权重。若有离散的最小改进量与已知后级范围,才可另证某个大权重足够。
运行一个覆盖连续区间的计算
代码按上面已证的分段线性结构检查端点和折点,同时返回最优区间。只用 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)。硬约束本身若冲突仍可能无解;应由建模者决定哪些条件可以软化,而不是自动把所有约束改为愿望。若对超额完成也施罚,目标规划还可能选择被原始“越多越好”指标支配的点,不能无条件声称结果属于原多目标问题的帕累托前沿。
参考文献
- ↑ Schrage, Optimization Modeling with LINGO,第五版,§14.3软约束与§14.3.2优先级目标规划。