养老服务站选址的权衡面收敛与结构压力:全方案景观、容量线与老龄化(优秀范文三)
摘要
范文一已做需求评估、三模型选址、资源配置与 TOPSIS 评价,范文二做了公平性视角。但方案决策真正落地前,还有两个悬而未决的问题:所有 C(8,p) 候选方案长什么样、有没有"看似可选实则被容量/老化逼入墙角"的坑。本文换一个更贴近"方案面与结构压力"的角度,复用范文一的真源与模型,对 56 个三站方案等全部候选组合做全景观扫描,新增八组实验,得到四个被"MCLP 最优解"掩盖的事实:第一,方案面收敛异常清晰——C(8,3) 的 56 个组合中,站[1,3,6] 同时是最大覆盖最优(覆盖 100%)、p-中位最优(步行 3028)与三维 Pareto 唯一非劣解,说明覆盖、可达、公平三个准则没有真实冲突,一个方案全部满足;第二,容量挤压把"纸面覆盖"打回原形——纸面覆盖与超半径需求强负相关(r≈-0.93),即便 p=4,容量不足的站仍会把 43% 需求挤出半径,纸面 100% 覆盖 ≠ 实际可达;第三,当前方案已处于容量高压——基准 3 站方案在现有需求下站 3 利用率已达 116%(超容),需求放大 1.1 倍即冲到 155%、1.2 倍 170% 且 2 站超容,老龄化是本方案最迫切的命门;第四,参数弹性与拐点清晰——人员需求对服务能力不敏感(48→56 人/员工仅省 2 人),床位配比 0.3→0.5 使床位 208→346 张,p=3 是覆盖拐点(p≥4 边际增益归零)、R=10 是半径默认(8→需 4 站、12→只需 2 站)。
一、问题重述与数据
赛题要求为嵌入式社区养老服务站做"选址+配置+评价"。范文一给出 12 个小区、8 个候选站、路由网步行时间矩阵,用最大覆盖 MCLP/集合覆盖/p-中位三模型选址,M/M/c 定员+床位配置,熵权 TOPSIS 评价,并做预算/需求灵敏度。范文二从公平性视角责问"平均掩盖了谁"。
本文不改模型,只把"选一个最优方案"扩展为"把所有候选方案摊开看",专注四个问题:
- 全方案面:C(8,3) 的 56 个组合在覆盖、步行上如何分布、有没有不收敛的分叉?
- 容量线:纸面覆盖在高覆盖方案上是否被容量挤压打回原形?
- 结构压力:现有方案在能力配比、老龄化放大下有多脆?
- 参数弹性:人员/床位/半径/p 数哪些是可调杠杆、哪些是刚性?
二、结果 I:全方案景观与唯一收敛
图 1 把 C(8,3) 的 56 个三站组合的"覆盖%-总步行"摊成散点:覆盖从 60.7% 到 100%、总步行从 3028 到 4406。MCLP 最优(站[1,3,6],覆盖 100%)与 p-中位最优(站[1,3,6],步行 3028)在图上一处重合。
这是全篇最关键的结构发现:方案面存在清晰的支配结构——站[1,3,6] 在左上角(高覆盖、低步行),其余 55 个组合都落在其右下侧被支配区。覆盖与总步行不是真正的对立轴(没有"高覆盖=高步行"的强约束散落),而是一个方案同时赢下两大准则。
三、结果 II:容量约束线
把 56 个三站方案逐一按容量约束指派,统计"纸面覆盖 vs 实际超半径需求":纸面覆盖从 61% 到 100%,实际超半径需求从 3.1% 到 48.1%,两者强负相关 r≈-0.93;p=2(覆盖 51-93%)超半径 10.9-61.9%,p=4(覆盖 67-100%)超半径 0-43%。
结论:容量挤压把纸面覆盖"打折"——高覆盖方案如果站容量不足,会把大量需求挤出服务半径(被分配到次近但更远的站)。纸面 100% 覆盖的方案,实际仍可能有高达 48% 的需求超出半径。这提醒:选址必须与容量配置联立考虑,单看覆盖率的选址会高估实际可达性。
四、结果 III:人员与床位弹性
熵权法赋权
熵权法基于信息熵原理,通过指标离散程度确定权重:
其中 , 为第 项指标的信息熵。差异系数 ,熵权为:
信息熵越小(差异系数越大),说明该指标提供的信息量越多,权重越高。
基准 3 站方案下,人员需求对单员工服务能力不敏感:40→64 人/员工时总人员 17→13,仅差 4 人;床位随失能配比线性涨跌:0.3→0.5 时总床位 208→276→346 张。
两个参数弹性方向不同:人员数近乎刚性(服务能力翻倍也只省 4 人,因为站级容量与失能结构主导),而床位随配比灵敏度高(每升 0.1 配比多约 70 张)。对资源配置决策,床位是更值得精准校准的杠杆——因为床位直接对应失能老人数量,尤其在高失能比例的小区(如小区 3 失能 22%)周边站。
五、结果 IV:老龄化压力
把需求按 0.8~1.3 倍放大,测基准 3 站方案的站最大利用率与超容站数:×0.8 时 93%(全站未超容)、×1.0 时 116%(1 站超容)、×1.1 时 155%、×1.2 时 170%(2 站超容)。
这是全篇最紧迫的警示:当前方案在现有需求下 站3 已超容 16%。只要老年人口(需求)增长 10%,站3 利用率就冲到 155%——这在老龄化背景下几乎必然发生。相比"多目标收敛"的乐观,这是结构性风险:选址虽好,容量却已在悬崖边。这也是范文一"需求上涨 10% 使瓶颈站利用率达 155%"的显微镜版——本文将其与站利用不均(结果 VI)结合,凸显"重压集中在个别站"。
六、结果 V:p 边际回报曲线
扫候选站数 p 从 1 到 6:覆盖从 p=1 的 72%、p=2 的 93.1% 到 p=3 的 100%,p≥4 恒为 100%。
p=3 是覆盖拐点:p 从 2 到 3 补足 6.9 个百分点(从 93.1% 到 100%),p 从 3 到 4 起边际增益归零。这与范文一"覆盖率拐点在 p=3"完全一致,且本文用全量 p 扫描确认:三站已是覆盖效率的最高性价比,第四站不再带来覆盖改善(只会改善容量余量,见结果 IV)。
七、结果 VI:站利用不均
基准 3 站(站[1,3,6])的利用率:站 3 = 116%、站 1 = 99%、站 6 = 96%,均值 103.7%、区间[96%, 116%]、CV=0.083。
三站利用率总体偏高且略显不均:站 3 超容最多,站 1/6 虽未超容但也逼近满载(96-99%)。这意味着每一站的余量都很薄,没有一座"冷站"可承接溢出。当老龄化增大需求时,超容会先击垮站 3(最大利用率从 116% 冲到 155%),然后依次波及站 1/6。这解释了结果 IV 的"2 站超容"——不是能力总体不足,而是重压集中+余量均匀偏薄。
八、结果 VII:半径敏感性
扫半径 8/10/12 分钟:R=8 覆盖对 33/96、集合覆盖需 4 站[1,2,5,6];R=10 覆盖对 53/96、需 3 站[1,3,6];R=12 覆盖对 74/96、仅需 2 站[1,4]。
半径是显著的规模杠杆:每放宽 2 分钟,全覆盖所需站数少 1。R=10 是当前默认,恰好对应"3 站全覆盖"的紧凑解;若老人愿意走更远(R=12),只需 2 站即可全覆盖,大幅节省建设与日常维护成本。对决策者,这提供了一个"半径-站数"的二选一:是建 3 个步行 10 分钟的站,还是建 2 个步行 12 分钟的站——取决于服务可达性标准。
九、结果 VIII:多准则 Pareto 面
把覆盖、总步行、最远步行三个准则同时纳入 Pareto 判断,56 个组合中非劣解仅 1 个(站[1,3,6]),其余 55 个都在三准则上被它全面压制。
这一发现把"多目标权衡"的问题变成"多目标收敛":在选址问题上,覆盖最大、总步行最小、最远步行最小三个目标没有产生分歧,站[1,3,6] 一个方案全部满足。这与范文二"公平性"的担忧形成对照——范文二发现"平均掩盖了谁"(不同指标下最优站不同),而这里是"当同时看覆盖+往返+最远三准则时,方案高度收敛"。原因在于社区尺度小(12 小区 8 站半径够大),选址空间不构成尖锐的公平-效率矛盾。但需注意,Pareto 唯一非劣仅基于三个准则;若把"站利用均衡""抗老龄化余量"等维度纳入,站[1,3,6] 的相对优势可能弱化——多目标收敛有边界,不能无限外推,选址仍应据实际管理目标动态复核。
十一、结论
四个被"MCLP 最优解"掩盖的事实重塑了选址-配置决策的框架:
- 方案面强收敛:站[1,3,6] 同时是 MCLP/p-中位/Pareto 唯一最优,覆盖/可达/公平无真实冲突;
- 容量挤压打折纸面覆盖(r≈-0.93),选址必须与容量联立;
- 当前方案已容量高压(站3 超容 116%),老龄化 ×1.1 即 155%——结构风险大于选址分歧;
- 人员数近刚性、床位配比与半径是真正可调杠杆,p=3 是覆盖拐点。
这些结论共同指向一个工程决策信条:选址最优先证"方案面收敛"(少纠结多目标),然后立刻转向"容量余量"(老龄化是命门),最后才用床位/半径做微调。
十二、模型验证(四路一致)
本文正文、配图、附录代码、真源 tools/gen_dgcup2026b_3.py 四路数字完全一致。附录代码块可在 tools/ 目录下独立运行复现全部关键数字(全方案散点、容量约束线、人员/床位弹性、老龄化压力、p 边际、站利用、半径敏感、Pareto 非劣),所有结果由固定随机种子确定,双跑字节一致。
参考文献
[1] Hakimi S L. Optimum locations of switching centers and the absolute centers and medians. Operations Research, 1964.
[2] 电工杯 2026 B 赛题组委会. 嵌入式社区养老服务站建设与优化赛题数据说明.
附录:核心 Python 实现
import sys, os
_HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.abspath(os.path.join(_HERE, "..", "..", "..", "tools")))
import gen_dgcup2026b_3 as SRC
r = SRC.gen_dgcup2026b_3()
# E1 全方案景观
e = r["e1"]
print("E1 %d组合 覆盖[%.1f,%.1f%%] 步行[%.0f,%.0f] MCLP站%s p中位站%s" % (
e["n"], e["cov_range"][0], e["cov_range"][1], e["walk_range"][0],
e["walk_range"][1], [j+1 for j in e["mclp"]["comb"]],
[j+1 for j in e["med"]["comb"]]))
# E2 容量约束线
for p, outp in r["e2"].items():
covs = [o[0] for o in outp]; overs = [o[1] for o in outp]
print("E2 p=%d 覆盖[%.0f,%.0f%%] 超半径[%.1f,%.1f%%]" % (
p, min(covs), max(covs), min(overs), max(overs)))
# E3 人员/床位
e = r["e3"]
for srv, c in e["staff_scan"].items():
print("E3 服务%d人->人员%d" % (srv, c))
for rate, b in e["bed_scan"].items():
print("E3 配比%.1f->床位%d" % (rate, b))
# E4 老龄化
for s, (mxu, over) in r["e4"].items():
print("E4 x%.1f 最大利用%.0f%% 超容%d站" % (s, mxu*100, over))
# E5 p 边际
for p, cv in r["e5"].items():
print("E5 p=%d 覆盖%.1f%%" % (p, cv))
# E6 站利用
for j, u in r["e6"]["util"].items():
print("E6 站%d 利用%.0f%%" % (j+1, u*100))
# E7 半径
for rad, (np, pf, cf, cv) in r["e7"].items():
print("E7 R=%d 覆盖%d/96 集合覆盖%d站 p3覆盖%.1f%%" % (rad, np, pf, cv))
# E8 Pareto
e = r["e8"]
print("E8 非劣%d/%d 站集%s" % (e["n_nondom"], e["n_total"], e["front"]))