动态批量问题
动态批量问题(dynamic lot-sizing problem)在各期需求已知但不恒定时,联合决定什么时候订货、一次订多少。每次订货要付一笔固定费用,提前订货又会产生库存费;单独优化某一期,可能错过把相邻需求合成一批的机会。
考虑四周需求依次为 件的教学模型。每次订货固定费五元,期末库存每件每周收一元;补货立即到达,没有容量限制和缺货,初、末库存均为零。单位采购价固定时,总采购数量必为十件,采购费对所有方案相同,以下只比较订货与持有费用。
用库存守恒写出模型
令 为第 周初订量, 为该周期末库存, 为需求。先补货再满足需求,因此 固定费 仅在 时发生,目标为 ,其中 是每件跨一个周期的库存费。本篇先取 为常数,需求确定且非负;提前期、产能上限和延期交货均暂不加入。[1]
逐周订货的四笔固定费共二十元,库存费为零。若第一周把十件全部买来,期末库存为 ,费用为 元。两种简单方案都可行,却还不是最便宜的方案。
一批货覆盖连续需求
在上述条件下,存在一个最优方案,使每次正订货之前库存为零。说明这一性质时,可以把货品逐件标记:若本周仍有旧货留到周初,且本周也在订货,就把尚未用掉的那部分旧货推迟到本周这笔订单。此前需求仍由已被消耗的货满足,本周及以后可用量不变;没有新开订单,旧订单还可能被取消,持有费用只会减少或不变。反复作这种调整,就得到所述结构。这个论证用到了固定采购单价和无限订量;有产能上限时推迟采购可能不可行。
因此一笔订单可以看成负责某段连续需求。若在第 周订货,覆盖到第 周,相关费用为 第 周要用的 件提前存放了 周,故乘上该距离。整段需求为零时,无须实际订货,费用应为零。
递推与完整计算
记 为满足前 周需求、结束时清空库存的最小费用,。最后一笔正订单从某个 开始,前面必须已最优地解决前 周,因此 任意结构化方案都落在其中一个分支,给出不小于右端的下界;反过来,取前段最优方案与这笔订单拼接,就得到右端对应的可行方案。向前归纳证明递推确实求得最优值,而非只给出一种启发式。
主例中 ,;第三周三种最后起点的费用为 ,所以 。第四周对应四个候选为 ,最小值为十三。回溯得第一周订五件、第三周再订五件。
订单后的期末库存为 ,故固定费为十元、库存费为三元,总费用十三元,和递推值一致。
可复算实现与变式
下例输入非负有限需求、固定费和持有费,返回一组最优订单及相关费用,不修改输入。前缀需求和与“时期乘需求”的前缀和,使每段费用可用常数次运算求出;共检查 段,时间为 ,额外空间为 。比较采用浮点数,接近相等的费用可能受舍入影响。
import math
def dynamic_lots(demand, setup, holding):
d = tuple(float(v) for v in demand)
setup, holding = float(setup), float(holding)
if any(not math.isfinite(v) or v < 0 for v in d + (setup, holding)):
raise ValueError("finite nonnegative data required")
n = len(d)
p, w = [0.0], [0.0]
for k, value in enumerate(d):
p.append(p[-1] + value)
w.append(w[-1] + k * value)
f, previous = [0.0] + [math.inf] * n, [0] * (n + 1)
for t in range(1, n + 1):
for j in range(t):
quantity = p[t] - p[j]
cost = 0.0 if quantity == 0 else setup + holding * (
w[t] - w[j] - j * quantity)
if f[j] + cost < f[t]:
f[t], previous[t] = f[j] + cost, j
orders, t = [], n
while t:
j = previous[t]
quantity = p[t] - p[j]
if quantity > 0:
orders.append((j + 1, quantity))
t = j
return list(reversed(orders)), f[n]
print(dynamic_lots([3, 2, 4, 1], 5, 1))
# ([(1, 5.0), (3, 5.0)], 13.0)
变式。 固定费降到每次二分之一元,持有费仍为一元时,逐周订货只需两元。任何把正需求提前存放一周的方案至少多付一元,却至多省下二分之一元,因此逐周订货最优。需求全为零或没有周期时,代码返回空订单、零费用。
容量约束、随时间变化的采购价、损耗或批量折扣会改变段费用与结构证明。使用相同的库存守恒式,并不保证还能使用这条无容量动态规划。
参考文献
- ↑ MIT OpenCourseWare,Dynamic Economic Lot Sizing Model,ESD.273J (2009),第21—28页,模型假设、零库存订货与最短路递推。