交互式图论学习
交互式图论学习
Guest User
Using app without sign in
设施选址求解器
寻找使平均距离最小的最佳中心枢纽
选择算法并生成步骤以开始可视化
设施选址问题决定在何处开设仓库或诊所等设施,以最小总成本服务一组需求点,在设施开设成本与顾客服务距离之间权衡。大多数变体(包括 k-中位与 k-中心)都是 NP 难的。
实用求解器结合多种思路。贪心算法开设成本除以覆盖需求之比最优的设施,并达到可证明的近似保证。局部搜索在仍可改进时交换开设与关闭的设施。中等规模的精确解使用混合整数规划,大型实例使用拉格朗日松弛或 k-means 等基于聚类的启发式来播种候选站点。
设施选址决定供应链中仓库与配送中心的位置、基站与电动车充电覆盖、用于应急响应的医院与消防站选址,以及内容分发服务器的部署。它是运筹学和物流分析的旗舰问题。
这个问题在两项方向相反的成本之间权衡:开设站点要花钱,但每多开一个站点,通往客户的路程就更短。精确表述是一个整数规划;实践中则采用带局部改进的贪心启发式。
// 精确(小规模):枚举站点的每个子集
最优 = 无穷大
对候选站点的每个非空子集 S:
代价 = S 中各 f 的 开设成本[f] 之和
对每个客户 c:
代价 += S 中各 f 的 服务成本[f][c] 的最小值
最优 = min(最优, 代价)
// 贪心(大规模):开设能省下最多的那个站点
S = {}
重复:
f* = 使总代价下降最多的未开设站点
若开设 f* 不能降低总代价: 停止
S = S + {f*}
// 之后:用交换、开设与关闭做局部搜索关键在于客户总是被分配给对他们而言最便宜的已开设站点,因此唯一真正的自由度就是开设哪一个子集。这把一个看似连续的问题变成了在子集上的组合问题,而这也正是它 NP 困难的原因:共有 2 的 n 次方个子集,而且没有已知办法能在多项式时间内遍历它们。
在三个候选站点和四个客户的情形下决定开设哪些站点,把所有子集都比一遍。
示例图: 开设成本:F1 为 10,F2 为 8,F3 为 6。各客户的服务成本:F1 服务 C1 与 C2 分别为 2 和 3,但服务 C3 与 C4 各需 9;F2 服务 C3 与 C4 分别为 2 和 3,但服务 C1 与 C2 需 8 和 7;F3 服务这四个客户各需 5。
最优方案是只开设 F3,总代价为 26。这一点值得停下来体会:F3 不是任何一个客户的首选站点,然而最优子集恰恰就是它。一个把每个客户分配给其服务成本最低站点的启发式,会开设 F1 与 F2 并得到 28。真正起作用的只有开设成本与服务成本之间的权衡,而逐个客户去推理捕捉不到这一点。
时间: NP 困难;精确解为 O(2^n · n · m) · 空间: O(n · m)
设有 n 个候选站点和 m 个客户,精确枚举要测试全部 2 的 n 次方个非空子集,并对每个子集把 m 个客户各以 O(n) 的代价分配到最便宜的已开设站点,因此是 O(2 的 n 次方乘以 n 乘以 m)。这只在大约 20 到 25 个站点以内才可行。该问题是 NP 困难的,因此不预期存在精确的多项式算法。好消息是无容量限制的版本是可近似的:基于线性规划舍入与局部搜索,存在近似比约为 1.5 的常数因子算法,这与图着色形成鲜明对照,后者没有任何像样的近似算法。每一步开设能带来最大节省的站点这种贪心做法具有对数级保证,实践中表现也不错。
选哪个版本取决于站点是否有容量上限,以及客户有多少。
| 替代算法 | 以下情况更合适 | 代价 |
|---|---|---|
| 精确枚举或整数规划 | 候选站点少于约 25 个,而且你需要可证明的最优解。 | O(2^n · n · m) |
| 贪心加局部搜索 | 大规模算例。按最大节省开设,然后再做交换、开设与关闭。 | 每轮 O(n^2 · m) |
| 带容量的选址 | 每个站点能服务的需求有上限。要难得多。 | NP 困难 |
| K-均值 | 不存在开设成本,你只是想把客户分成 k 个地理区域。 | O(n · k · i · d) |
| K-中值 | 你要在没有开设成本的前提下恰好开设 k 个站点,并最小化总距离。 | NP 困难 |