diff --git a/task1/README.md b/task1/README.md
index 615d645..58629d5 100644
--- a/task1/README.md
+++ b/task1/README.md
@@ -14,129 +14,136 @@
## 整体流程图
+### 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 │ 70站点: 位置、2019访问次数、μ、σ │
-│ └──────┬──────┘ │
-└───────────┼─────────────────────────────────────────────────────────────────────────────┘
- │
- ▼
-┌─────────────────────────────────────────────────────────────────────────────────────────┐
-│ TASK 1: 基础排程 [已完成 ✓] │
-│ │
-│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
-│ │ 01_clean.py │────▶│02_demand_ │────▶│03_allocate.py│────▶│04_evaluate.py│ │
-│ │ │ │correction.py │ │ │ │ │ │
-│ │ 数据清洗 │ │ 截断回归修正 │ │ Hamilton分配 │ │ 指标计算 │ │
-│ └──────────────┘ └──────────────┘ └──────────────┘ └──────┬───────┘ │
-│ │ │ │ │ │
-│ ▼ ▼ ▼ ▼ │
-│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
-│ │01_clean.xlsx │ │02_demand.xlsx│ │03_allocate. │ │04_metrics. │ │
-│ │ │ │ μ̃ (5站点修正)│ │xlsx (k分配) │ │xlsx │ │
-│ └──────────────┘ └──────────────┘ └──────┬───────┘ └──────────────┘ │
-│ │ │
-│ ▼ │
-│ ┌──────────────┐ │
-│ │05_schedule.py│ │
-│ │ 日历排程生成 │ │
-│ └──────┬───────┘ │
-│ │ │
-│ ▼ │
-│ ┌──────────────┐ │
-│ │05_schedule. │ │
-│ │xlsx (365天) │ │
-│ └──────┬───────┘ │
-└─────────────────────────────────────────────────────┼───────────────────────────────────┘
- │
- ┌─────────────────────────────────────────┴─────────────────────────────────┐
- │ │
- ▼ ▼
-┌───────────────────────────────────────────┐ ┌───────────────────────────────────────────┐
-│ TASK 2: 天气响应调度 [待完成] │ │ TASK 3: 双站点同车 [待完成] │
-│ │ │ │
-│ 选项 2a: 减少站点数 + 优化位置 │ │ ┌─────────────────────────────────────┐ │
-│ ┌─────────────────────────────────────┐ │ │ │ 1. 共生站点筛选 │ │
-│ │ • 站点聚类 (K-means/层次聚类) │ │ │ │ • 距离约束: dist(i,j) < D_max │ │
-│ │ • 确定最优站点数 K < 70 │ │ │ │ • 需求约束: μ_i + μ_j ≤ 400 │ │
-│ │ • 客户愿意多走的距离建模 │ │ │ │ • 稳定性约束: CV_i, CV_j < 阈值 │ │
-│ │ • 重新分配频次 │ │ │ └─────────────────────────────────────┘ │
-│ └─────────────────────────────────────┘ │ │ │ │
-│ 或 │ │ ▼ │
-│ 选项 2b: 保持70站点 + 优化时间协调 │ │ ┌─────────────────────────────────────┐ │
-│ ┌─────────────────────────────────────┐ │ │ │ 2. 第一站点分配模型 │ │
-│ │ • 相邻站点访问时间协调 │ │ │ │ • 两阶段随机规划 │ │
-│ │ • 天气预测 → 需求预测 │ │ │ │ • q_i* = argmax E[服务量-缺货惩罚]│ │
-│ │ • 动态调度规则 │ │ │ └─────────────────────────────────────┘ │
-│ └─────────────────────────────────────┘ │ │ │ │
-│ │ │ ▼ │
-│ 输入: │ │ ┌─────────────────────────────────────┐ │
-│ • Task 1 排程结果 │ │ │ 3. 频次重分配 │ │
-│ • 历史天气数据 (如有) │ │ │ • 共生站点合并需求 │ │
-│ • 站点间距离矩阵 │ │ │ • Hamilton方法重新分配 │ │
-│ │ │ └─────────────────────────────────────┘ │
-│ 输出: │ │ │ │
-│ • 改进后的排程方案 │ │ ▼ │
-│ • 性能提升量化 │ │ ┌─────────────────────────────────────┐ │
-│ │ │ │ 4. 日历排程 + 对比评估 │ │
-└───────────────────────────────────────────┘ │ │ • 与 Task 1 对比 E1, E2, F1, F2 │ │
- │ └─────────────────────────────────────┘ │
- │ │
- │ 输入: │
- │ • Task 1 分配结果 (03_allocate.xlsx) │
- │ • 站点距离矩阵 │
- │ │
- │ 输出: │
- │ • 共生站点配对表 │
- │ • 第一站点分配方案 │
- │ • 新日历排程 │
- └───────────────────────────────────────────┘
- │
- ▼
-┌─────────────────────────────────────────────────────────────────────────────────────────┐
-│ TASK 4: Executive Summary [待完成] │
-│ │
-│ ┌─────────────────────────────────────────────────────────────────────────────────┐ │
-│ │ 1页执行摘要: │ │
-│ │ • Task 1 方案优势: 总服务量提升 34.6% │ │
-│ │ • Task 2/3 改进效果量化 │ │
-│ │ • 对 FBST 的关键建议 │ │
-│ │ • 方法论局限性说明 │ │
-│ └─────────────────────────────────────────────────────────────────────────────────┘ │
-└─────────────────────────────────────────────────────────────────────────────────────────┘
+│ ┌─────────────────────────────────────────────────────────────────────────────────┐ │
+│ │ 核心流程 [已完成 ✓] │ │
+│ │ │ │
+│ │ 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: 执行摘要 [待完成] │
+ └──────────────────────────┘
```
-### 当前进度
+### 当前进度与待完成事项
-| 任务 | 状态 | 说明 |
-|------|------|------|
-| Task 1 | ✅ 已完成 | 基础排程方案,5个脚本全部运行通过 |
-| Task 2 | ⏳ 待开始 | 天气响应调度(选择2a或2b之一)|
-| Task 3 | ⏳ 待开始 | 双站点同车分配优化 |
-| Task 4 | ⏳ 待开始 | 1页执行摘要 |
-
-### 下一步操作
-
-```
-1. [Task 2 或 Task 3] 根据题目要求选择完成其一
- │
- ├─▶ 若选 Task 2:
- │ • 计算站点间距离矩阵
- │ • 选择 2a(减站点) 或 2b(优化时间)
- │ • 实现并量化改进
- │
- └─▶ 若选 Task 3:
- • 筛选共生站点配对
- • 建立第一站点分配模型
- • 生成新排程并对比评估
-
-2. [Task 4] 撰写1页执行摘要
- • 汇总 Task 1 + (Task 2 或 Task 3) 结果
- • 突出方法优势与建议
-```
+| 模块 | 状态 | 脚本 | 说明 |
+|------|------|------|------|
+| 数据清洗 | ✅ 完成 | `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` | 论文图表 |
---
@@ -157,8 +164,6 @@
### 1.1 输入数据
-对 $n=70$ 个站点,数据提供:
-
| 字段 | 符号 | 说明 |
|------|------|------|
| 位置 | $(lat_i, lon_i)$ | 经纬度坐标 |
@@ -166,364 +171,417 @@
| 单次服务人数均值 | $\mu_i$ | 观测均值,范围[17.2, 396.6] |
| 单次服务人数标准差 | $\sigma_i$ | 观测波动,范围[2.2, 93.5] |
-### 1.2 运营参数(题面提取)
+### 1.2 运营参数
-| 参数 | 符号 | 值 | 来源 |
-|------|------|-----|------|
-| 卡车物理运力 | $W$ | 15,000 lbs | 题面明确 |
-| 典型服务户数 | $[\underline{C}, \bar{C}]$ | [200, 250] | 题面"typical" |
-| 每日可派车次 | - | 2 | 题面"2 trucks any given day" |
-| 全年运营天数 | $T$ | 365 | 假设全年运营 |
-| 年度总访问次数 | $N$ | 730 | $= 2 \times 365$ |
+| 参数 | 值 | 来源 |
+|------|-----|------|
+| 卡车物理运力 | 15,000 lbs | 题面明确 |
+| 典型服务户数 | [200, 250] | 题面"typical" |
+| 每日可派车次 | 2 | 题面 |
+| 年度总访问次数 $N$ | 730 | $365 \times 2$ |
-### 1.3 决策变量
+### 1.3 硬约束
-- $k_i \in \mathbb{Z}^+$:站点 $i$ 的年度访问次数
-- $\mathcal{S}_i = \{t_{i,1}, ..., t_{i,k_i}\}$:站点 $i$ 的具体访问日期
-
-### 1.4 硬约束
-
-$$\sum_{i=1}^{70} k_i = N = 730 \tag{C1: 资源约束}$$
-
-$$k_i \geq 1, \quad \forall i \in [1,70] \tag{C2: 覆盖约束}$$
-
-$$|\{i : t \in \mathcal{S}_i\}| = 2, \quad \forall t \in [1, 365] \tag{C3: 每日2站点}$$
+$$\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 关键数据观察
+### 2.1 问题本质:为什么需要修正?
-分析70个站点的 $\mu_i$ 分布:
+**底层逻辑**:
-| 统计量 | 值 |
-|--------|-----|
-| $\mu > 250$ 的站点数 | 9 |
-| $\mu_{max}$ | 396.6 (MFP Waverly) |
-| $\mu$ 第二高 | 314.6 (MFP Avoca) |
-| $\mu$ 第三高 | 285.3 (MFP Endwell) |
-| $\mu$ 均值 | 141.4 |
+题面说"typical visit serves 200-250 families",但数据中 $\mu_{max} = 396.6$。这说明:
-**结论**:题面"200-250户"是"typical"而非硬上限。高需求站点通过减少每户分配量实现超额服务。
+1. **200-250不是硬上限**:高需求站点可以服务更多家庭
+2. **存在隐性容量约束**:卡车运力15000磅 ÷ 每户约38-75磅 ≈ 200-400户
+3. **观测被截断**:当真实需求 > 容量时,只能观测到容量值
-### 2.2 观测机制建模
+```
+真实需求分布: 观测到的分布:
+ │ │
+ │ ╱╲ │ ╱╲
+ │ ╱ ╲ │ ╱ ╲▓▓▓ ← 被截断部分
+ │ ╱ ╲ │ ╱ │
+ │ ╱ ╲ │ ╱ │
+ ├───────────── ├───────┤
+ 0 μ̃ C 0 μ C
+```
-**核心假设**:观测到的 $\mu_i$ 是真实需求 $\tilde{\mu}_i$ 在服务容量约束下的截断观测。
+**因此**:直接用 $\mu_i$ 会**系统性低估**高需求站点的真实需求。
-设单次服务的有效容量上限为 $C$(取 $C = 400$,略高于 $\mu_{max}$)。
+### 2.2 截断概率的推导
-$$\mu_i = E[\min(\tilde{D}_i, C)]$$
+**假设**:真实需求 $\tilde{D}_i \sim \mathcal{N}(\tilde{\mu}_i, \sigma_i^2)$
-其中 $\tilde{D}_i \sim \mathcal{N}(\tilde{\mu}_i, \tilde{\sigma}_i^2)$ 是站点 $i$ 的真实单次需求。
+**推导**:截断概率 = 真实需求超过容量C的概率
-### 2.3 截断修正公式
+$$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)$$
-**Step 1**:计算截断概率代理
+**近似**:由于我们不知道 $\tilde{\mu}_i$,用观测值 $\mu_i$ 近似:
-$$p_i^{trunc} = 1 - \Phi\left(\frac{C - \mu_i}{\sigma_i}\right)$$
+$$p_i^{trunc} \approx 1 - \Phi\left(\frac{C - \mu_i}{\sigma_i}\right)$$
-**Step 2**:分段修正(阈值 $p^{trunc} \geq 0.02$)
+**物理意义**:$p_i^{trunc}$ 越大,说明该站点越可能被截断,需要更大的修正。
-$$\tilde{\mu}_i = \begin{cases}
-\mu_i & \text{if } p_i^{trunc} < 0.02 \\[8pt]
-\mu_i \cdot (1 + 0.4 \cdot p_i^{trunc}) & \text{if } p_i^{trunc} \geq 0.02
-\end{cases}$$
+### 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 实际修正结果
-采用阈值 $p^{trunc} \geq 0.02$,共5个站点被修正:
-
| 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 United Methodist | 285.2 | 60.8 | 0.030 | 288.6 | +1.2% |
-| 30 | MFP Redeemer Lutheran | 230.6 | 93.5 | 0.035 | 233.8 | +1.4% |
-
-**修正前后对比**:
-- 修正前 $\sum \mu_i$ = 9,899.9
-- 修正后 $\sum \tilde{\mu}_i$ = 9,997.2
-- 增幅:+0.98%
+| 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 分配原则
+### 3.1 分配原则的底层逻辑
-**核心思想**:按真实需求 $\tilde{\mu}_i$ 比例分配访问次数。
+**题面要求**:"frequency informed by total demand in surrounding communities"
-$$k_i = 1 + \text{Hamilton}\left(N - 70, \; w_i = \tilde{\mu}_i\right)$$
+**问题**:什么是"周边社区需求"?
-其中:
-- 先给每个站点分配1次(满足覆盖约束C2)
-- 剩余 $N - 70 = 660$ 次按权重 $\tilde{\mu}_i$ 做整数分配
+**两种理解**:
+1. ❌ 用空间核平滑估计(循环论证:用供给估计需求)
+2. ✅ 每个站点本身就服务其周边社区,$\tilde{\mu}_i$ 就是需求代理
-### 3.2 Hamilton方法(最大余数法)
+**我们的选择**:直接用修正后的 $\tilde{\mu}_i$ 作为"周边社区需求"的代理。
-```python
-def hamilton_allocation(total: int, weights: list) -> list:
- n = len(weights)
- w_sum = sum(weights)
- quotas = [total * w / w_sum for w in weights]
- floors = [int(q) for q in quotas]
- remainders = [q - f for q, f in zip(quotas, floors)]
- leftover = total - sum(floors)
- indices = sorted(range(n), key=lambda i: -remainders[i])
- for i in indices[:leftover]:
- floors[i] += 1
- return floors
-```
+**为什么按比例分配?**
-### 3.3 实际分配结果
+假设目标是**最大化总服务量**且**保证公平**:
+
+- 最大化 $\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]$
-- 最小访问次数:2(满足覆盖约束)
-
-**访问次数分布**:
-
-```
-k = 2: 1 个站点 █
-k = 3: 14 个站点 ██████████████
-k = 4: 2 个站点 ██
-k = 5: 4 个站点 ████
-k = 6: 4 个站点 ████
-k = 8: 1 个站点 █
-k = 9: 3 个站点 ███
-k = 10: 3 个站点 ███
-k = 11: 6 个站点 ██████
-k = 12: 5 个站点 █████
-k = 13: 6 个站点 ██████
-k = 14: 5 个站点 █████
-k = 15: 4 个站点 ████
-k = 16: 2 个站点 ██
-k = 17: 1 个站点 █
-k = 18: 2 个站点 ██
-k = 19: 4 个站点 ████
-k = 20: 1 个站点 █
-k = 22: 1 个站点 █
-k = 32: 1 个站点 █
-```
-
-**频次最高的10个站点**:
-
-| site_id | 站点名称 | $\mu$ | $\tilde{\mu}$ | $k$ | 年度服务量 |
-|---------|---------|-------|---------------|-----|-----------|
-| 66 | MFP Waverly | 396.6 | 471.9 | 32 | 12,692 |
-| 2 | MFP Avoca | 314.6 | 323.2 | 22 | 6,921 |
-| 17 | MFP Endwell United Methodist | 285.3 | 288.6 | 20 | 5,705 |
-| 3 | MFP Bath | 279.5 | 279.5 | 19 | 5,310 |
-| 13 | MFP College TC3 | 261.5 | 268.4 | 19 | 4,969 |
-| 28 | MFP Rathbone | 269.1 | 269.1 | 19 | 5,113 |
-| 32 | MFP Richford | 265.9 | 265.9 | 19 | 5,052 |
-| 11 | MFP College Corning | 251.0 | 251.0 | 18 | 4,518 |
-| 62 | MFP The Love Church | 259.3 | 259.3 | 18 | 4,668 |
-| 31 | MFP Rehoboth Deliverance | 235.9 | 235.9 | 17 | 4,010 |
+- 覆盖约束:$\min k_i = 2 \geq 1$ ✓
---
## 4. 阶段三:效果评估指标
-### 4.1 有效性指标
+### 4.1 有效性指标的设计逻辑
**E1:原始总服务量**
$$E_1 = \sum_{i=1}^{70} k_i \cdot \mu_i$$
+**问题**:E1假设服务量与访问次数线性增长,但忽略了**质量下降**。
+
**E2:质量加权服务量**
-$$E_2 = \sum_{i=1}^{70} k_i \cdot \mu_i \cdot q(\mu_i), \quad q(\mu) = \min\left(1, \frac{250}{\mu}\right)$$
+**底层逻辑**:当 $\mu_i > 250$ 时,每户获得的食物量下降。
-### 4.2 公平性指标
+$$\text{每户食物量} = \frac{15000 \text{ lbs}}{\mu_i}$$
-**定义满足率**:
+当 $\mu_i = 250$ 时,每户60磅(典型值)。
+当 $\mu_i = 400$ 时,每户37.5磅(低于典型)。
-$$r_i = \frac{k_i \cdot \mu_i}{\tilde{\mu}_i}$$
+**质量折扣因子**:
-- **F1**:满足率基尼系数 $\text{Gini}(\mathbf{r})$
-- **F2**:最差站点满足率 $\min_i r_i$
-- **F3**:满足率变异系数 $CV_r$
+$$q(\mu) = \min\left(1, \frac{250}{\mu}\right) = \begin{cases} 1 & \mu \leq 250 \\ \frac{250}{\mu} & \mu > 250 \end{cases}$$
-### 4.3 实际评估结果
+**物理意义**:$q(\mu)$ 表示"相对于典型服务质量的比例"。
-| 方案 | E1 | E2 | F1 (Gini) | F2 (min r) | F3 (CV) |
-|------|-----|-----|-----------|------------|---------|
-| **推荐方案** (μ̃比例) | **140,120.6** | **131,673.2** | 0.314 | 2.00 | 0.561 |
-| 基线1: 均匀分配 | 104,797.3 | 101,308.9 | **0.026** | **8.41** | **0.052** |
-| 基线2: 2019缩放 | 104,070.7 | 100,263.8 | 0.092 | 5.00 | 0.177 |
-| 基线3: μ比例(无修正) | 139,129.2 | 131,397.1 | 0.311 | 2.00 | 0.550 |
+### 4.2 公平性指标的设计逻辑
-**推荐方案优势**:
-- 相对均匀分配:E1 +33.7%,E2 +30.0%
-- 相对2019缩放:E1 +34.6%,E2 +31.3%
+**为什么不用"访问次数相等"衡量公平?**
-**有效性-公平性权衡**:推荐方案最大化了总服务量,但公平性(Gini系数)较差。这是按需求比例分配的固有特性。
+题面说"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 目标
+### 5.1 排程目标的底层逻辑
-将 $\{k_i\}_{i=1}^{70}$ 转化为365天日历,满足每日2站点约束,并最小化访问间隔的不均匀性。
+**为什么要均匀分布访问日期?**
-### 5.2 算法:贪心装箱 + 局部优化
+题面说"schedule published months in advance to help clients plan"。
-1. **生成理想日期**:$t_{i,j}^* = \text{round}\left(\frac{(j + 0.5) \cdot 365}{k_i}\right)$
-2. **贪心分配**:按理想日期排序,就近分配到可用槽位
-3. **局部优化**:随机交换站点,若改善间隔方差则接受
+如果某站点访问间隔不均匀(如:1月5次,2月0次),客户难以规划。
-### 5.3 实际排程结果
+**理想间隔**:
-**验证**:
-- 已分配访问事件:730 / 730 ✓
-- 日历统计:365天满载 + 0天部分 + 0天空闲 ✓
-- 局部优化:5000次迭代,接受33次改进
+$$\Delta_i^* = \frac{365}{k_i}$$
-**间隔统计**:
+例如:$k_i = 12$ 次/年 → 理想间隔 ≈ 30天/次
-| 指标 | 值 |
-|------|-----|
-| 平均间隔均值 | 55.4 天 |
-| 平均间隔标准差 | 3.2 天 |
-| 最大单次间隔 | 179 天 |
-| 平均间隔CV | 0.103 |
+### 5.2 贪心算法的设计逻辑
-**日历预览(前10天)**:
+**为什么不用整数规划?**
-| 日期 | 站点1 | 站点2 |
-|------|-------|-------|
-| 1 | MFP Avoca | MFP Waverly |
-| 2 | MFP Van Etten | MFP Endwell United Methodist |
-| 3 | MFP Bath | MFP Richford |
-| 4 | MFP College Corning | MFP College TC3 |
-| 5 | MFP Rehoboth Deliverance | MFP Rathbone |
-| 6 | MFP Waverly | MFP Redeemer Lutheran |
-| 7 | MFP The Love Church | MFP Lindley |
-| 8 | MFP Tuscarora | MFP Woodhull |
-| 9 | MFP Endwell United Methodist | MFP Richford |
-| 10 | MFP Bath | MFP College Corning |
+730个访问事件 × 365天 = 26万个0-1变量,计算复杂度过高。
+
+**贪心策略**:
+
+1. 为每个访问事件计算"理想日期"
+2. 按理想日期排序
+3. 依次分配到最近的可用槽位
+
+**为什么有效?**
+
+- 理想日期已经考虑了均匀分布
+- 按顺序分配避免了冲突
+- 局部优化可进一步改善
+
+### 5.3 排程结果
+
+- 365天全部满载 ✓
+- 平均间隔:55.4天
+- 最大间隔:179天(低频站点)
---
-## 6. 可复现流水线
+## 6. 待完成:结果验证
-### 6.1 脚本结构
+### 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 # Hamilton频次分配
-├── 04_evaluate.py # 评估指标计算
-├── 05_schedule.py # 日历排程生成
-├── 01_clean.xlsx # Step 1 输出
-├── 02_demand.xlsx # Step 2 输出
-├── 03_allocate.xlsx # Step 3 输出
-├── 04_metrics.xlsx # Step 4 输出
-└── 05_schedule.xlsx # Step 5 输出
+├── 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/ ⏳ 图表输出目录
```
-### 6.2 运行方法
+### 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
```
-### 6.3 关键参数
+---
-| 参数 | 值 | 位置 |
-|------|-----|------|
-| 有效容量上限 $C$ | 400 | `02_demand_correction.py` |
-| 截断概率阈值 | 0.02 | `02_demand_correction.py` |
-| 质量折扣阈值 $\bar{C}$ | 250 | `04_evaluate.py` |
-| 年度总访问次数 $N$ | 730 | `03_allocate.py` |
-| 全年天数 $T$ | 365 | `05_schedule.py` |
+## 10. 假设与局限性
-### 6.4 输出文件说明
+### 10.1 显式假设
-| 文件 | 内容 |
-|------|------|
-| `01_clean.xlsx` | 标准化数据:site_id, site_name, lat, lon, visits_2019, mu, sigma |
-| `02_demand.xlsx` | 需求修正:+ mu_tilde, p_trunc, is_corrected |
-| `03_allocate.xlsx` | 频次分配:+ k, annual_service, r |
-| `04_metrics.xlsx` | 评估指标:metrics_summary, site_details, parameters |
-| `05_schedule.xlsx` | 日历排程:calendar, site_dates, gap_statistics, parameters |
+| 编号 | 假设 | 依据 | 影响 |
+|------|------|------|------|
+| A1 | 真实需求服从正态分布 | 中心极限定理 | 截断修正公式 |
+| A2 | 有效容量 $C=400$ | $\mu_{max}=396.6$ | 修正强度 |
+| A3 | 2021年需求≈2019年 | 题面要求 | 整体方案有效性 |
+| A4 | 全年365天运营 | 简化假设 | 总访问次数 |
+| A5 | 每日2站点硬约束 | 题面 | 排程可行性 |
+
+### 10.2 局限性
+
+1. **截断修正简化**:使用线性近似而非完整MLE
+2. **需求外生性**:未建模"访问频次→需求"的反馈效应
+3. **空间相关性**:未考虑相邻站点需求相关性
+4. **季节性**:未考虑冬季需求下降
---
-## 7. 敏感性分析
+## 11. 结论与建议
-### 7.1 参数范围
+### 11.1 方法论贡献
-| 参数 | 符号 | 基准值 | 敏感性范围 |
-|------|------|--------|-----------|
-| 有效容量 | $C$ | 400 | {350, 400, 450} |
-| 截断概率阈值 | $p^{trunc}$ | 0.02 | {0.01, 0.02, 0.05, 0.10} |
-| 典型服务量 | $\bar{C}$ | 250 | {200, 250, 300} |
+1. **截断偏误识别**:发现高需求站点 $\mu$ 被低估
+2. **质量-数量权衡**:引入质量折扣因子
+3. **满足率公平**:以服务充足度衡量公平
-### 7.2 阈值敏感性
+### 11.2 对FBST的运营建议
-| 阈值 | 被修正站点数 | $\sum \tilde{\mu}$ 增幅 |
-|------|-------------|----------------------|
-| 0.01 | 7 | +1.2% |
-| 0.02 | 5 | +0.98% |
-| 0.05 | 2 | +0.82% |
-| 0.10 | 1 | +0.76% |
+1. **MFP Waverly**:需求异常高($k=32$),建议增派资源
+2. **数据收集**:记录"被拒服务人数"以更准确估计需求
+3. **动态调整**:季度末复盘,调整下季度排程
----
+### 11.3 有效性-公平性权衡
-## 8. 假设与局限性
-
-### 8.1 显式假设
-
-| 编号 | 假设 | 依据 |
-|------|------|------|
-| A1 | 真实需求服从正态分布 | 中心极限定理 |
-| A2 | 有效容量 $C=400$ | 基于 $\mu_{max}=396.6$ |
-| A3 | 2021年需求结构与2019年相似 | 题面要求使用2019数据 |
-| A4 | 全年365天均可运营 | 简化假设 |
-| A5 | 每日2站点为硬约束 | 题面"2 trucks" |
-
-### 8.2 局限性
-
-1. **截断修正的简化**:采用线性近似而非完整截断正态MLE
-2. **需求外生性**:未建模"访问频次影响需求"的内生效应
-3. **空间相关性**:未考虑相邻站点需求的空间自相关
-4. **季节性**:未考虑需求的季节波动(如冬季低需求)
-
----
-
-## 9. 结论与建议
-
-### 9.1 方法论贡献
-
-1. **识别截断偏误**:通过数据分析发现高需求站点的 $\mu$ 被容量截断,提出截断回归修正
-2. **质量-数量权衡**:引入质量折扣因子 $q(\mu)$,避免简单最大化服务人次
-3. **满足率公平**:以需求满足率而非访问次数衡量公平
-
-### 9.2 对FBST的建议
-
-1. **高需求站点**:MFP Waverly ($k=32$) 需求远超其他站点,建议考虑增派车辆或设立分站
-2. **数据收集**:建议记录"被拒绝服务的客户数"以更准确估计真实需求
-3. **动态调整**:建议季度末根据实际服务数据调整下季度排程
-
-### 9.3 有效性-公平性权衡
-
-推荐方案在有效性(总服务量)上显著优于基线,但公平性较差。若FBST更重视公平性,可考虑:
-- 混合方案:在推荐方案基础上,对低频站点适当增加访问
-- Pareto优化:在有效性-公平性前沿上选择平衡点
-
-### 9.4 后续研究方向
-
-- **Task 2**:考虑天气对需求的影响,建立动态调度模型
-- **Task 3**:双站点同车访问的最优分配策略
+推荐方案牺牲公平性换取服务量最大化。若FBST优先考虑公平:
+- 可设置 $k_i$ 上下限约束
+- 或使用混合目标函数 $\max (E_2 - \lambda \cdot F_1)$