Depth-First Search
def solve
solve_recursively(Path.initial(state))
candidates.min_by(&:length) || Outcome.no_solution(state)
end
def solve_recursively(path)
return candidates << path.to_outcome if path.solved?
path.allowable_successors.each do |successor|
solve_recursively(successor)
end
end
Breadth-First Search
def solve
paths = [Path.initial(initial_state)]
until paths.empty?
path = paths.shift
return path.to_outcome if path.solved?
paths += path.allowable_successors
end
Outcome.no_solution(initial_state)
end
Slide 81
Slide 81 text
Breadth-First Search
Global visited list works now
Slide 82
Slide 82 text
Optimization
Do Less Things:
Reduce the size of the state space by
pruning branches from the graph
Slide 83
Slide 83 text
Optimization
Do Things Faster:
Less work per state
Slide 84
Slide 84 text
Optimization
Heuristics: Rules of Thumb
Less certain; may work in some circumstances, but not others
Slide 85
Slide 85 text
Heuristic: Move Active Robot First
States Considered
0
350000
700000
1050000
1400000
Original Algorithm Active First
Slide 86
Slide 86 text
Do Less Things: Check for Solutions at Generation Time
def solve
paths = [Path.initial(initial_state)]
until paths.empty?
path = paths.shift
return path.to_outcome if path.solved?
paths += path.allowable_successors
end
Outcome.no_solution(initial_state)
end
Slide 87
Slide 87 text
Do Less Things: Check for Solutions at Generation Time
1
2 3 4
5 6 7 8 9 10 11
12 13 14 15 16
Slide 88
Slide 88 text
Do Less Things: Check for Solutions at Generation Time
def solve
paths = [Path.initial(initial_state)]
until paths.empty?
path = paths.shift
successors = path.allowable_successors
solution = successors.find(&:solved?)
return solution.to_outcome if solution
paths += successors
end
Outcome.no_solution(initial_state)
end
Slide 89
Slide 89 text
Do Less Things: Check for Solutions at Generation Time
1
2 3 4
5 6
X X
X
X
X
X
X
X
X
16
Slide 90
Slide 90 text
Do Less Things: Check for Solutions at Generation Time
0
800,000
1,600,000
2,400,000
3,200,000
Original Algorithm Check at Generation
Total States Considered
Slide 91
Slide 91 text
Do Things Faster: Precompute stopping cells
Slide 92
Slide 92 text
Do Things Faster: Precompute stopping cells
States / second
0
675
1350
2025
2700
Original Algorithm Pre-compute Stops
Slide 93
Slide 93 text
Do Less Things / Do Things Faster:
Treat non-active robots as equivalent
Slide 94
Slide 94 text
Do Less Things / Do Things Faster:
Treat non-active robots as equivalent
0
1,000,000
2,000,000
3,000,000
4,000,000
Original Algorithm Check at Generation Robot Equivalence
Total States Considered
Slide 95
Slide 95 text
Do Less Things / Do Things Faster:
Treat non-active robots as equivalent
States / second
0
750
1500
2250
3000
Original Algorithm Pre-compute Stops Robot Equiv.
Slide 96
Slide 96 text
Do Things Faster: Sorted Array vs Set
States / second
0
800
1600
2400
3200
Original Algorithm Pre-compute Stops Robot Equiv. Arrays not Sets
Slide 97
Slide 97 text
Do Things Faster: Less Object Creation
States / second
0
1250
2500
3750
5000
Original Algorithm Pre-compute Stops Robot Equiv. Arrays not Sets Less Objects
Slide 98
Slide 98 text
Do Things Faster:
Use Object Identity Instead of Deep Equality
States / second
0
1750
3500
5250
7000
Original Algorithm Pre-compute Stops Robot Equiv. Arrays not Sets Less Objects Object Identity
Slide 99
Slide 99 text
Final Results
Solving time (seconds)
0
750
1500
2250
3000
Original Active First Check at Gen. Pre-compute Robot Equiv. Arrays not Sets Less Objects Robot Identity
Slide 100
Slide 100 text
Demo
Slide 101
Slide 101 text
Future Ideas: Better Algorithms
A* Algorithm
Slide 102
Slide 102 text
A* Algorithm
Next state to expand is one with minimum
distance so far +
estimated distance to goal
Future Ideas: Better Heuristics
Move most-recently moved robots first
(MRU)
Slide 113
Slide 113 text
Future Ideas: Better Heuristics
Some combination of active robot
and MRU robots
Slide 114
Slide 114 text
Future Ideas: Better Heuristics
Sort movement directions intelligently
Slide 115
Slide 115 text
Future Ideas: More Optimizations
Pre-compute per-robot stopping positions
Slide 116
Slide 116 text
Future Ideas: More Optimizations
Use less objects and more primitive types
Slide 117
Slide 117 text
Future Ideas: More Optimizations
Parallelism
Slide 118
Slide 118 text
Acknowledgements
• Trever Yarrish of Zeal for the awesome graphics and visualizations
• The Zealots of Zeal for ideas, feedback, and pairing on the solver
• Michael Fogleman for some optimization ideas
• Trevor Lalish-Menagh for introducing me to the game
Slide 119
Slide 119 text
Questions ?
http://randycoulman.com
http://speakerdeck.com/randycoulman
http://speakerrate.com/randycoulman
Code is on Github
https://github.com/CodingZeal/robots
Slide 120
Slide 120 text
www
.codingzeal.com
@codingzeal
Thank You!
Randy Coulman
@randycoulman