设施布局优化器Skill facility-layout-optimizer

设施布局优化器是一款基于AI的工业工程技能,专门用于优化工厂、仓库等设施的物理布局。它通过分析物料流动数据、部门间关系,并应用CRAFT等经典算法,自动生成和评估布局方案,旨在最小化物料搬运成本、最大化空间利用率并提升整体运营效率。核心功能包括从-到图表分析、活动关系图绘制、区块布局生成、通道设计及布局方案评估。适用于供应链管理、物流规划、生产设施设计等领域。 关键词:设施布局优化,物料流分析,空间利用率,CRAFT算法,工厂布局设计,仓库规划,工业工程,供应链优化,布局评估,通道设计

精益生产 0 次安装 28 次浏览 更新于 2/25/2026

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.js
  • workstation-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": [
    "交换发货区和质检区以减少物料搬运"
  ]
}

最佳实践

  1. 从关系开始——定义紧密度要求
  2. 量化流量——使用实际的物料搬运数据
  3. 考虑扩展——为增长做规划
  4. 安全第一——紧急出口、危险品隔离
  5. 与用户验证——运营输入至关重要
  6. 比较备选方案——评估多个选项

约束条件

  • 固定建筑约束
  • 柱位位置
  • 公用设施接入点
  • 建筑规范和法规
  • 预算限制