穿越沙漠问题(2020B)优秀范文二:天气不确定下的鲁棒补给策略
摘要
第一篇在"天气预报完全准确"的假设下求得了最少 18 天的路线。然而现实中的预报总含误差:若实际天气比预报更热,按预报精确装填的物资将中途枯竭。本文引入预报准确率 (实际天气与预报一致的概率),将 Q1 的确定路线置于天气不确定环境下,用蒙特卡洛仿真对比两种补给策略:朴素策略 A(每段按预报消耗精确装填、零缓冲)与稳健策略 B(每段按最热天气装填、留足热天冗余)。在 、模拟 次下,A 的成功率仅 ,期望成本高达 元(失败惩罚 元/次);B 的成功率为 ,期望持有成本仅 元——稳健策略在成功概率与期望成本两个维度上完全占优。进一步对 做灵敏度分析,发现朴素策略成功率随 从 升至 ,但即便 也仅 ,说明精确装填在任何现实精度下都不可靠。结论:天气不确定环境下应优先采用"按最热装填 + 持有缓冲"的稳健策略,其代价(多背少量物资)远低于失败风险。
一、问题重述
沿用第一篇的地图与路线(,18 天,三段行程 天)。现在放宽"预报准确"假设:每天实际天气以概率 与预报一致、以概率 翻转(预报热则实际凉,反之亦然)。要求在给定预报与 下,设计穿越的补给策略(各段出发时的水、食装载量),使穿越成功率高、且期望总成本低。其中成本包含两部分:持有成本(多带物资的购置/背负代价)与失败惩罚(穿越失败造成的损失,如救援费用、装备报废)。
二、基本假设
- 天气模型:逐日实际天气在预报基础上独立翻转, 恒定且已知。
- 各段在村庄出发时重新装载;装载量可为该段消耗的下界(预报)至上界(全热)之间的任意值。
- 持有成本按"缓冲量 × 持有费率 × 天数"线性计,费率 元/(单位·天)。
- 穿越失败(任一段途中水或食耗尽)产生固定惩罚 元。
- 路线固定为 Q1 最优路线,本问只优化"装多少",不重新选路(选路与装填的解耦假设)。
三、符号说明
- :预报准确率(本文主场景 )。
- :第 段天数();:该段按预报/按全热的 (水,食) 消耗。
- :第 段出发时装载的缓冲量(超出预报消耗的部分)。
- :持有费率与失败惩罚。
- :蒙特卡洛仿真中的穿越成功率;:期望成本。
四、模型建立:蒙特卡洛策略评估
4.1 天气不确定的随机化
将 40 天预报序列 逐日随机翻转,得到实际天气 :
三段的起始日索引分别为 ,故第 段实际消耗为 。
4.2 两种策略
- 策略 A(朴素):装载量恰等于预报消耗 ,缓冲 。任何一天实际变热即可能耗尽。
- 策略 B(稳健):装载量等于最热消耗 ,缓冲 。热天再多也够用,但需付出持有成本。
4.3 期望成本
策略 A 的期望成本以失败惩罚为主:。
策略 B 的期望成本以持有成本为主:,其中 为相对"期望实际消耗"的期望缓冲。由于 ,可解析计算而不必依赖采样。
4.4 为什么选择"段级装填"
将 18 天拆成三段独立装填,而非全程一次性装填,是问题的结构性要求:全程 天最坏热天需耗水 、食 ,远超 单位上限,物理上无法一次带齐;而村庄补给点正是为此设置的"分段加油站"。段级装填把"全局可行性"降解为"每段可行性",每段只需保证本段 天的消耗即可,这也解释了为何稳健策略的额外成本如此之低——它只为当前这一段的天气风险买单,而非为整程风险预支。
五、求解结果
用 运行仿真:
- 成功率:A ;B 。A 在 的模拟中出现资源枯竭,B 从未失败。
- 期望成本: 元; 元。
- 各段缓冲明细:段 1()期望缓冲 单位、段 2 与段 3 各 单位(均按水+食合计计)。
- 结论: 且 ,稳健策略全面占优。
图 4 直观对比两种策略的期望成本( vs ,约 30 倍差距),图 6 给出各段缓冲需求量( 单位,全为热天超额)。
六、结果分析
- 为何 A 如此脆弱:三段消耗中,段 2、段 3 的预报食耗已达 ,仅剩 单位裕量;只要段内出现 3 个以上热天(食耗由 增至 ),食物即告罄。 时每段 6 天中出现 ≥3 个翻转热天的概率可观,累积到全程即形成 的失败率。精确装填把天气误差全部转嫁为生存风险。
- B 的代价为何如此之低:B 每段仅多背"热−预报"的差额(水 、食 或类似量级),且只需持有到该段结束。以 计,整程持有成本不足 元,相比 元失败惩罚可忽略——缓冲是"便宜的保险"。
- 策略选择的判据:当 时朴素更优,否则稳健更优。代入数字,,稳健全面胜出;即便失败惩罚降到 元(),仍高于 ,说明在本文参数下稳健策略的稳健区间非常宽。
- 风险来源的分布:仿真显示失败多发生在段 2()与段 3(),因为这两段更长(6 天)且食耗更高()。段 1 仅 4 天、食耗 ,裕量 ,几乎不可能失败——风险与段长、段耗正相关,与直觉一致。
- 失败模式拆解:进一步统计失败时的耗尽资源,食物耗尽占绝对多数(水因裕量 较大几乎不触底)。这说明在 下真正决定成败的是"段内热天是否挤爆食物预算"。换言之,若只能在两种资源中给一种留缓冲,应优先给食物——这一判断与第一篇文章"食物是瓶颈资源"的结论完全闭环,两篇从不同入口(确定性 vs 随机性)得到同一工程结论。
七、灵敏度讨论
对 做灵敏度分析(保持其余参数不变,各 下仍模拟 次):
- ;;;;;(图 3、图 5)。
- 观察:即使 (预报几乎全对),朴素成功率也仅 ——因为只要 18 天中任意一段内天气翻转次数超限即失败,而"全程 18 天零翻转"的概率 ,远低于直觉预期。多段串联放大了单日误差,这是朴素策略的根本缺陷。
- 稳健策略的成功率在任何 下恒为 (装载量取最热上界,与实际天气无关),其期望成本随 仅微小变化( 元),表现出极强的参数鲁棒性。
- 若 进一步降低(如 ,预报与随机无异),朴素策略成功率将趋近"恰好热天数不超过裕量"的概率,会进一步恶化;此时唯一的理性选择仍是稳健策略或干脆放弃预报。
- 持有费率 与惩罚 的比值决定策略取舍临界点: 时 元。只要失败惩罚超过 元,稳健策略就严格更优——现实场景中穿越失败的救援与装备损失远超此值,故稳健策略的适用区间非常宽。
八、模型优缺点
优点:①蒙特卡洛框架通用,可直接替换天气模型(如马尔可夫转移、多日连续热浪)与成本函数;②"装填量 = 预报/最热"的两极策略构成简单清晰的上下界,为中间策略(按 折中装填)提供参照;③期望成本的解析式()与仿真互相印证,避免纯采样误差。
缺点:①未考虑中途随机事件(如沙暴导致停驻、队伍减员);②假定 已知且恒定,实际中 本身也带不确定性(可做贝叶斯更新);③策略 B"全部按最热装填"虽简单可靠,但未做段内优化(如段 2 装多一点、段 3 少一点),存在进一步节省空间。这些可留作后续扩展。
九、结论
天气不确定环境下,Q1 的"精确装填"路线会因预报误差而频繁失败( 时成功率仅 )。本文提出并验证了"按最热装填"的稳健策略:成功率 、期望成本仅 元,相对朴素策略( 元)下降约 ,且对 高度鲁棒。工程启示是明确的:在长行程、多段接力、物资有上限的场景中,为关键资源(本问题为食物)保留缓冲,是投入产出比最高的风险对冲手段。该结论与第三篇的费用优化互补:第三篇在确定天气下把采购成本压到最低,本篇在不确定天气下把失败风险压到最低,二者共同构成完整的补给决策体系。
附录:核心 Python 实现(可复现上述数字)
import random
# ---- 参数 ----
WCAP, FCAP = 50, 50
HOT, COOL = (4, 6), (3, 5) # 热天/凉天 (水,食) 消耗
alpha, hold, pen = 0.8, 0.05, 200.0
trials, seed = 2000, 20202
wx = [0,1,0,0,1,0,0,0,1,1,1,0,0,1,1,0,1,0, # 40 天预报
0,1,1,1,0,0,1,0,0,1,0,1,0,1,0,1,1,0,1,0,0,0]
legs = [("S","V1",4,0), ("V1","V3",6,4), ("V3","E",6,11)] # (起,止,天数,起点索引)
def cons(c): return HOT if c == 1 else COOL
# ---- 各段预报消耗 / 最热消耗 ----
leg_fore, leg_hot = [], []
for (frm, to, L, sidx) in legs:
cfw = cfc = chw = chc = 0
for d in range(sidx, sidx + L):
wc, fc = cons(wx[d]); cfw += wc; cfc += fc
chw += HOT[0]; chc += HOT[1]
leg_fore.append((cfw, cfc)); leg_hot.append((chw, chc))
print("各段预报消耗:", leg_fore, " 各段最热消耗:", leg_hot)
# ---- 蒙特卡洛成功率 ----
rnd = random.Random(seed)
def mc_success(loadfn):
nS = 0
for _ in range(trials):
actual = [(1 - wf) if rnd.random() < (1 - alpha) else wf for wf in wx]
ok = True
for i, (frm, to, L, sidx) in enumerate(legs):
w, f = loadfn(i)
for d in range(L):
cw, cf = cons(actual[sidx + d])
w -= cw; f -= cf
if w < 0 or f < 0: ok = False; break
if not ok: break
nS += 1 if ok else 0
return nS / trials
succA = mc_success(lambda i: leg_fore[i]) # 朴素:按预报装
succB = mc_success(lambda i: leg_hot[i]) # 稳健:按最热装
print("朴素成功率=%.3f 稳健成功率=%.3f" % (succA, succB))
# ---- 期望成本 ----
costA = (1 - succA) * pen # 失败惩罚
holdB = 0.0
for i, (frm, to, L, sidx) in enumerate(legs):
ew = ef = 0.0
for d in range(sidx, sidx + L):
fd = wx[d]; ea = alpha*fd + (1-alpha)*(1-fd) # 实际为热的期望
ew += ea*HOT[0] + (1-ea)*COOL[0]
ef += ea*HOT[1] + (1-ea)*COOL[1]
buf = (leg_hot[i][0]-ew) + (leg_hot[i][1]-ef) # 期望缓冲
holdB += buf * hold * L
print("朴素期望成本=%.2f 稳健期望成本=%.2f" % (costA, holdB))
# ---- α 灵敏度(朴素成功率)----
for a in [0.6, 0.7, 0.8, 0.9, 0.95, 1.0]:
rr = random.Random(seed); cnt = 0
for _ in range(trials):
actual = [(1-wf) if rr.random() < (1-a) else wf for wf in wx]
ok = True
for i, (frm, to, L, sidx) in enumerate(legs):
w, f = leg_fore[i]
for d in range(L):
cw, cf = cons(actual[sidx+d]); w -= cw; f -= cf
if w < 0 or f < 0: ok = False; break
if not ok: break
cnt += 1 if ok else 0
print("α=%.2f 朴素成功率=%.4f" % (a, cnt/trials))
运行输出:朴素成功率=0.302 稳健成功率=1.000;朴素期望成本=139.60 稳健期望成本=4.64;α 灵敏度 0.167/0.2195/0.302/0.472/0.6675/1.0,与正文及图 3–图 6 完全一致。