Skip to content

laiagc/hackUpc26

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 

Repository files navigation

Warehouse Optimizer

Mecalux Hackathon — "Warehouse Optimizer" challenge solution.

How to Compile

mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build . --config Release
# Produces: build/optimizer (Linux/Mac) or build/Release/optimizer.exe (Windows)

Requires: C++17 compiler (g++ 9+ or clang++ 10+ or MSVC 2019+), CMake 3.14+.

How to Run

./build/optimizer <case_dir> <output_csv> [options]

# Options:
#   --time=100                    Total wall-clock budget in seconds (default: 100)
#   --threads=N                   Parallel workers (default: hardware_concurrency)
#   --seed=42                     Single seed (default: 42)
#   --seed-list=1,2,3             Try specific seeds, keep best result
#   --random-seeds=N              Generate and try N random seeds
#   --quiet                       Suppress verbose output
#   --init=greedy|random          Initialization strategy (default: greedy)
#   --heuristic=default|weighted|randomized
#                                 Bay scoring heuristic (default: default)

# Basic usage (unchanged behaviour):
./build/optimizer cases/Case0 output/solution.csv

# Use all CPU cores for 25 s — recommended for presentations:
./build/optimizer cases/Case0 output/solution.csv --time=25 --random-seeds=8

# Explicit thread count:
./build/optimizer cases/Case0 output/solution.csv --time=25 --threads=12 --random-seeds=12

# 32 seeds in batches of 8 (4 batches × ~6 s each ≈ 25 s total):
./build/optimizer cases/Case0 output/solution.csv --time=25 --threads=8 --random-seeds=32

# Weighted heuristic + all cores:
./build/optimizer cases/Case0 output/solution.csv --time=25 --random-seeds=8 --heuristic=weighted

# Maximum diversity:
./build/optimizer cases/Case0 output/solution.csv --time=25 --random-seeds=16 --init=random --heuristic=randomized

Or use the helper script:

bash scripts/run_case.sh cases/Case0 25 42
bash scripts/run_all_public_cases.sh 25 42

Input Format

All inputs are CSV files in the case directory:

File Columns Description
warehouse.csv x,y Vertices of the orthogonal warehouse polygon (in order)
obstacles.csv x,y,width,depth Axis-aligned rectangular obstacles
ceiling.csv x,height Piecewise-constant ceiling height by X position
types_of_bays.csv id,width,depth,height,gap,nLoads,price Bay type specifications

Output Format

solution.csv:

id,x,y,rotation
1,0,0,0
2,500,0,90
...
  • id: bay type id
  • x,y: bottom-left corner after rotation
  • rotation: 0, 90, 180, or 270 degrees

Score Formula

Q = (Σ price_i / nLoads_i)^(2 - Σ area_i / area_warehouse)

Minimize Q. Lower is better.

  • Σ price_i / nLoads_i: sum of price-per-load for all placed bays (want this small → efficient bays)
  • Σ area_i / area_warehouse: fraction of warehouse covered (want this close to 1 → full coverage)
  • The exponent 2 - ratio decreases as coverage increases, which lowers Q

Strategy: Place many high-efficiency (low price/load) bays that cover as much area as possible.

Constraints

  1. Bays must be fully inside the warehouse polygon
  2. Bays cannot overlap each other (touching OK)
  3. Bays cannot overlap obstacles (touching OK)
  4. Bay height must not exceed the ceiling height at any point of its X footprint
  5. Rotations are arbitrary float degrees 0–360 (axis-aligned 0/90/180/270 during greedy; SA also explores continuous angles)

Algorithm

  1. Phase 1 — Initial solution (35% of time budget):
    • --init=greedy (default): Sort bay types by heuristic score. For each candidate grid position (snapped to walls/obstacles/placed-bay edges), place the best-fitting bay at all 4 axis-aligned rotations.
    • --init=random: Sample bay types by weighted probability, try random positions across the bounding box. 50% discrete rotations, 50% continuous.
  2. Phase 2 — Multi-start (up to 50% of time budget): Repeat Phase 1 with shuffled/re-scored orderings; keep the best result seen.
  3. Phase 3 — Simulated Annealing (remaining time): Add/remove/swap/rotate bays with temperature-controlled acceptance. Rotation moves include both discrete perturbations (±5/10/15/30/45/90°) and continuous random angles.

Heuristic modes (--heuristic):

Mode Score formula Best for
default nLoads/price Stable, reproducible runs
weighted nLoads/price + 0.3 × area/maxArea Cases where large bays pay off
randomized nLoads/price × (1 ± 0.15) Multi-seed diversity

Total time budget: configurable (default 100s).

How to Open the Visualization

cd web
python3 -m http.server 8080
# Open http://localhost:8080 in your browser

Then:

  1. Click each file input label to load the CSV files
  2. Click Render (or press Enter)
  3. The warehouse, obstacles, and bays are shown in SVG
  4. Click any bay for details in the sidebar
  5. Scroll to zoom, drag to pan

How to Add New Cases

mkdir cases/CaseX
# Copy and fill in:
#   cases/CaseX/warehouse.csv
#   cases/CaseX/obstacles.csv
#   cases/CaseX/ceiling.csv
#   cases/CaseX/types_of_bays.csv

bash scripts/run_case.sh cases/CaseX

Project Structure

warehouse-optimizer/
├── CMakeLists.txt
├── README.md
├── src/
│   ├── main.cpp         CLI entry point
│   ├── csv_parser.h/cpp  Input file parsing
│   ├── geometry.h/cpp    Polygon, rect, collision, spatial grid
│   ├── optimizer.h/cpp   Greedy + SA placement algorithm
│   ├── scoring.h/cpp     Q function computation
│   └── validator.h/cpp   Constraint validation
├── web/
│   ├── index.html        Visualizer UI
│   ├── viewer.js         SVG rendering + file loading
│   └── style.css         Dark-theme styling
├── scripts/
│   ├── run_case.sh
│   └── run_all_public_cases.sh
├── cases/
│   └── Case0/           Example case
└── output/              Generated solutions

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors