Babysitter facility-layout-optimizer
Facility layout optimization skill for material flow minimization and space utilization.
install
source · Clone the upstream repo
git clone https://github.com/a5c-ai/babysitter
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/a5c-ai/babysitter "$T" && mkdir -p ~/.claude/skills && cp -r "$T/library/specializations/domains/science/industrial-engineering/skills/facility-layout-optimizer" ~/.claude/skills/a5c-ai-babysitter-facility-layout-optimizer && rm -rf "$T"
manifest:
library/specializations/domains/science/industrial-engineering/skills/facility-layout-optimizer/SKILL.mdsource content
facility-layout-optimizer
You are facility-layout-optimizer - a specialized skill for optimizing facility layouts to minimize material flow and maximize space utilization.
Overview
This skill enables AI-powered facility layout optimization including:
- From-To chart analysis
- Activity relationship diagramming
- CRAFT and ALDEP algorithm implementation
- Block layout generation
- Aisle design and dimensioning
- Material flow visualization
- Space requirement calculation
- Layout alternative evaluation
Capabilities
1. From-To Chart Analysis
import numpy as np import pandas as pd def create_from_to_chart(flow_data: list): """ Create From-To chart from material flow data flow_data: list of (from_dept, to_dept, flow_volume, cost_per_unit) """ # Get unique departments depts = set() for from_d, to_d, _, _ in flow_data: depts.add(from_d) depts.add(to_d) depts = sorted(list(depts)) # Create matrix 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 # Calculate weighted flow 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. Activity Relationship Diagram
from dataclasses import dataclass from enum import Enum class Closeness(Enum): A = "Absolutely necessary" E = "Especially important" I = "Important" O = "Ordinary" U = "Unimportant" X = "Undesirable" @dataclass class RelationshipEntry: dept1: str dept2: str closeness: Closeness reason: str def create_relationship_chart(relationships: list): """ Create Activity Relationship Chart (REL chart) """ # Extract departments depts = set() for r in relationships: depts.add(r.dept1) depts.add(r.dept2) depts = sorted(list(depts)) # Create relationship matrix 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 score for layout optimization closeness_scores = { 'A': 64, 'E': 16, 'I': 4, 'O': 1, 'U': 0, 'X': -64 } # Create numeric matrix for algorithms 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 Algorithm
def craft_algorithm(initial_layout: np.ndarray, flow_matrix: np.ndarray, distance_matrix_func, max_iterations: int = 100): """ CRAFT (Computerized Relative Allocation of Facilities Technique) Improvement algorithm - starts with initial layout and iteratively improves """ 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 # Try all pairwise exchanges for i in range(n): for j in range(i + 1, n): # Swap departments i and 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 # No improvement found # Apply best swap 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. Block Layout Generation
def generate_block_layout(departments: list, space_requirements: dict, facility_dimensions: tuple, rel_chart: dict): """ Generate block layout from space requirements """ width, height = facility_dimensions total_space = width * height # Calculate space allocation total_required = sum(space_requirements.values()) layouts = [] # Simple strip-based layout x_pos = 0 y_pos = 0 max_height_in_row = 0 for dept in departments: required = space_requirements.get(dept, 100) # Calculate block dimensions (roughly square) block_width = np.sqrt(required) block_height = required / block_width if x_pos + block_width > width: # Move to next row 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. Layout Evaluation
def evaluate_layout(layout: list, flow_data: dict, rel_chart: dict): """ Evaluate layout quality """ # Calculate centroids centroids = {} for block in layout: centroids[block['department']] = ( block['x'] + block['width'] / 2, block['y'] + block['height'] / 2 ) # Calculate total material handling cost 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 # Check relationship satisfaction 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]) # Adjacent if distance < threshold is_adjacent = dist < 50 # Threshold if target_score > 0 and is_adjacent: rel_score += target_score elif target_score < 0 and not is_adjacent: rel_score -= target_score # Good that they're apart # Space utilization 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. Aisle Design
def design_aisles(layout: list, traffic_data: dict): """ Design aisle system for layout """ aisles = [] # Main aisle (runs length of facility) main_width = traffic_data.get('main_aisle_width', 12) # feet aisles.append({ "type": "main", "width": main_width, "orientation": "horizontal", "y_position": max(b['y'] + b['height'] for b in layout) / 2 }) # Cross aisles 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) }) # Calculate aisle area 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 }
Process Integration
This skill integrates with the following processes:
warehouse-layout-slotting-optimization.jsworkstation-design-optimization.js
Output Format
{ "layout": { "blocks": [ {"department": "Receiving", "x": 0, "y": 0, "width": 50, "height": 40}, {"department": "Storage", "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": [ "Swap Shipping and QC to reduce material handling" ] }
Best Practices
- Start with relationships - Define closeness requirements
- Quantify flows - Use actual material handling data
- Consider expansion - Plan for growth
- Safety first - Emergency egress, hazard separation
- Validate with users - Operations input essential
- Compare alternatives - Evaluate multiple options
Constraints
- Fixed building constraints
- Column locations
- Utility access points
- Building codes and regulations
- Budget limitations