Files
mcm-mfp/task1/README.md
2026-01-19 01:40:19 +08:00

109 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Task 12021 年 MFP 计划)——可审计建模与排程(论文式说明)
## 摘要
本文给出一套在“仅有站点经纬度、2019 年访问次数、单次到访人数均值/标准差”的数据条件下,仍然**闭环、可复现、可审计**的 2021 年 MFP 访问频次与全年日历排程方案。方案遵循三层结构:
(1) 用空间核平滑把“周边社区总需求”落地为站点邻域需求代理;
(2) 在给定全年总访问次数约束下分配每个站点年度访问次数;
(3) 将年度次数转换为 2021 年逐日(每天 2 个站点)可发布的排程日历。
本文严格采用题面确认的运营情景:**每天 2 个站点、全年 365 天运营、总访问次数 `N_total=730`、必须覆盖全部 70 个站点、且不建单次容量上限**。
## 1. 问题与数据
### 1.1 输入数据(`data.xlsx`
对每个站点 `i=1..70`,数据给出:
- 位置:`(lat_i, lon_i)`
- 2019 年访问次数:`v_i^{2019}`
- 单次到访人数统计量:均值 `μ_i`、标准差 `σ_i`(单位为 “clients per visit”按题面口径理解
### 1.2 决策变量与约束
我们需要为 2021 年决策每个站点年度访问次数 `k_i`,并生成逐日排程。
- 覆盖约束(题面/用户确认):`k_i >= 1`
- 总资源约束(情景 B`Σ_i k_i = N_total = 730`= 365 天 × 2 站点/天)
## 2. “周边社区总需求”的可审计代理
题面要求“频次由周边社区总需求指导”,但数据没有社区人口/贫困率等外部字段,因此我们将其定义为**可审计的空间平滑代理**。
### 2.1 距离
使用 haversine 距离 `dist(i,j)`(英里)。
### 2.2 高斯核平滑(核心)
给定尺度参数 `ρ`(英里),定义站点 i 的邻域需求代理:
`D_i(ρ) = Σ_j μ_j · exp( - dist(i,j)^2 / (2ρ^2) )`
含义:越近的站点对“周边需求”贡献越大,且贡献按距离平滑衰减;`ρ` 越大表示“更大范围的周边”。
### 2.3 敏感性分析
本文默认同时计算 `ρ ∈ {10, 20, 30}` miles 三个情景,用于审计“周边”尺度选择对结果的影响。
## 3. 年度频次分配:有效性与公平性
### 3.1 有效性Effectiveness
用户确认“不建单次容量上限”,因此总体服务量(期望)可用下式作为有效性代理:
`Eff = Σ_i k_i · μ_i`
该指标等价于:假设单次服务量随到访人数线性增长,且不考虑单次运力/食品上限截断。
### 3.2 公平性Fairness服务水平而非次数
题面“served much better”更自然地对应“服务水平/满足率”而非“访问次数相等”。
我们定义站点 i 的服务水平(对邻域需求的相对供给)为:
`S_i(ρ) = (k_i · μ_i) / D_i(ρ)`
然后用两类审计指标衡量不均等:
- `min_i S_i(ρ)`最弱站点的服务水平max-min 视角)
- `Gini({S_i(ρ)})`:服务水平分布的不均等程度(标准 Gini 公式)
### 3.3 分配规则(主推荐:按周边需求比例分配)
在覆盖约束 `k_i>=1` 下,我们采用**按周边需求代理 `D_i(ρ)` 比例分配剩余次数**
1) 先给每站点 1 次:`k_i := 1`
2) 将剩余 `R = N_total - 70` 次按权重 `w_i = D_i(ρ)` 做整数分配largest remainder / Hamilton 方法):
- 连续目标:`k_i ≈ 1 + R · w_i/Σw`
- 再通过取整与余数分配保证 `Σk_i=N_total`
该规则的解释性很强:**周边需求越大,年度访问越多**,且覆盖约束保证所有站点至少一次。
### 3.4 基线与对比
为可审计地量化改进输出中包含“2019 访问次数按比例缩放到 730 次”的基线(`baseline_2019_scaled`),并在同一套指标下对比:
- 总有效性 `Σ k_i μ_i`
- 公平性 `Gini(S)``min S`
## 4. 排程层(何时去):将 `k_i` 变成 2021 日历
目标:把每站点年度次数转成可发布的具体日期,同时保证每天正好 2 个不同站点。
### 4.1 均匀间隔的目标日期
对站点 i 的第 `j` 次访问(`j=0..k_i-1`设理想目标日1..365)为:
`t_{i,j} = round( (j+0.5) · 365 / k_i )`
直观含义:尽量均匀地把 `k_i` 次撒在全年。
### 4.2 装箱与修复
先按 `t_{i,j}` 把访问事件放入对应日期桶若某天超过容量2 个站点)或出现同一站点重复,则将溢出事件移动到最接近的仍有空位且不重复的日期,直至:
- 每天正好 2 个站点
- 每天两站点不同
- 总计 730 个事件全部入日历
输出同时给出每站点相邻访问间隔的统计(最大/均值/标准差),用于审计“服务连续性”。
## 5. 可复现流水线(脚本 + xlsx 传输)
按步骤运行(从项目根目录):
1) `python task1/01_clean.py``task1/01_clean.xlsx`(标准化字段、补 `site_id`
2) `python task1/02_neighbor_demand.py``task1/02_neighbor.xlsx``D_i(ρ)` 与距离矩阵)
3) `python task1/03_allocate_k.py``task1/03_allocate.xlsx`(多种分配方法 + 指标对比)
4) `python task1/04_schedule_2021.py``task1/04_schedule.xlsx`2021 日历排程;默认 `ρ=20mi` + `proportional_D`
### 5.1 关键输出表
- `task1/03_allocate.xlsx`:
- `allocations`:每站点的 `k_i` 以及对应 `S_i(ρ)`(按不同 `ρ`/方法)
- `metrics`:每种方法/情景的有效性与公平性汇总
- `task1/04_schedule.xlsx`:
- `meta`:排程采用的 `ρ` 与方法列名
- `calendar`:每天两个站点(可直接发布的日历)
- `site_dates`:每站点的具体日期列表
- `gap_metrics`:每站点访问间隔统计(连续性审计)
## 6. 假设与局限(必须在正文显式声明)
- 由于用户确认“不建单次容量上限”,本文未建模单次运力/食品约束,也无法估计缺供概率;有效性以 `Σ k_i μ_i` 作为线性代理。
- `μ_i, σ_i` 被视为“真实到访需求”的代理统计量;若历史存在供给截断,则高需求站点可能被系统性低估(需在后续任务中引入容量或外部数据修正)。
- “周边需求”完全由站点间空间平滑构造;`ρ` 的选择需要与 FBST 对“可接受出行半径”的运营经验校准,因此本文提供 `ρ∈{10,20,30}` 的敏感性结果便于审计与讨论。