最优火车站选址问题的分析与解决
问题描述
小F计划在网格状布局的A市中选一个最优的火车站建设点,使得所有市民到火车站的曼哈顿距离之和最小。需要从备选位置中选出一个地址,如果有多个位置最优,则选取列表中第一个出现的位置。
曼哈顿距离公式:
对于两点 (x1,y1)(x_1, y_1)(x1,y1) 和 (x2,y2)(x_2, y_2)(x2,y2),曼哈顿距离为:
距离=∣x1−x2∣+∣y1−y2∣\text{距离} = |x_1 - x_2| + |y_1 - y_2|距离=∣x1−x2∣+∣y1−y2∣
解题思路
- 逐一计算总距离: 遍历每个备选火车站点,计算所有市民到该点的曼哈顿距离之和。
- 比较最小值: 对所有备选点的总距离进行比较,记录最小距离及对应的位置。
- 处理平局情况: 如果多个点的总距离相同,选择列表中较前的点。
解题步骤
-
输入解析:
n表示市民人数,m表示备选火车站数量。citizens为市民位置的列表。locations为备选火车站位置的列表。
-
遍历备选点:
- 对每个火车站备选点,逐一计算其与所有市民之间的曼哈顿距离。
-
比较并更新最优解:
- 如果当前点的总距离小于记录的最小距离,更新最小距离及最优点。
- 如果当前点的总距离等于记录的最小距离,保持之前记录的点。
-
返回结果:
- 输出最优火车站的位置坐标。
Python 实现
python
def solution(n, m, citizens, locations):
min_total_distance = float('inf') # 初始化最小总距离
optimal_location = None # 初始化最优位置
for location in locations:
total_distance = 0
# 计算该点与所有市民的距离总和
for citizen in citizens:
distance = abs(citizen[0] - location[0]) + abs(citizen[1] - location[1])
total_distance += distance
# 更新最优点
if total_distance < min_total_distance:
min_total_distance = total_distance
optimal_location = location
elif total_distance == min_total_distance:
# 若距离相同,选择先出现的位置
continue
return optimal_location
时间复杂度与空间复杂度
时间复杂度:
- 外层循环遍历备选点,复杂度为 O(m)O(m)O(m)。
- 内层循环遍历市民,计算距离的复杂度为 O(n)O(n)O(n)。
- 总体复杂度为 O(m×n)O(m \times n)O(m×n)。
空间复杂度:
- 只使用了常数级别的额外空间,空间复杂度为 O(1)O(1)O(1)。
测试用例
python
print(solution(4, 3, [[-1, -1], [-1, 1], [1, -1], [1, 1]], [[3, 2], [1, 0], [0, 0]]))
# 输出: [1, 0]
print(solution(2, 2, [[0, 0], [0, 4]], [[0, 2], [0, 3]]))
# 输出: [0, 2]
print(solution(3, 1, [[10, 10], [20, 20], [30, 30]], [[15, 15]]))
# 输出: [15, 15]
print(solution(5, 3, [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]], [[4, 5], [6, 7], [8, 9]]))
# 输出: [4, 5]
print(solution(6, 2, [[10, 10], [20, 20], [30, 30], [40, 40], [50, 50], [60, 60]], [[35, 35], [45, 45]]))
# 输出: [35, 35]
知识总结与心得
-
问题分解与建模:
- 通过数学公式将现实问题转化为编程可解的问题。
- 把"总距离最小化"作为目标函数,用遍历求解。
-
优化与效率:
- 曼哈顿距离的计算公式简单易用,无需复杂几何计算。
- 直接比较距离总和和更新最优解,逻辑清晰、效率较高。
-
应用场景:
- 曼哈顿距离的概念常用于城市规划、物流选址等领域,熟练掌握可以解决多类优化问题。
通过本题的练习,我们能够更好地理解如何处理距离优化问题,并掌握遍历、比较与更新逻辑的应用技巧。