| name | inventory-placement |
| description | Optimize inventory placement in warehouse storage. Use this skill when assigning SKUs to locations, considering pick efficiency, implementing zone-based storage, or managing storage location assignments. |
Inventory Placement
Optimize SKU and inventory placement for warehouse efficiency.
Installation
pip install numpy pandas
Quick Start
import numpy as np
def assign_sku_to_location(sku_velocity, locations, location_scores):
"""
Assign SKUs to locations based on velocity and accessibility.
Higher velocity SKUs get better (higher score) locations.
"""
# Sort SKUs by velocity descending
sorted_skus = sorted(sku_velocity.items(), key=lambda x: -x[1])
# Sort locations by score descending
sorted_locs = sorted(locations, key=lambda x: -location_scores[x])
assignments = {}
for (sku, _), loc in zip(sorted_skus, sorted_locs):
assignments[sku] = loc
return assignments
Common Patterns
Velocity-Based Slotting
def velocity_based_placement(skus, locations):
"""
Place high-velocity SKUs in prime locations.
skus: dict of {sku_id: {'velocity': picks_per_day, 'size': cube}}
locations: dict of {loc_id: {'zone': str, 'level': int, 'accessibility': float}}
"""
# Score locations by accessibility
scored_locs = sorted(
locations.items(),
key=lambda x: x[1]['accessibility'],
reverse=True
)
# Sort SKUs by velocity
scored_skus = sorted(
skus.items(),
key=lambda x: x[1]['velocity'],
reverse=True
)
assignments = {}
available_locs = list(scored_locs)
for sku_id, sku_data in scored_skus:
# Find best fitting location
for i, (loc_id, loc_data) in enumerate(available_locs):
assignments[sku_id] = loc_id
available_locs.pop(i)
break
return assignments
Zone-Based Storage
def zone_assignment(skus, zones):
"""
Assign SKUs to zones based on characteristics.
zones: dict with zone definitions and rules
"""
assignments = {}
for sku_id, sku_data in skus.items():
best_zone = None
best_score = -1
for zone_id, zone_rules in zones.items():
score = 0
# Check temperature requirement
if 'temp_range' in zone_rules and 'temp_req' in sku_data:
min_t, max_t = zone_rules['temp_range']
if min_t <= sku_data['temp_req'] <= max_t:
score += 10
# Check hazmat
if sku_data.get('hazmat', False):
if zone_rules.get('hazmat_allowed', False):
score += 5
else:
continue # Can't use this zone
# Velocity match
if 'velocity_class' in zone_rules:
if sku_data.get('velocity_class') == zone_rules['velocity_class']:
score += 8
if score > best_score:
best_score = score
best_zone = zone_id
assignments[sku_id] = best_zone
return assignments
Family Grouping
def group_by_family(skus, locations, family_zones):
"""
Keep SKU families together for efficient picking.
family_zones: dict mapping family_id to preferred zone
"""
# Group SKUs by family
families = {}
for sku_id, sku_data in skus.items():
family = sku_data.get('family', 'default')
if family not in families:
families[family] = []
families[family].append((sku_id, sku_data))
# Assign each family to contiguous locations
assignments = {}
zone_locations = {}
for zone_id, locs in locations.items():
zone_locations[zone_id] = list(locs)
for family_id, family_skus in families.items():
preferred_zone = family_zones.get(family_id, list(locations.keys())[0])
# Sort family SKUs by velocity
family_skus.sort(key=lambda x: -x[1].get('velocity', 0))
# Assign to contiguous locations in zone
available = zone_locations.get(preferred_zone, [])
for sku_id, _ in family_skus:
if available:
assignments[sku_id] = available.pop(0)
return assignments
Cube Utilization
def optimize_cube_utilization(skus, locations):
"""
Match SKU sizes to location sizes for optimal cube utilization.
"""
assignments = {}
# Sort SKUs by size descending
sorted_skus = sorted(
skus.items(),
key=lambda x: x[1]['cube'],
reverse=True
)
# Sort locations by capacity descending
available_locs = sorted(
locations.items(),
key=lambda x: x[1]['capacity'],
reverse=True
)
for sku_id, sku_data in sorted_skus:
sku_cube = sku_data['cube']
# Find smallest location that fits
best_fit = None
best_waste = float('inf')
for i, (loc_id, loc_data) in enumerate(available_locs):
if loc_data['capacity'] >= sku_cube:
waste = loc_data['capacity'] - sku_cube
if waste < best_waste:
best_fit = i
best_waste = waste
if best_fit is not None:
loc_id, _ = available_locs.pop(best_fit)
assignments[sku_id] = loc_id
return assignments
Replenishment Planning
def calculate_replenishment_locations(primary_assignments, reserve_locations, skus):
"""
Assign reserve/replenishment locations for each SKU.
"""
replenishment = {}
# Group reserve locations by zone
reserve_by_zone = {}
for loc_id, loc_data in reserve_locations.items():
zone = loc_data['zone']
if zone not in reserve_by_zone:
reserve_by_zone[zone] = []
reserve_by_zone[zone].append(loc_id)
for sku_id, primary_loc in primary_assignments.items():
sku_data = skus[sku_id]
zone = primary_loc.split('-')[0] # Extract zone from location
# Find reserve locations in same zone
available_reserve = reserve_by_zone.get(zone, [])
# Calculate how many reserve locations needed
daily_picks = sku_data.get('velocity', 0)
units_per_pallet = sku_data.get('units_per_pallet', 100)
days_coverage = 7
pallets_needed = (daily_picks * days_coverage) / units_per_pallet
reserve_slots = int(np.ceil(pallets_needed))
replenishment[sku_id] = {
'primary': primary_loc,
'reserve': available_reserve[:reserve_slots],
'replenish_qty': units_per_pallet
}
return replenishment