| name | warehouse-navigation |
| description | Navigate warehouse layouts and calculate efficient paths between locations. Use this skill when working with warehouse grids, aisle structures, rack positions, or calculating travel distances in distribution centers. |
Warehouse Navigation
Navigate warehouse layouts and calculate optimal paths between pick locations.
Installation
pip install numpy networkx heapq
Quick Start
import numpy as np
# Define warehouse layout (0=aisle, 1=rack)
warehouse = np.array([
[0, 0, 0, 0, 0, 0],
[1, 1, 0, 1, 1, 0],
[1, 1, 0, 1, 1, 0],
[0, 0, 0, 0, 0, 0],
[1, 1, 0, 1, 1, 0],
[0, 0, 0, 0, 0, 0]
])
# Find path from (0,0) to (5,5)
Warehouse Layout Representation
Grid-Based Layout
class WarehouseGrid:
def __init__(self, rows, cols, aisle_width=1):
self.rows = rows
self.cols = cols
self.aisle_width = aisle_width
self.grid = np.zeros((rows, cols))
self.locations = {} # SKU -> (row, col)
def add_rack(self, row_start, row_end, col_start, col_end):
"""Mark area as rack (not walkable)."""
self.grid[row_start:row_end, col_start:col_end] = 1
def add_location(self, sku, row, col):
"""Add a pick location for a SKU."""
self.locations[sku] = (row, col)
def is_walkable(self, row, col):
"""Check if position is an aisle."""
if 0 <= row < self.rows and 0 <= col < self.cols:
return self.grid[row][col] == 0
return False
def get_neighbors(self, row, col):
"""Get walkable neighbors of a position."""
neighbors = []
for dr, dc in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
new_row, new_col = row + dr, col + dc
if self.is_walkable(new_row, new_col):
neighbors.append((new_row, new_col))
return neighbors
Aisle-Based Layout
class AisleLayout:
def __init__(self, num_aisles, aisle_length, cross_aisles=None):
self.num_aisles = num_aisles
self.aisle_length = aisle_length
self.cross_aisles = cross_aisles or [0, aisle_length]
self.locations = {}
def add_location(self, sku, aisle, position, side='left'):
"""Add location: aisle number, position along aisle, side."""
self.locations[sku] = {
'aisle': aisle,
'position': position,
'side': side
}
def distance_between(self, loc1, loc2):
"""Calculate travel distance between two locations."""
if loc1['aisle'] == loc2['aisle']:
# Same aisle - direct travel
return abs(loc1['position'] - loc2['position'])
else:
# Different aisles - need to use cross aisle
aisle_distance = abs(loc1['aisle'] - loc2['aisle'])
# Find best cross aisle
best_distance = float('inf')
for cross in self.cross_aisles:
dist = (abs(loc1['position'] - cross) +
aisle_distance +
abs(loc2['position'] - cross))
best_distance = min(best_distance, dist)
return best_distance
Pathfinding Algorithms
A* Algorithm
import heapq
def astar_path(warehouse, start, end):
"""Find shortest path using A* algorithm."""
def heuristic(a, b):
return abs(a[0] - b[0]) + abs(a[1] - b[1])
open_set = [(0, start)]
came_from = {}
g_score = {start: 0}
f_score = {start: heuristic(start, end)}
while open_set:
current = heapq.heappop(open_set)[1]
if current == end:
# Reconstruct path
path = [current]
while current in came_from:
current = came_from[current]
path.append(current)
return path[::-1]
for neighbor in warehouse.get_neighbors(*current):
tentative_g = g_score[current] + 1
if neighbor not in g_score or tentative_g < g_score[neighbor]:
came_from[neighbor] = current
g_score[neighbor] = tentative_g
f_score[neighbor] = tentative_g + heuristic(neighbor, end)
heapq.heappush(open_set, (f_score[neighbor], neighbor))
return None # No path found
Dijkstra's Algorithm
def dijkstra_path(warehouse, start, end):
"""Find shortest path using Dijkstra's algorithm."""
distances = {start: 0}
previous = {}
pq = [(0, start)]
visited = set()
while pq:
dist, current = heapq.heappop(pq)
if current in visited:
continue
visited.add(current)
if current == end:
path = []
while current in previous:
path.append(current)
current = previous[current]
path.append(start)
return path[::-1]
for neighbor in warehouse.get_neighbors(*current):
if neighbor not in visited:
new_dist = dist + 1
if neighbor not in distances or new_dist < distances[neighbor]:
distances[neighbor] = new_dist
previous[neighbor] = current
heapq.heappush(pq, (new_dist, neighbor))
return None
Distance Calculations
def calculate_all_pairs_distances(warehouse, locations):
"""Pre-compute distances between all pick locations."""
location_list = list(locations.values())
n = len(location_list)
distances = np.zeros((n, n))
for i in range(n):
for j in range(i + 1, n):
path = astar_path(warehouse, location_list[i], location_list[j])
if path:
distances[i][j] = len(path) - 1
distances[j][i] = distances[i][j]
return distances
def travel_time(distance, speed=1.2):
"""Convert distance to travel time (default: 1.2 m/s walking speed)."""
return distance / speed
Warehouse Zones
class ZonedWarehouse:
def __init__(self):
self.zones = {}
self.zone_connections = {}
def add_zone(self, name, layout):
"""Add a zone with its own layout."""
self.zones[name] = layout
def connect_zones(self, zone1, exit1, zone2, entry2, distance):
"""Define connection between zones."""
self.zone_connections[(zone1, zone2)] = {
'exit': exit1,
'entry': entry2,
'distance': distance
}
def path_across_zones(self, start_zone, start_pos, end_zone, end_pos):
"""Find path that may cross multiple zones."""
if start_zone == end_zone:
return astar_path(self.zones[start_zone], start_pos, end_pos)
# Use zone-level pathfinding first, then detailed paths
# Implementation depends on zone topology
pass