固定K-means聚类质心以确定仓库选址的技术求助
固定K-means质心实现工厂+仓库选址方案
针对你的需求——固定工厂位置为K-means的一个质心,求解其余仓库质心,以下是可落地的技术实现步骤:
核心思路
将工厂坐标设为不可更新的固定质心,让K-means迭代过程中仅更新剩余质心,确保工厂自动覆盖周边需求点,剩余质心即为最优仓库选址,再结合重心法(COG)优化初始值提升效率。
1. 数据预处理
- 整理所有配送需求点的经纬度为二维数组(示例用NumPy):
import numpy as np # 替换为你的实际配送需求点数据 demand_points = np.array([[116.397, 39.908], [116.41, 39.89], [116.45, 39.85], ...]) # 工厂的固定经纬度 factory_coords = np.array([[116.52, 39.96]]) - 设定聚类总数:
k = 仓库数量 + 1(+1是预留工厂的固定质心位)
2. 自定义固定质心的K-means实现
直接修改K-means的迭代逻辑,锁定工厂质心不参与更新:
def fixed_centroid_kmeans(X, fixed_centroid, k, max_iter=100, tol=1e-6): # 初始化质心:第一个为工厂,剩余k-1个用需求点随机初始化(或用COG结果) centroids = np.vstack([fixed_centroid, X[np.random.choice(len(X), k-1, replace=False)]]) centroids_prev = centroids.copy() for _ in range(max_iter): # 计算每个需求点到所有质心的距离,分配聚类标签 distances = np.sqrt(((X - centroids[:, np.newaxis])**2).sum(axis=2)) labels = np.argmin(distances, axis=0) # 仅更新非工厂的质心 for i in range(1, k): cluster_points = X[labels == i] if len(cluster_points) > 0: centroids[i] = cluster_points.mean(axis=0) # 检查收敛:非固定质心变化小于阈值则停止 if np.allclose(centroids[1:], centroids_prev[1:], atol=tol): break centroids_prev = centroids.copy() return labels, centroids # 运行:假设需要2个仓库,k=3 labels, final_centroids = fixed_centroid_kmeans(demand_points, factory_coords, k=3) # final_centroids[0]是工厂,final_centroids[1:]即为仓库选址坐标
3. 结合重心法(COG)优化初始值
为了让仓库质心更贴合远区需求,可先筛选出远离工厂的需求点,计算其重心作为仓库质心的初始值:
# 计算需求点到工厂的距离,筛选远区点(可自定义距离阈值,比如10公里,需转成经纬度距离) def haversine(lon1, lat1, lon2, lat2): lon1, lat1, lon2, lat2 = map(np.radians, [lon1, lat1, lon2, lat2]) dlon = lon2 - lon1 dlat = lat2 - lat1 a = np.sin(dlat/2)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon/2)**2 c = 2 * np.arcsin(np.sqrt(a)) r = 6371 # 地球半径(公里) return c * r # 筛选距离工厂超过10公里的点 distances_to_factory = haversine(demand_points[:,0], demand_points[:,1], factory_coords[0,0], factory_coords[0,1]) far_points = demand_points[distances_to_factory > 10] # 计算远区点的重心(COG)作为仓库初始质心 cog_far = np.mean(far_points, axis=0) # 替换初始化逻辑中的随机质心 init_centroids = np.vstack([factory_coords, cog_far, cog_far]) # 若2个仓库,可复制或计算次重心
4. 结果验证与可视化
用Folium将结果可视化,验证聚类合理性:
- 给不同聚类的需求点标不同颜色
- 用特殊标记标注工厂和仓库质心
- 检查工厂聚类是否集中在周边,仓库聚类是否覆盖远区,若不符合可调整聚类数或距离阈值重新运行
内容的提问来源于stack exchange,提问作者Nani
相关产品推荐
相关产品推荐

