2026-01-18 14:43:22 +08:00
2026-01-18 14:26:44 +08:00
2026-01-18 14:26:44 +08:00
2026-01-17 18:41:59 +08:00
2026-01-17 18:46:16 +08:00
2026-01-17 11:26:04 +08:00
2026-01-17 19:25:35 +08:00
2026-01-17 11:26:04 +08:00
2026-01-18 14:43:22 +08:00
2026-01-17 19:25:35 +08:00
2026-01-17 23:03:26 +08:00

20260116 美赛模拟食物分发MFP

本仓库包含对 2019 年 MFP 站点数据的频次分配(任务一)与全年排班优化(任务二)脚本。 核心数据文件:prob/MFP Regular Sites 2019.xlsx

Task 1: 频次分配Visit Frequency Allocation

目标:在总车次约束下,为每个站点分配年度访问次数 f_i,并评估有效性/公平性含最低10%平均、基尼系数等)。

  • 运行:python3 kmin_effectiveness.py
  • 输出(写入 data/
    • data/kmin_effectiveness.pngk_min 与指标曲线图
    • data/kmin_effectiveness_data.csv:每个 k_min 的汇总指标 + 各站点 visits_01..visits_N
    • data/kmin_effectiveness_sites.csvvisits_XX 与站点名称/顺序映射

说明:kmin_effectiveness.py 当前使用 Monte Carlo引入 StDev(Demand per Visit))对有效性做多次模拟平均。

kmin effectiveness

Scheduling (Step 2)

Optimize a 365-day schedule with at most 2 visits per day and minimum gap constraints:

  • python3 scheduling_optimization.py --days 365 --daily-capacity 2 --gap-min 14
  • Outputs are written to data/ (e.g., data/schedule_optimized_kmin6.8_gap14.csv), using data/kmin_effectiveness_data.csv as the frequency source.

Visualization (Plan A)

  • python3 visualize_schedule.py
  • Outputs: data/schedule_barcode_*.png and data/schedule_gap_deviation_*.png
  • Site label rule: remove first 4 chars, then take 12 chars.

schedule barcode

schedule gap deviation

Task 3: 双站点同车方案Two-stop trips

目标:允许同一辆车在一次出车中访问两个站点,需要在站点配对、访问日期以及第一站分配量上共同决策,并评估有效性/公平性。

算法框架(基于 Task 1/2 输出)

  1. 需求与频次基线
    使用 kmin_effectiveness.py 得到各站点年度访问频次 f_i 与需求分布(均值、标准差)。
    记单车载量 C=15000lb(或折算为服务人数上限 C_OPT),每次出车总量不超过 C

  2. 候选配对生成Manhattan 距离,基于经纬度)
    设站点 i 的坐标为 (lat_i, lon_i),在不使用道路网的情况下,用曼哈顿距离近似“同日可达性”。
    推荐用“纬度/经度分别折算为里程”的加权曼哈顿:

    d_ij = 69.0 * |lat_i - lat_j| + 69.0 * cos(lat0) * |lon_i - lon_j|
    

    其中 lat0 可取所有站点纬度均值(单位:英里)。若仅需相对距离,也可用 |lat_i - lat_j| + |lon_i - lon_j| 作为无量纲近似。
    具体配对流程(可直接脚本化):

    • 距离筛选:对每个站点 i,计算与所有 j != id_ij,保留 d_ij <= d_max 或取 k 个最近邻(如 k=5~8),得到近邻集合 N(i)
    • 需求均衡筛选:对候选 (i, j),要求 mu_i / mu_j 处于区间 [r_min, r_max](如 [0.5, 2.0]|mu_i - mu_j| <= delta_mu,避免极端失衡导致第二站缺货。
    • 波动风险筛选:若 sigma_isigma_j 过大(如 sigma / mu > 0.5 则优先作为第二站(或直接剔除)以降低不确定性风险。
    • 最终候选集P = {(i, j) | j in N(i) 且满足需求/波动筛选} 再去重((i, j)(j, i) 合并)并记录候选对的 d_ij 与需求统计。
  3. 第一站分配量优化(核心不确定性)
    假设 D_i ~ Normal(mu_i, sigma_i)D_j ~ Normal(mu_j, sigma_j),选择第一站上限 q_i

    • 实际服务:S_i = min(D_i, q_i)
    • 剩余载量:R = C - S_i
    • 第二站服务:S_j = min(D_j, R)
      用一维搜索/网格或解析近似,选择 q_i* 最大化期望目标:
    maximize   E[S_i + S_j]
               - alpha * E[unmet_i + unmet_j]
               - beta  * E[waste_i + waste_j]
               - gamma * |E[S_i / D_i] - E[S_j / D_j]|
    

    期望可用 Monte Carlokmin_effectiveness.py 一致)或截断正态闭式近似;得到每个候选对的 (q_i*, score)

  4. 排程与配对选择CP-SAT / MIP
    在 Task 2 的日程框架上,将“单站访问”与“可配对双站访问”视作不同任务,决策变量:

    • 是否在某天为一辆车选择 (i, j)
    • 其他站点仍按单站访问
      约束:每站点访问次数 = f_i;每日出车数 ≤ 2每辆车最多一条路线。
      目标:最大化总期望有效性得分,并在目标函数中加入公平性惩罚(如 Gini 或最低 10% 均值惩罚)。
  5. 有效性 & 公平性评估
    复用 Task 1 指标:

    • 有效性:总体服务率、总未满足需求、总浪费
    • 公平性:基尼系数、最低 10% 站点平均服务比例、最小服务比例
      对双站路线进行 Monte Carlo 汇总,给出与单站方案的对比提升/退化幅度。

直观规则(工程可用的简化版)

  • 配对规则:优先将“高需求站点 + 低需求站点”或“需求相近且近邻”的站点配对,降低极端不公平。
  • 第一站分配q_iD_i 的 60%~80% 分位数作为保守上限,剩余量留给第二站;必要时按历史波动调整分位数。
  • 动态修正:若某站点连续出现“后站不足”,在后续排程中降低其作为第一站的概率或提高 q_i 分位数阈值。

该方案与当前脚本兼容:kmin_effectiveness.py 提供需求统计与 Monte Carlo 框架;scheduling_optimization.py 的 CP-SAT 可扩展为“单站/双站二选一”的排程模型。

Description
美赛模拟-食物分发 (20260116)
Readme 30 MiB
Languages
Python 65%
TeX 27.7%
HTML 6.9%
C++ 0.3%