update readmes

This commit is contained in:
2026-01-19 22:57:22 +08:00
parent b4a307e5a8
commit d49a10a042
12 changed files with 198 additions and 31 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -10,9 +10,9 @@
4. **风险可控的全局调度**:在提升效率的同时,将服务缺口风险控制在可接受范围 4. **风险可控的全局调度**:在提升效率的同时,将服务缺口风险控制在可接受范围
**实际运行结果** **实际运行结果**
- 总服务量提升 **9.8%**141,044 → 154,884 - 总服务量提升 **9.9%**139,469 → 153,307
- 质量加权服务量提升 **6.2%**132,009 → 140,194 - 质量加权服务量提升 **6.3%**131,462 → 139,701
- 资源节省 **9.5%**69次双站点访问) - 资源节省 **9.6%**70次双站点访问)
- 服务缺口风险 **1.2%**(低风险水平) - 服务缺口风险 **1.2%**(低风险水平)
--- ---
@@ -326,12 +326,17 @@ $$V_{ij} = \underbrace{\alpha \cdot \frac{\mu_i + \mu_j}{Q}}_{\text{容量利用
- **价值 (Value)**:综合得分。得分越高,表明该配对在“高容量利用”、“低距离代价”和“低波动风险”三方面取得了最佳平衡。 - **价值 (Value)**:综合得分。得分越高,表明该配对在“高容量利用”、“低距离代价”和“低波动风险”三方面取得了最佳平衡。
| 排名 | 站点i (Site i) | 站点j (Site j) | 距离 (mi) | 需求和 ($\mu_{sum}$) | 价值 ($V_{ij}$) | | 排名 | 站点i (Site i) | 站点j (Site j) | 距离 (mi) | 需求和 ($\mu_{sum}$) | 价值 ($V_{ij}$) |
|------|-------|-------|------|--------|------| |---|---|---|---|---|---|
| 1 | Boys and Girls Club | Redeemer Lutheran | 0.4 mi | 441 | 1.07 | | 1 | American Legion - Binghamton | First Assembly Of God Church | 1.3 mi | 346 | 0.96 |
| 2 | Rathbone | Woodhull | 5.8 mi | 445 | 1.06 | | 2 | Senior - Villa Serene | The Love Church | 0.8 mi | 329 | 0.92 |
| 3 | Bath | Campbell | 9.6 mi | 448 | 1.05 | | 3 | College Corning Community College | Senior - Dayspring | 2.2 mi | 328 | 0.91 |
| 4 | Springview Apts | Waverly | 0.8 mi | 424 | 1.05 | | 4 | Endwell United Methodist Church | Senior - North Shore Towers | 5.8 mi | 344 | 0.91 |
| 5 | Birnie Transport | Lindley | 10.1 mi | 446 | 1.04 | | 5 | Danby | Salvation Army Ithaca | 6.1 mi | 341 | 0.90 |
| 6 | Beaver Dams | Millport | 6.1 mi | 337 | 0.89 |
| 7 | Birnie Transportation Services | Bradford | 13.6 mi | 336 | 0.81 |
| 8 | Rehoboth Deliverance Ministry | Senior - CFS Lakeview | 17.4 mi | 348 | 0.81 |
| 9 | Richford | Senior - Titus Towers | 16.4 mi | 339 | 0.80 |
| 10 | Rathbone | Senior - Addison Place Apartments | 4.7 mi | 299 | 0.79 |
--- ---
@@ -441,12 +446,12 @@ $$\mu_i - k\sigma_i \leq q \leq Q - \mu_j + k\sigma_j$$
- **比例 (Ratio)**$q^*/400$。注意看 **Springview + Waverly** 这一组,尽管 Waverly (站点j) 的需求很大,但由于 Springview (站点i) 的波动极小 ($\sigma=5.6$) 而 Waverly 波动大 ($\sigma=51.9$),模型仅给 Springview 预留了 6.0% 的极低比例。这精确地反映了“将大部分缓冲留给波动大的站点”这一核心策略。 - **比例 (Ratio)**$q^*/400$。注意看 **Springview + Waverly** 这一组,尽管 Waverly (站点j) 的需求很大,但由于 Springview (站点i) 的波动极小 ($\sigma=5.6$) 而 Waverly 波动大 ($\sigma=51.9$),模型仅给 Springview 预留了 6.0% 的极低比例。这精确地反映了“将大部分缓冲留给波动大的站点”这一核心策略。
| 配对 | $\mu_i$ | $\mu_j$ | $\sigma_i$ | $\sigma_j$ | $q^*$ | 比例 | | 配对 | $\mu_i$ | $\mu_j$ | $\sigma_i$ | $\sigma_j$ | $q^*$ | 比例 |
|------|---------|---------|------------|------------|-------|------| |---|---|---|---|---|---|---|
| Boys & Girls + Redeemer | 210.8 | 230.6 | 28.9 | 93.5 | 195.9 | 49.0% | | American Legion + First Assemb... | 200.2 | 146.0 | 46.1 | 21.6 | 236.8 | 59.2% |
| Rathbone + Woodhull | 269.1 | 176.0 | 38.2 | 35.9 | 248.1 | 62.0% | | Senior + The Love Church | 69.7 | 259.3 | 5.1 | 59.9 | 75.3 | 18.8% |
| Bath + Campbell | 279.5 | 168.5 | 67.9 | 33.9 | 254.3 | 63.6% | | College Corn... + Senior | 251.0 | 77.2 | 33.3 | 17.9 | 297.6 | 74.4% |
| Springview + Waverly | 27.6 | 396.6 | 5.6 | 51.9 | 23.9 | 6.0% | | Endwell Unit... + Senior | 285.2 | 58.3 | 60.8 | 6.9 | 335.9 | 84.0% |
| Birnie + Lindley | 213.4 | 232.9 | 27.8 | 56.9 | 189.4 | 47.3% | | Danby + Salvation Ar... | 160.2 | 181.2 | 34.6 | 39.6 | 187.5 | 46.9% |
--- ---
@@ -528,19 +533,19 @@ $$R_1 = P(S_i / D_i < 0.8 \text{ 或 } S_j / D_j < 0.8)$$
下表对比了 Task 1传统单站点模式与 Task 3双站点优化模式的关键性能指标。数据表明新模型在各项核心指标上均取得了显著突破。 下表对比了 Task 1传统单站点模式与 Task 3双站点优化模式的关键性能指标。数据表明新模型在各项核心指标上均取得了显著突破。
- **E1 (总服务量)**:提升 **9.8%**。这直接归功于释放出的 69 个访问槽位被重新分配给了全网络,增加了总的服务频次。 - **E1 (总服务量)**:提升 **9.9%**。这直接归功于释放出的 70 个访问槽位被重新分配给了全网络,增加了总的服务频次。
- **E2 (质量加权)**:提升 **6.2%**。虽然增幅略低于 E1因为双站点模式下每户平均分得量可能略减导致质量因子下降但整体质量效益依然显著为正。 - **E2 (质量加权)**:提升 **6.3%**。虽然增幅略低于 E1因为双站点模式下每户平均分得量可能略减导致质量因子下降但整体质量效益依然显著为正。
- **R1 (缺口风险)**:虽然从 0 增加到 1.2%,但这一数值远低于行业通常接受的 5% 风险阈值,说明模型成功用微小的风险代价换取了巨大的效率提升。 - **R1 (缺口风险)**:虽然从 0 增加到 1.2%,但这一数值远低于行业通常接受的 5% 风险阈值,说明模型成功用微小的风险代价换取了巨大的效率提升。
- **RS (资源节省)****9.5%** 的资源节省率意味着 FBST 可以用同样的卡车和志愿者资源,多服务近一成的社区,或者在维持现有服务水平下减少 9.5% 的运营成本。 - **RS (资源节省)****9.6%** 的资源节省率意味着 FBST 可以用同样的卡车和志愿者资源,多服务近一成的社区,或者在维持现有服务水平下减少 9.6% 的运营成本。
| 指标 | Task 1 | Task 3 | 变化 | 变化% | | 指标 | Task 1 | Task 3 | 变化 | 变化% |
|------|--------|--------|------|-------| |---|---|---|---|---|
| **E1 (总服务量)** | 141,044 | 154,884 | +13,840 | **+9.8%** | | **E1 (总服务量)** | 139,469 | 153,307 | +13,838 | **+9.9%** |
| **E2 (质量加权)** | 132,009 | 140,194 | +8,184 | **+6.2%** | | **E2 (质量加权)** | 131,462 | 139,701 | +8,240 | **+6.3%** |
| F1 (Gini系数) | 0.313 | 0.320 | +0.007 | +2.4% | | F1 (Gini系数) | 0.314 | 0.322 | +0.008 | +2.5% |
| F2 (最低满足率) | 2.00 | 2.00 | 0.00 | 0.0% | | F2 (最低满足率) | 2.000 | 2.000 | -0.000 | -0.0% |
| **R1 (缺口风险)** | 0 | 0.012 | +0.012 | 新增 | | **R1 (缺口风险)** | 0 | 0.012 | +0.012 | 新增 |
| **RS (资源节省)** | 0% | 9.5% | +9.5% | 新增 | | **RS (资源节省)** | 0% | 9.6% | +9.6% | 新增 |
**核心发现** **核心发现**
1. 通过双站点模式释放9.5%的访问槽位 1. 通过双站点模式释放9.5%的访问槽位
@@ -570,11 +575,11 @@ $$R_1 = P(S_i / D_i < 0.8 \text{ 或 } S_j / D_j < 0.8)$$
**总体汇总(范围为扫描区间的最小值~最大值)** **总体汇总(范围为扫描区间的最小值~最大值)**
| 参数 | E1范围 | E2范围 | R1范围 | | 参数 | E1范围 | E2范围 | R1范围 |
|------|--------|--------|--------| |---|---|---|---|
| $r_{merge}$ | 143,904 ~ 181,014-12.13% ~ +10.52% | 132,849 ~ 143,124-4.22% ~ +3.19% | 0.1708 ~ 0.1708 | | $r_{merge}$ | 143252 - 180189 (+22.69%) | 132637 - 142734 (+7.30%) | 0.1708 - 0.1708 |
| $l_{max}$ | 158,665 ~ 163,777-3.12% ~ +0.00% | 137,369 ~ 138,699-0.96% ~ +0.00% | 0.1447 ~ 0.1796 | | $l_{max}$ | 158014 - 162762 (+2.92%) | 137158 - 138424 (+0.92%) | 0.1447 - 0.1796 |
| $\mu_{sum,max}$ | 160,924 ~ 164,140-1.74% ~ +0.22% | 135,781 ~ 143,672-2.10% ~ +3.59% | 0.0262 ~ 0.2090 | | $\mu_{sum,max}$ | 160273 - 163268 (+1.84%) | 135569 - 143460 (+5.71%) | 0.0262 - 0.2090 |
| $CV_{max}$ | 141,666 ~ 163,951-13.50% ~ +0.11% | 132,823 ~ 138,873-4.24% ~ +0.13% | 0.0000 ~ 0.1810 | | $CV_{max}$ | 141014 - 162936 (+13.47%) | 132611 - 138445 (+4.22%) | 0.0000 - 0.1810 |
**1. 合并比例 $r_{merge}$ — 影响 E1/E2 的主导参数** **1. 合并比例 $r_{merge}$ — 影响 E1/E2 的主导参数**
@@ -726,7 +731,7 @@ $$R_1 = P(S_i / D_i < 0.8 \text{ 或 } S_j / D_j < 0.8)$$
### 10.1 主要发现 ### 10.1 主要发现
1. **配对收益**双站点模式可节省9.5%的访问槽位服务量提升9.8% 1. **配对收益**双站点模式可节省9.6%的访问槽位服务量提升9.9%
2. **分配策略**:最优分配量 $q^*$ 与两站点需求波动性成反比——波动大的站点需要更多"缓冲" 2. **分配策略**:最优分配量 $q^*$ 与两站点需求波动性成反比——波动大的站点需要更多"缓冲"
3. **风险可控**通过合理的配对选择和鲁棒性约束服务缺口风险控制在1.2%以内 3. **风险可控**通过合理的配对选择和鲁棒性约束服务缺口风险控制在1.2%以内
4. **参数敏感性分工明确**:合并比例主导 E1/E2容量上限与CV阈值主导风险与E2距离阈值快速进入平台期 4. **参数敏感性分工明确**:合并比例主导 E1/E2容量上限与CV阈值主导风险与E2距离阈值快速进入平台期

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 760 KiB

After

Width:  |  Height:  |  Size: 755 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 63 KiB

View File

@@ -0,0 +1,162 @@
import pandas as pd
import numpy as np
def format_table_1_pairings():
try:
df = pd.read_excel('02_pairing.xlsx', sheet_name='selected_pairs')
df = df.sort_values('value', ascending=False).head(10)
print("\n### Top 10 High Value Pairings")
print("| 排名 | 站点i (Site i) | 站点j (Site j) | 距离 (mi) | 需求和 (μ_sum) | 价值 (V_ij) |")
print("|---|---|---|---|---|---|")
for idx, row in df.iterrows():
rank = idx + 1 # Assuming index resets or we just use counter. Actually index might not be 0-based if sorted.
# But wait, df is from read_excel, default index 0..N.
# If I sorted it, index is shuffled.
# I should use a counter.
pass
for i, (idx, row) in enumerate(df.iterrows()):
rank = i + 1
site_i = row['site_i_name'].replace('MFP ', '')
site_j = row['site_j_name'].replace('MFP ', '')
dist = f"{row['distance']:.1f} mi"
mu_sum = f"{row['mu_sum']:.0f}"
val = f"{row['value']:.2f}"
print(f"| {rank} | {site_i} | {site_j} | {dist} | {mu_sum} | {val} |")
except Exception as e:
print(f"Error generating Table 1: {e}")
def format_table_2_allocation():
try:
df = pd.read_excel('03_allocation.xlsx', sheet_name='allocation')
df = df.sort_values('value', ascending=False).head(5)
print("\n### Top 5 Pairings' Optimal Allocation Strategies")
print("| 配对 | μ_i | μ_j | σ_i | σ_j | q* | 比例 |")
print("|---|---|---|---|---|---|---|")
for _, row in df.iterrows():
name_i = row['site_i_name'].replace('MFP ', '').split(' - ')[0]
name_j = row['site_j_name'].replace('MFP ', '').split(' - ')[0]
# If still too long, take first 15 chars
if len(name_i) > 15: name_i = name_i[:12] + "..."
if len(name_j) > 15: name_j = name_j[:12] + "..."
pair = f"{name_i} + {name_j}"
mu_i = f"{row['mu_i']:.1f}"
mu_j = f"{row['mu_j']:.1f}"
sigma_i = f"{row['sigma_i']:.1f}"
sigma_j = f"{row['sigma_j']:.1f}"
q_star = f"{row['q_final']:.1f}"
ratio = f"{row['q_ratio']:.1%}"
print(f"| {pair} | {mu_i} | {mu_j} | {sigma_i} | {sigma_j} | {q_star} | {ratio} |")
except Exception as e:
print(f"Error generating Table 2: {e}")
def format_table_3_comparison():
try:
df = pd.read_excel('06_evaluate.xlsx', sheet_name='comparison')
# The structure is Metric, Task 1, Task 3, Change, Change %
print("\n### Actual Result Comparison Analysis")
print("| 指标 | Task 1 | Task 3 | 变化 | 变化% |")
print("|---|---|---|---|---|")
for _, row in df.iterrows():
metric = row['Metric']
# Bold important metrics
if 'E1' in metric or 'E2' in metric or 'RS' in metric or 'R1' in metric:
metric = f"**{metric}**"
task1 = row['Task 1']
task3 = row['Task 3']
change = row['Change']
change_pct = row['Change %']
# Format numbers
if 'Gini' in row['Metric'] or '最低' in row['Metric'] or '风险' in row['Metric']:
t1_str = f"{task1:.3f}" if isinstance(task1, (int, float)) else task1
t3_str = f"{task3:.3f}" if isinstance(task3, (int, float)) else task3
ch_str = f"{change:+.3f}" if isinstance(change, (int, float)) else change
else:
t1_str = f"{task1:,.0f}" if isinstance(task1, (int, float)) else task1
t3_str = f"{task3:,.0f}" if isinstance(task3, (int, float)) else task3
ch_str = f"{change:+,.0f}" if isinstance(change, (int, float)) else change
if '风险' in row['Metric'] and task1 == 0:
pct_str = "新增"
elif '节省' in row['Metric'] and task1 == 0:
pct_str = "新增"
else:
pct_str = f"{change_pct:+.1f}%" if isinstance(change_pct, (int, float)) else change_pct
# Bold significant improvements
if isinstance(change_pct, (int, float)) and change_pct > 5:
pct_str = f"**{pct_str}**"
print(f"| {metric} | {t1_str} | {t3_str} | {ch_str} | {pct_str} |")
# Add R1 and RS from task3_metrics sheet
try:
metrics_df = pd.read_excel('06_evaluate.xlsx', sheet_name='task3_metrics')
r1_val = metrics_df.loc[metrics_df['metric']=='R1', 'value'].values[0]
rs_val = metrics_df.loc[metrics_df['metric']=='RS', 'value'].values[0] # Note: stored as RS/100 (e.g. 0.095)
visits_val = metrics_df.loc[metrics_df['metric']=='total_dual_visits', 'value'].values[0]
print(f"\nTotal Dual Visits: {visits_val}")
# Format R1
# Task 1 R1 is 0
print(f"| **R1 (缺口风险)** | 0 | {r1_val:.3f} | +{r1_val:.3f} | 新增 |")
# Format RS
# Task 1 RS is 0%
rs_pct = rs_val * 100
print(f"| **RS (资源节省)** | 0% | {rs_pct:.1f}% | +{rs_pct:.1f}% | 新增 |")
except Exception as e2:
print(f"Error adding R1/RS: {e2}")
except Exception as e:
print(f"Error generating Table 3: {e}")
def format_table_4_sensitivity():
try:
df = pd.read_excel('07_sensitivity.xlsx', sheet_name='summary')
print("\n### Sensitivity Analysis Results")
print("| 参数 | E1范围 | E2范围 | R1范围 |")
print("|---|---|---|---|")
for _, row in df.iterrows():
param = row['Parameter']
e1_range = row['E1_Range']
e2_range = row['E2_Range']
r1_range = row['R1_Range']
# Add variable percentage if available
e1_var = row['E1_Var%']
e2_var = row['E2_Var%']
e1_str = f"{e1_range} ({e1_var:+.2f}%)" if pd.notnull(e1_var) else e1_range
e2_str = f"{e2_range} ({e2_var:+.2f}%)" if pd.notnull(e2_var) else e2_range
# Map param names to symbols
if param == 'merge_ratio': param = '$r_{merge}$'
elif param == 'l_max': param = '$l_{max}$'
elif param == 'mu_sum_max': param = '$\mu_{sum,max}$'
elif param == 'cv_max': param = '$CV_{max}$'
print(f"| {param} | {e1_str} | {e2_str} | {r1_range} |")
except Exception as e:
print(f"Error generating Table 4: {e}")
if __name__ == "__main__":
format_table_1_pairings()
format_table_2_allocation()
format_table_3_comparison()
format_table_4_sensitivity()