name: facility-layout-optimizer description: 用于物料流最小化和空间利用最大化的设施布局优化技能。 allowed-tools: Bash(*) Read Write Edit Glob Grep WebFetch metadata: author: babysitter-sdk version: “1.0.0” category: supply-chain backlog-id: SK-IE-027
设施布局优化器
您是设施布局优化器——一个专门用于优化设施布局以最小化物料流并最大化空间利用率的技能。
概述
此技能支持AI驱动的设施布局优化,包括:
- 从-到图表分析
- 活动关系图绘制
- CRAFT和ALDEP算法实现
- 区块布局生成
- 通道设计和尺寸确定
- 物料流可视化
- 空间需求计算
- 布局方案评估
功能
1. 从-到图表分析
import numpy as np
import pandas as pd
def create_from_to_chart(flow_data: list):
"""
根据物料流数据创建从-到图表
flow_data: 列表,元素为 (起始部门, 目标部门, 流量, 单位成本)
"""
# 获取唯一部门
depts = set()
for from_d, to_d, _, _ in flow_data:
depts.add(from_d)
depts.add(to_d)
depts = sorted(list(depts))
# 创建矩阵
n = len(depts)
flow_matrix = np.zeros((n, n))
cost_matrix = np.zeros((n, n))
dept_idx = {d: i for i, d in enumerate(depts)}
for from_d, to_d, flow, cost in flow_data:
i, j = dept_idx[from_d], dept_idx[to_d]
flow_matrix[i, j] = flow
cost_matrix[i, j] = cost
# 计算加权流量
weighted_flow = flow_matrix * cost_matrix
return {
"departments": depts,
"flow_matrix": pd.DataFrame(flow_matrix, index=depts, columns=depts),
"cost_matrix": pd.DataFrame(cost_matrix, index=depts, columns=depts),
"weighted_flow": pd.DataFrame(weighted_flow, index=depts, columns=depts),
"total_flow": flow_matrix.sum(),
"total_weighted_flow": weighted_flow.sum()
}
2. 活动关系图
from dataclasses import dataclass
from enum import Enum
class Closeness(Enum):
A = "绝对必要"
E = "特别重要"
I = "重要"
O = "普通"
U = "不重要"
X = "不希望"
@dataclass
class RelationshipEntry:
dept1: str
dept2: str
closeness: Closeness
reason: str
def create_relationship_chart(relationships: list):
"""
创建活动关系图(REL图)
"""
# 提取部门
depts = set()
for r in relationships:
depts.add(r.dept1)
depts.add(r.dept2)
depts = sorted(list(depts))
# 创建关系矩阵
n = len(depts)
rel_matrix = {}
for r in relationships:
key = (r.dept1, r.dept2) if r.dept1 < r.dept2 else (r.dept2, r.dept1)
rel_matrix[key] = {
"closeness": r.closeness.name,
"reason": r.reason
}
# 用于布局优化的紧密度评分
closeness_scores = {
'A': 64, 'E': 16, 'I': 4, 'O': 1, 'U': 0, 'X': -64
}
# 为算法创建数值矩阵
score_matrix = np.zeros((n, n))
dept_idx = {d: i for i, d in enumerate(depts)}
for (d1, d2), rel in rel_matrix.items():
i, j = dept_idx[d1], dept_idx[d2]
score = closeness_scores[rel['closeness']]
score_matrix[i, j] = score
score_matrix[j, i] = score
return {
"departments": depts,
"relationships": rel_matrix,
"score_matrix": pd.DataFrame(score_matrix, index=depts, columns=depts),
"summary": {
"total_relationships": len(relationships),
"A_count": sum(1 for r in relationships if r.closeness == Closeness.A),
"X_count": sum(1 for r in relationships if r.closeness == Closeness.X)
}
}
3. CRAFT算法
def craft_algorithm(initial_layout: np.ndarray, flow_matrix: np.ndarray,
distance_matrix_func, max_iterations: int = 100):
"""
CRAFT(计算机化设施相对分配技术)
改进算法——从初始布局开始,迭代改进
"""
n = len(flow_matrix)
current_layout = initial_layout.copy()
def calculate_cost(layout, flow, dist_func):
total_cost = 0
for i in range(n):
for j in range(n):
if i != j:
loc_i = np.argwhere(layout == i)[0]
loc_j = np.argwhere(layout == j)[0]
dist = dist_func(loc_i, loc_j)
total_cost += flow[i, j] * dist
return total_cost
current_cost = calculate_cost(current_layout, flow_matrix, distance_matrix_func)
iteration = 0
improvement_history = [{"iteration": 0, "cost": current_cost}]
while iteration < max_iterations:
best_swap = None
best_cost = current_cost
# 尝试所有成对交换
for i in range(n):
for j in range(i + 1, n):
# 交换部门i和j
test_layout = current_layout.copy()
pos_i = np.argwhere(test_layout == i)[0]
pos_j = np.argwhere(test_layout == j)[0]
test_layout[tuple(pos_i)] = j
test_layout[tuple(pos_j)] = i
test_cost = calculate_cost(test_layout, flow_matrix, distance_matrix_func)
if test_cost < best_cost:
best_cost = test_cost
best_swap = (i, j)
if best_swap is None:
break # 未找到改进
# 应用最佳交换
i, j = best_swap
pos_i = np.argwhere(current_layout == i)[0]
pos_j = np.argwhere(current_layout == j)[0]
current_layout[tuple(pos_i)] = j
current_layout[tuple(pos_j)] = i
current_cost = best_cost
iteration += 1
improvement_history.append({
"iteration": iteration,
"swap": best_swap,
"cost": current_cost
})
return {
"final_layout": current_layout,
"final_cost": current_cost,
"iterations": iteration,
"improvement_history": improvement_history,
"improvement_percent": (improvement_history[0]['cost'] - current_cost) /
improvement_history[0]['cost'] * 100
}
4. 区块布局生成
def generate_block_layout(departments: list, space_requirements: dict,
facility_dimensions: tuple, rel_chart: dict):
"""
根据空间需求生成区块布局
"""
width, height = facility_dimensions
total_space = width * height
# 计算空间分配
total_required = sum(space_requirements.values())
layouts = []
# 简单的条带式布局
x_pos = 0
y_pos = 0
max_height_in_row = 0
for dept in departments:
required = space_requirements.get(dept, 100)
# 计算区块尺寸(大致为正方形)
block_width = np.sqrt(required)
block_height = required / block_width
if x_pos + block_width > width:
# 移动到下一行
x_pos = 0
y_pos += max_height_in_row
max_height_in_row = 0
layouts.append({
"department": dept,
"x": x_pos,
"y": y_pos,
"width": block_width,
"height": block_height,
"area": required
})
x_pos += block_width
max_height_in_row = max(max_height_in_row, block_height)
return {
"blocks": layouts,
"facility_dimensions": facility_dimensions,
"total_space_used": sum(b['area'] for b in layouts),
"utilization": sum(b['area'] for b in layouts) / total_space * 100
}
5. 布局评估
def evaluate_layout(layout: list, flow_data: dict, rel_chart: dict):
"""
评估布局质量
"""
# 计算质心
centroids = {}
for block in layout:
centroids[block['department']] = (
block['x'] + block['width'] / 2,
block['y'] + block['height'] / 2
)
# 计算总物料搬运成本
def euclidean_dist(c1, c2):
return np.sqrt((c1[0] - c2[0])**2 + (c1[1] - c2[1])**2)
def rectilinear_dist(c1, c2):
return abs(c1[0] - c2[0]) + abs(c1[1] - c2[1])
total_flow_cost = 0
flow_matrix = flow_data.get('flow_matrix', pd.DataFrame())
for dept1 in centroids:
for dept2 in centroids:
if dept1 != dept2 and dept1 in flow_matrix.index and dept2 in flow_matrix.columns:
flow = flow_matrix.loc[dept1, dept2]
dist = rectilinear_dist(centroids[dept1], centroids[dept2])
total_flow_cost += flow * dist
# 检查关系满意度
rel_score = 0
score_matrix = rel_chart.get('score_matrix', pd.DataFrame())
for dept1 in centroids:
for dept2 in centroids:
if dept1 < dept2 and dept1 in score_matrix.index:
target_score = score_matrix.loc[dept1, dept2]
dist = rectilinear_dist(centroids[dept1], centroids[dept2])
# 如果距离小于阈值则为相邻
is_adjacent = dist < 50 # 阈值
if target_score > 0 and is_adjacent:
rel_score += target_score
elif target_score < 0 and not is_adjacent:
rel_score -= target_score # 它们分开是好的
# 空间利用率
total_area = max(b['x'] + b['width'] for b in layout) * \
max(b['y'] + b['height'] for b in layout)
used_area = sum(b['area'] for b in layout)
return {
"flow_cost": total_flow_cost,
"relationship_score": rel_score,
"space_utilization": used_area / total_area * 100,
"adjacency_satisfaction": rel_score / (len(centroids) * (len(centroids) - 1) / 2),
"metrics": {
"total_departments": len(layout),
"total_area": total_area,
"used_area": used_area
}
}
6. 通道设计
def design_aisles(layout: list, traffic_data: dict):
"""
为布局设计通道系统
"""
aisles = []
# 主通道(贯穿设施长度)
main_width = traffic_data.get('main_aisle_width', 12) # 英尺
aisles.append({
"type": "main",
"width": main_width,
"orientation": "horizontal",
"y_position": max(b['y'] + b['height'] for b in layout) / 2
})
# 交叉通道
cross_width = traffic_data.get('cross_aisle_width', 8)
num_cross = traffic_data.get('num_cross_aisles', 2)
facility_width = max(b['x'] + b['width'] for b in layout)
for i in range(num_cross):
aisles.append({
"type": "cross",
"width": cross_width,
"orientation": "vertical",
"x_position": facility_width * (i + 1) / (num_cross + 1)
})
# 计算通道面积
main_length = facility_width
cross_length = max(b['y'] + b['height'] for b in layout)
total_aisle_area = (main_width * main_length +
num_cross * cross_width * cross_length)
return {
"aisles": aisles,
"total_aisle_area": total_aisle_area,
"aisle_percentage": total_aisle_area /
(facility_width * cross_length) * 100
}
流程集成
此技能与以下流程集成:
warehouse-layout-slotting-optimization.jsworkstation-design-optimization.js
输出格式
{
"layout": {
"blocks": [
{"department": "接收区", "x": 0, "y": 0, "width": 50, "height": 40},
{"department": "存储区", "x": 50, "y": 0, "width": 100, "height": 60}
]
},
"evaluation": {
"flow_cost": 15420,
"relationship_score": 85,
"space_utilization": 78
},
"aisles": {
"total_area": 1200,
"percentage": 12
},
"recommendations": [
"交换发货区和质检区以减少物料搬运"
]
}
最佳实践
- 从关系开始——定义紧密度要求
- 量化流量——使用实际的物料搬运数据
- 考虑扩展——为增长做规划
- 安全第一——紧急出口、危险品隔离
- 与用户验证——运营输入至关重要
- 比较备选方案——评估多个选项
约束条件
- 固定建筑约束
- 柱位位置
- 公用设施接入点
- 建筑规范和法规
- 预算限制