# Task 1: 2021年MFP访问计划——需求驱动的频次分配与日历排程 ## 摘要 本文提出一套**因果逻辑清晰、闭环可审计**的2021年MFP访问频次分配与日历排程方案。核心创新点: 1. **截断回归修正**:识别到9个站点历史服务量 $\mu_i > 250$(最高396.6),说明高需求站点的观测数据被容量截断,采用截断正态模型恢复真实需求 $\tilde{\mu}_i$ 2. **质量加权有效性**:考虑高服务量下每户分配食物减少的质量折扣 3. **满足率公平性**:以"年度服务量/真实需求"的均等程度衡量公平,而非简单的访问次数均等 方案遵循四阶段结构:需求估计 → 频次分配 → 效果评估 → 日历排程。 --- ## 整体流程图 ### Mermaid版本(GitHub可渲染) ```mermaid flowchart TB subgraph INPUT["数据输入"] A[data.xlsx
70站点数据] end subgraph TASK1["TASK 1: 基础排程"] direction TB subgraph CORE["核心流程 ✅ 已完成"] B1[01_clean.py
数据清洗] B2[02_demand_correction.py
截断回归修正] B3[03_allocate.py
Hamilton分配] B4[04_evaluate.py
指标计算] B5[05_schedule.py
日历排程] B1 --> B2 --> B3 --> B4 B3 --> B5 end subgraph VALIDATE["结果验证 ⏳ 待完成"] V1[06_validate.py
约束检验] V2[07_backtest.py
历史回测] end subgraph SENSITIVITY["敏感性分析 ⏳ 待完成"] S1[08_sensitivity.py
参数扫描] end subgraph VISUAL["可视化 ⏳ 待完成"] P1[09_visualize.py
图表生成] end CORE --> VALIDATE CORE --> SENSITIVITY VALIDATE --> VISUAL SENSITIVITY --> VISUAL end subgraph TASK2["TASK 2: 天气响应 ⏳"] C1[2a或2b方案] end subgraph TASK3["TASK 3: 双站点同车 ⏳"] D1[共生站点优化] end subgraph TASK4["TASK 4: Executive Summary ⏳"] E1[1页执行摘要] end A --> B1 VISUAL --> TASK2 VISUAL --> TASK3 TASK2 --> TASK4 TASK3 --> TASK4 style CORE fill:#90EE90 style VALIDATE fill:#FFE4B5 style SENSITIVITY fill:#FFE4B5 style VISUAL fill:#FFE4B5 ``` ### ASCII版本(详细) ``` ┌─────────────────────────────────────────────────────────────────────────────────────────┐ │ TASK 1 完整流程 │ ├─────────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────────────────────────────────┐ │ │ │ 核心流程 [已完成 ✓] │ │ │ │ │ │ │ │ data.xlsx ──▶ 01_clean ──▶ 02_demand ──▶ 03_allocate ──▶ 04_evaluate │ │ │ │ correction │ │ │ │ │ ▼ │ │ │ │ 05_schedule │ │ │ └─────────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ │ ┌─────────────┴────────────┬───────────┴───────────┐ │ │ ▼ ▼ ▼ │ │ ┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐ │ │ │ 结果验证 [待完成 ⏳] │ │ 敏感性分析 [待完成 ⏳] │ │ 可视化 [待完成 ⏳] │ │ │ │ │ │ │ │ │ │ │ │ 06_validate.py │ │ 08_sensitivity.py │ │ 09_visualize.py │ │ │ │ ┌──────────────────┐ │ │ ┌──────────────────┐ │ │ ┌──────────────────┐ │ │ │ │ │• 约束满足检验 │ │ │ │• C ∈ {350,400,450}│ │ │ │• 站点地图(需求) │ │ │ │ │ │ - Σk=730? │ │ │ │• p阈值扫描 │ │ │ │• k分布直方图 │ │ │ │ │ │ - k≥1? │ │ │ │• C̄ ∈ {200,250,300}│ │ │ │• E-F权衡曲线 │ │ │ │ │ │ - 每日2站点? │ │ │ │ │ │ │ │• 日历热力图 │ │ │ │ │ └──────────────────┘ │ │ └──────────────────┘ │ │ │• 间隔分布箱线图 │ │ │ │ │ │ │ │ │ └──────────────────┘ │ │ │ │ 07_backtest.py │ │ 输出: │ │ │ │ │ │ ┌──────────────────┐ │ │ • 参数-指标表 │ │ 输出: │ │ │ │ │• 2019数据回测 │ │ │ • Pareto前沿图 │ │ • figures/*.png │ │ │ │ │• 预测vs实际对比 │ │ │ │ │ • 论文插图 │ │ │ │ │• 残差分析 │ │ │ │ │ │ │ │ │ └──────────────────┘ │ │ │ │ │ │ │ └──────────────────────┘ └──────────────────────┘ └──────────────────────┘ │ │ │ │ └────────────────────────────────────────┼───────────────────────────────────────────────┘ │ ▼ ┌────────────────────┴────────────────────┐ │ │ ▼ ▼ ┌──────────────────────────┐ ┌──────────────────────────┐ │ TASK 2: 天气响应 [待完成] │ │ TASK 3: 双站点 [待完成] │ └──────────────────────────┘ └──────────────────────────┘ │ │ └────────────────┬────────────────────────┘ ▼ ┌──────────────────────────┐ │ TASK 4: 执行摘要 [待完成] │ └──────────────────────────┘ ``` ### 当前进度与待完成事项 | 模块 | 状态 | 脚本 | 说明 | |------|------|------|------| | 数据清洗 | ✅ 完成 | `01_clean.py` | 字段标准化 | | 需求修正 | ✅ 完成 | `02_demand_correction.py` | 截断回归 | | 频次分配 | ✅ 完成 | `03_allocate.py` | Hamilton方法 | | 指标计算 | ✅ 完成 | `04_evaluate.py` | E1,E2,F1,F2 | | 日历排程 | ✅ 完成 | `05_schedule.py` | 贪心+局部优化 | | **约束验证** | ⏳ 待完成 | `06_validate.py` | 硬约束检验 | | **历史回测** | ⏳ 待完成 | `07_backtest.py` | 模型有效性 | | **敏感性分析** | ⏳ 待完成 | `08_sensitivity.py` | 参数稳健性 | | **可视化** | ⏳ 待完成 | `09_visualize.py` | 论文图表 | --- ## 运行结果摘要 | 指标 | 推荐方案 | 均匀分配 | 2019缩放 | 变化 | |------|---------|---------|---------|------| | E1 (总服务量) | **140,121** | 104,797 | 104,071 | +34.6% | | E2 (质量加权) | **131,673** | 101,309 | 100,264 | +31.3% | | F1 (Gini系数) | 0.314 | **0.026** | 0.092 | 公平性降低 | | F2 (最低满足率) | 2.0 | **8.4** | 5.0 | - | **核心发现**:按需求比例分配可提升34.6%的总服务量,但存在有效性-公平性权衡。 --- ## 1. 问题形式化 ### 1.1 输入数据 | 字段 | 符号 | 说明 | |------|------|------| | 位置 | $(lat_i, lon_i)$ | 经纬度坐标 | | 2019年访问次数 | $v_i$ | 历史频次,总计722次 | | 单次服务人数均值 | $\mu_i$ | 观测均值,范围[17.2, 396.6] | | 单次服务人数标准差 | $\sigma_i$ | 观测波动,范围[2.2, 93.5] | ### 1.2 运营参数 | 参数 | 值 | 来源 | |------|-----|------| | 卡车物理运力 | 15,000 lbs | 题面明确 | | 典型服务户数 | [200, 250] | 题面"typical" | | 每日可派车次 | 2 | 题面 | | 年度总访问次数 $N$ | 730 | $365 \times 2$ | ### 1.3 硬约束 $$\sum_{i=1}^{70} k_i = 730 \tag{C1: 资源约束}$$ $$k_i \geq 1 \tag{C2: 覆盖约束}$$ $$|\text{sites on day } t| = 2 \tag{C3: 每日容量}$$ --- ## 2. 阶段一:真实需求估计(截断回归) ### 2.1 问题本质:为什么需要修正? **底层逻辑**: 题面说"typical visit serves 200-250 families",但数据中 $\mu_{max} = 396.6$。这说明: 1. **200-250不是硬上限**:高需求站点可以服务更多家庭 2. **存在隐性容量约束**:卡车运力15000磅 ÷ 每户约38-75磅 ≈ 200-400户 3. **观测被截断**:当真实需求 > 容量时,只能观测到容量值 ``` 真实需求分布: 观测到的分布: │ │ │ ╱╲ │ ╱╲ │ ╱ ╲ │ ╱ ╲▓▓▓ ← 被截断部分 │ ╱ ╲ │ ╱ │ │ ╱ ╲ │ ╱ │ ├───────────── ├───────┤ 0 μ̃ C 0 μ C ``` **因此**:直接用 $\mu_i$ 会**系统性低估**高需求站点的真实需求。 ### 2.2 截断概率的推导 **假设**:真实需求 $\tilde{D}_i \sim \mathcal{N}(\tilde{\mu}_i, \sigma_i^2)$ **推导**:截断概率 = 真实需求超过容量C的概率 $$p_i^{trunc} = P(\tilde{D}_i > C) = P\left(Z > \frac{C - \tilde{\mu}_i}{\sigma_i}\right) = 1 - \Phi\left(\frac{C - \tilde{\mu}_i}{\sigma_i}\right)$$ **近似**:由于我们不知道 $\tilde{\mu}_i$,用观测值 $\mu_i$ 近似: $$p_i^{trunc} \approx 1 - \Phi\left(\frac{C - \mu_i}{\sigma_i}\right)$$ **物理意义**:$p_i^{trunc}$ 越大,说明该站点越可能被截断,需要更大的修正。 ### 2.3 修正公式的推导 **截断正态的条件期望**(Mills ratio): 对于 $X \sim \mathcal{N}(\mu, \sigma^2)$,有: $$E[X | X > c] = \mu + \sigma \cdot \frac{\phi\left(\frac{c-\mu}{\sigma}\right)}{1 - \Phi\left(\frac{c-\mu}{\sigma}\right)}$$ **简化近似**: 当截断概率 $p^{trunc}$ 较小时,修正量近似与 $p^{trunc}$ 线性相关: $$\tilde{\mu}_i \approx \mu_i \cdot (1 + \alpha \cdot p_i^{trunc})$$ 取 $\alpha = 0.4$(经验系数,可通过敏感性分析调整)。 **分段处理的原因**: - 当 $p^{trunc} < 0.02$:截断概率很低,修正量可忽略 - 当 $p^{trunc} \geq 0.02$:存在显著截断,需要修正 ### 2.4 实际修正结果 | site_id | 站点名称 | $\mu$ | $\sigma$ | $p^{trunc}$ | $\tilde{\mu}$ | 修正幅度 | |---------|---------|-------|----------|-------------|---------------|----------| | 66 | MFP Waverly | 396.6 | 51.9 | 0.474 | 471.9 | +19.0% | | 2 | MFP Avoca | 314.6 | 57.3 | 0.068 | 323.2 | +2.7% | | 13 | MFP College TC3 | 261.5 | 92.0 | 0.066 | 268.4 | +2.6% | | 17 | MFP Endwell | 285.2 | 60.8 | 0.030 | 288.6 | +1.2% | | 30 | MFP Redeemer | 230.6 | 93.5 | 0.035 | 233.8 | +1.4% | --- ## 3. 阶段二:频次分配模型 ### 3.1 分配原则的底层逻辑 **题面要求**:"frequency informed by total demand in surrounding communities" **问题**:什么是"周边社区需求"? **两种理解**: 1. ❌ 用空间核平滑估计(循环论证:用供给估计需求) 2. ✅ 每个站点本身就服务其周边社区,$\tilde{\mu}_i$ 就是需求代理 **我们的选择**:直接用修正后的 $\tilde{\mu}_i$ 作为"周边社区需求"的代理。 **为什么按比例分配?** 假设目标是**最大化总服务量**且**保证公平**: - 最大化 $\sum k_i \mu_i$ subject to $\sum k_i = N$ - 拉格朗日条件:$\frac{\partial}{\partial k_i}(k_i \mu_i - \lambda k_i) = \mu_i - \lambda = 0$ 这说明最优解是 $k_i \propto \mu_i$(或 $\tilde{\mu}_i$)。 ### 3.2 为什么用Hamilton方法? **问题**:按比例分配得到的是实数,需要转换为整数。 **Hamilton方法(最大余数法)的优点**: 1. **保证总和**:$\sum k_i = N$ 严格成立 2. **公平性**:余数大的站点优先获得额外1次 3. **可解释**:政治选举中广泛使用,逻辑透明 **替代方法对比**: | 方法 | 优点 | 缺点 | |------|------|------| | 四舍五入 | 简单 | 总和可能不等于N | | 向下取整+贪心 | 简单 | 可能不公平 | | Hamilton | 公平、总和准确 | 稍复杂 | | 整数规划 | 可加约束 | 过于复杂 | ### 3.3 分配结果验证 - 总访问次数:$\sum k_i = 730$ ✓ - 访问次数范围:$[2, 32]$ - 覆盖约束:$\min k_i = 2 \geq 1$ ✓ --- ## 4. 阶段三:效果评估指标 ### 4.1 有效性指标的设计逻辑 **E1:原始总服务量** $$E_1 = \sum_{i=1}^{70} k_i \cdot \mu_i$$ **问题**:E1假设服务量与访问次数线性增长,但忽略了**质量下降**。 **E2:质量加权服务量** **底层逻辑**:当 $\mu_i > 250$ 时,每户获得的食物量下降。 $$\text{每户食物量} = \frac{15000 \text{ lbs}}{\mu_i}$$ 当 $\mu_i = 250$ 时,每户60磅(典型值)。 当 $\mu_i = 400$ 时,每户37.5磅(低于典型)。 **质量折扣因子**: $$q(\mu) = \min\left(1, \frac{250}{\mu}\right) = \begin{cases} 1 & \mu \leq 250 \\ \frac{250}{\mu} & \mu > 250 \end{cases}$$ **物理意义**:$q(\mu)$ 表示"相对于典型服务质量的比例"。 ### 4.2 公平性指标的设计逻辑 **为什么不用"访问次数相等"衡量公平?** 题面说"are some served much better than others"——关键词是**served**,不是**visited**。 需求100的站点访问10次 vs 需求200的站点访问10次 → 后者服务不足。 **满足率的定义**: $$r_i = \frac{\text{年度服务量}}{\text{年度需求}} = \frac{k_i \cdot \mu_i}{\tilde{\mu}_i}$$ **为什么用Gini系数?** - Gini系数是衡量分布不均等的标准指标 - 取值[0,1],0表示完全均等,1表示完全不均等 - 易于解释:收入分配、资源分配广泛使用 ### 4.3 评估结果 | 方案 | E1 | E2 | F1 (Gini) | F2 (min r) | |------|-----|-----|-----------|------------| | **推荐方案** | **140,121** | **131,673** | 0.314 | 2.00 | | 均匀分配 | 104,797 | 101,309 | **0.026** | **8.41** | | 2019缩放 | 104,071 | 100,264 | 0.092 | 5.00 | **有效性-公平性权衡**: ``` F1 (Gini, 越小越公平) ▲ 0.4 │ ● 推荐方案 (E1=140k) │ 0.3 │ │ 0.2 │ │ 0.1 │ ● 2019缩放 (E1=104k) │ 0.0 │● 均匀分配 (E1=105k) └────────────────────────────▶ E1 (总服务量) 100k 120k 140k ``` --- ## 5. 阶段四:日历排程 ### 5.1 排程目标的底层逻辑 **为什么要均匀分布访问日期?** 题面说"schedule published months in advance to help clients plan"。 如果某站点访问间隔不均匀(如:1月5次,2月0次),客户难以规划。 **理想间隔**: $$\Delta_i^* = \frac{365}{k_i}$$ 例如:$k_i = 12$ 次/年 → 理想间隔 ≈ 30天/次 ### 5.2 贪心算法的设计逻辑 **为什么不用整数规划?** 730个访问事件 × 365天 = 26万个0-1变量,计算复杂度过高。 **贪心策略**: 1. 为每个访问事件计算"理想日期" 2. 按理想日期排序 3. 依次分配到最近的可用槽位 **为什么有效?** - 理想日期已经考虑了均匀分布 - 按顺序分配避免了冲突 - 局部优化可进一步改善 ### 5.3 排程结果 - 365天全部满载 ✓ - 平均间隔:55.4天 - 最大间隔:179天(低频站点) --- ## 6. 待完成:结果验证 ### 6.1 约束满足检验 (`06_validate.py`) | 检验项 | 公式 | 预期结果 | |--------|------|---------| | 资源约束 | $\sum k_i = 730$ | 通过 | | 覆盖约束 | $\min k_i \geq 1$ | 通过 | | 日容量约束 | 每日恰好2站点 | 通过 | | 无重复约束 | 同一天不重复访问同一站点 | 通过 | ### 6.2 模型有效性验证 (`07_backtest.py`) **方法**:留一交叉验证(Leave-One-Out) 1. 用2019年的69个站点数据训练模型 2. 预测第70个站点的 $\tilde{\mu}$ 和 $k$ 3. 与实际值对比 4. 重复70次,计算平均误差 **评估指标**: - MAPE(平均绝对百分比误差) - $R^2$(决定系数) --- ## 7. 待完成:敏感性分析 ### 7.1 参数扫描 (`08_sensitivity.py`) | 参数 | 基准值 | 扫描范围 | 影响 | |------|--------|---------|------| | 有效容量 $C$ | 400 | [350, 450] | 截断修正强度 | | 截断阈值 $p^{trunc}$ | 0.02 | [0.01, 0.10] | 修正站点数 | | 质量阈值 $\bar{C}$ | 250 | [200, 300] | E2计算 | ### 7.2 敏感性报告格式 ``` C = 350: 修正7站点, E1=141,234, F1=0.318 C = 400: 修正5站点, E1=140,121, F1=0.314 ← 基准 C = 450: 修正3站点, E1=139,456, F1=0.310 ``` --- ## 8. 待完成:可视化 ### 8.1 图表清单 (`09_visualize.py`) | 图编号 | 图名 | 类型 | 用途 | |--------|------|------|------| | Fig.1 | 站点地图 | 散点图+地图底图 | 展示站点分布和需求 | | Fig.2 | 需求修正对比 | 柱状图 | 展示修正前后μ变化 | | Fig.3 | 频次分配分布 | 直方图 | 展示k的分布 | | Fig.4 | 有效性-公平性权衡 | 散点图 | Pareto前沿 | | Fig.5 | 日历热力图 | 热力图 | 全年排程概览 | | Fig.6 | 访问间隔箱线图 | 箱线图 | 间隔分布 | | Fig.7 | 敏感性分析 | 折线图 | 参数影响 | ### 8.2 图表示例说明 **Fig.1 站点地图**: - X轴:经度 - Y轴:纬度 - 点大小:$\mu_i$(需求) - 点颜色:$k_i$(访问频次) **Fig.4 有效性-公平性权衡**: - X轴:E2(质量加权服务量) - Y轴:F1(Gini系数,越小越公平) - 多个方案的散点 - Pareto前沿曲线 **Fig.5 日历热力图**: - X轴:月份(1-12) - Y轴:日期(1-31) - 颜色:该日访问的站点需求总和 --- ## 9. 可复现流水线 ### 9.1 完整脚本结构 ``` task1/ ├── 01_clean.py ✅ 数据清洗 ├── 02_demand_correction.py ✅ 截断修正 ├── 03_allocate.py ✅ 频次分配 ├── 04_evaluate.py ✅ 指标计算 ├── 05_schedule.py ✅ 日历排程 ├── 06_validate.py ⏳ 约束验证 ├── 07_backtest.py ⏳ 历史回测 ├── 08_sensitivity.py ⏳ 敏感性分析 ├── 09_visualize.py ⏳ 可视化 ├── 01_clean.xlsx ├── 02_demand.xlsx ├── 03_allocate.xlsx ├── 04_metrics.xlsx ├── 05_schedule.xlsx └── figures/ ⏳ 图表输出目录 ``` ### 9.2 运行命令 ```bash # 核心流程(已完成) python task1/01_clean.py python task1/02_demand_correction.py python task1/03_allocate.py python task1/04_evaluate.py python task1/05_schedule.py # 验证与分析(待完成) python task1/06_validate.py python task1/07_backtest.py python task1/08_sensitivity.py python task1/09_visualize.py ``` --- ## 10. 假设与局限性 ### 10.1 显式假设 | 编号 | 假设 | 依据 | 影响 | |------|------|------|------| | A1 | 真实需求服从正态分布 | 中心极限定理 | 截断修正公式 | | A2 | 有效容量 $C=400$ | $\mu_{max}=396.6$ | 修正强度 | | A3 | 2021年需求≈2019年 | 题面要求 | 整体方案有效性 | | A4 | 全年365天运营 | 简化假设 | 总访问次数 | | A5 | 每日2站点硬约束 | 题面 | 排程可行性 | ### 10.2 局限性 1. **截断修正简化**:使用线性近似而非完整MLE 2. **需求外生性**:未建模"访问频次→需求"的反馈效应 3. **空间相关性**:未考虑相邻站点需求相关性 4. **季节性**:未考虑冬季需求下降 --- ## 11. 结论与建议 ### 11.1 方法论贡献 1. **截断偏误识别**:发现高需求站点 $\mu$ 被低估 2. **质量-数量权衡**:引入质量折扣因子 3. **满足率公平**:以服务充足度衡量公平 ### 11.2 对FBST的运营建议 1. **MFP Waverly**:需求异常高($k=32$),建议增派资源 2. **数据收集**:记录"被拒服务人数"以更准确估计需求 3. **动态调整**:季度末复盘,调整下季度排程 ### 11.3 有效性-公平性权衡 推荐方案牺牲公平性换取服务量最大化。若FBST优先考虑公平: - 可设置 $k_i$ 上下限约束 - 或使用混合目标函数 $\max (E_2 - \lambda \cdot F_1)$