Slide 1

Slide 1 text

www .codingzeal.com @codingzeal Randy Coulman Solving Ricochet Robots Senior Software Engineer @randycoulman

Slide 2

Slide 2 text

Why Graphs, Trees & Algorithms? Hierarchical structures: Organization charts

Slide 3

Slide 3 text

Why Graphs, Trees & Algorithms? Relationship Maps: Social Networks like LinkedIn & Facebook

Slide 4

Slide 4 text

Why Graphs, Trees & Algorithms? Trip Planning

Slide 5

Slide 5 text

Why Graphs, Trees & Algorithms? Network Routing

Slide 6

Slide 6 text

What is Ricochet Robots?

Slide 7

Slide 7 text

Moves to get to

Slide 8

Slide 8 text

1 1. Blue Right Moves to get to

Slide 9

Slide 9 text

1 2 1. Blue Right 2. Blue Down Moves to get to

Slide 10

Slide 10 text

1 2 3 1. Blue Right 2. Blue Down 3. Blue Left Moves to get to

Slide 11

Slide 11 text

1 2 3 4 1. Blue Right 2. Blue Down 3. Blue Left 4. Green Right Moves to get to

Slide 12

Slide 12 text

1 2 3 4 5 1. Blue Right 2. Blue Down 3. Blue Left 4. Green Right 5. Green Down Moves to get to

Slide 13

Slide 13 text

1 2 3 4 5 6 1. Blue Right 2. Blue Down 3. Blue Left 4. Green Right 5. Green Down 6. Green Left Moves to get to

Slide 14

Slide 14 text

1 2 3 4 5 6 7 1. Blue Right 2. Blue Down 3. Blue Left 4. Green Right 5. Green Down 6. Green Left 7. Green Down Moves to get to

Slide 15

Slide 15 text

Characterizing the Problem Possible Board States (size of state space): 252 * 251 * 250 * 249 * 248 = 976,484,376,000

Slide 16

Slide 16 text

Characterizing the Problem Branching Factor: 9 - 20 possible moves from each state

Slide 17

Slide 17 text

Representing the Board • Board (Static: 16 x 16)

Slide 18

Slide 18 text

Representing the Board • Board (Static: 16 x 16) • Walls & Targets (changes each game)

Slide 19

Slide 19 text

Representing the Board • Board (Static: 16 x 16) • Walls & Targets (changes each game) • Goal (changes each turn)

Slide 20

Slide 20 text

Representing the Board • Board (Static: 16 x 16) • Walls & Targets (changes each game) • Goal (changes each turn) • Robot Positions (changes each move)

Slide 21

Slide 21 text

Representing Robot Movement 1 2 1 2 1

Slide 22

Slide 22 text

Trees

Slide 23

Slide 23 text

Search Algorithms See Jamis Buck’s book Basil & Fabian: Three Ways Through

Slide 24

Slide 24 text

Depth-First Search

Slide 25

Slide 25 text

Depth-First Search 1

Slide 26

Slide 26 text

Depth-First Search 1 2

Slide 27

Slide 27 text

Depth-First Search 1 2 3

Slide 28

Slide 28 text

Depth-First Search 1 2 3 4

Slide 29

Slide 29 text

Depth-First Search 1 2 3 4 5

Slide 30

Slide 30 text

Depth-First Search 1 2 3 4 5 6

Slide 31

Slide 31 text

Depth-First Search 1 2 3 4 5 6 7

Slide 32

Slide 32 text

Depth-First Search 1 2 3 4 5 6 7 8

Slide 33

Slide 33 text

Depth-First Search 1 2 3 4 5 6 7 8 9

Slide 34

Slide 34 text

Depth-First Search 1 2 3 4 5 6 7 8 9 10

Slide 35

Slide 35 text

Depth-First Search 1 2 3 4 5 6 7 8 9 10 11

Slide 36

Slide 36 text

Depth-First Search 1 2 3 4 5 6 7 8 9 10 11 12

Slide 37

Slide 37 text

Depth-First Search 1 2 3 4 5 6 7 8 9 10 11 12 13

Slide 38

Slide 38 text

Depth-First Search 1 2 3 4 5 6 7 8 9 10 11 12 13 14

Slide 39

Slide 39 text

Depth-First Search 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Slide 40

Slide 40 text

Depth-First Search 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

Slide 41

Slide 41 text

Depth-First Search 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

Depth-First Search: Cycles

Slide 44

Slide 44 text

Depth-First Search: Cycles

Slide 45

Slide 45 text

Depth-First Search: Cycles

Slide 46

Slide 46 text

Depth-First Search: Cycles

Slide 47

Slide 47 text

Depth-First Search: Cycles

Slide 48

Slide 48 text

Depth-First Search: Cycles

Slide 49

Slide 49 text

Depth-First Search: Cycles

Slide 50

Slide 50 text

Depth-First Search: Cycles

Slide 51

Slide 51 text

Depth-First Search: Cycles

Slide 52

Slide 52 text

Depth-First Search: Cycles 3 1 1 2 3 2 4

Slide 53

Slide 53 text

Depth-First Search: Cycles

Slide 54

Slide 54 text

Depth-First Search: Cycles

Slide 55

Slide 55 text

Depth-First Search: Cycles

Slide 56

Slide 56 text

Depth-First Search: Cycles

Slide 57

Slide 57 text

1 Depth-First Search: Cycles

Slide 58

Slide 58 text

1 2 Depth-First Search: Cycles

Slide 59

Slide 59 text

1 2 3 Depth-First Search: Cycles

Slide 60

Slide 60 text

1 2 3 4 Depth-First Search: Cycles

Slide 61

Slide 61 text

1 2 3 4 5 Depth-First Search: Cycles

Slide 62

Slide 62 text

Breadth-First Search

Slide 63

Slide 63 text

Breadth-First Search 1

Slide 64

Slide 64 text

Breadth-First Search 1 2

Slide 65

Slide 65 text

Breadth-First Search 1 2 3

Slide 66

Slide 66 text

Breadth-First Search 1 2 3 4

Slide 67

Slide 67 text

Breadth-First Search 1 2 3 4 5

Slide 68

Slide 68 text

Breadth-First Search 1 2 3 4 5 6

Slide 69

Slide 69 text

Breadth-First Search 1 2 3 4 5 6 7

Slide 70

Slide 70 text

Breadth-First Search 1 2 3 4 5 6 7 8

Slide 71

Slide 71 text

Breadth-First Search 1 2 3 4 5 6 7 8 9

Slide 72

Slide 72 text

Breadth-First Search 1 2 3 4 5 6 7 8 9 10

Slide 73

Slide 73 text

Breadth-First Search 1 2 3 4 5 6 7 8 9 10 11

Slide 74

Slide 74 text

Breadth-First Search 1 2 3 4 5 6 7 8 9 10 11 12

Slide 75

Slide 75 text

Breadth-First Search 1 2 3 4 5 6 7 8 9 10 11 12 13

Slide 76

Slide 76 text

Breadth-First Search 1 2 3 4 5 6 7 8 9 10 11 12 13 14

Slide 77

Slide 77 text

Breadth-First Search 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Slide 78

Slide 78 text

Breadth-First Search 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

Slide 79

Slide 79 text

Breadth-First Search 1 2 5 3 7 8 4 9 10 11 6 12 13 14 15 16

Slide 80

Slide 80 text

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

Slide 103

Slide 103 text

A* Algorithm 0

Slide 104

Slide 104 text

A* Algorithm 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0

Slide 105

Slide 105 text

A* Algorithm 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0

Slide 106

Slide 106 text

A* Algorithm 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 0

Slide 107

Slide 107 text

A* Algorithm 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 0

Slide 108

Slide 108 text

A* Algorithm 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 0

Slide 109

Slide 109 text

Future Ideas: Better Algorithms Collision Detection

Slide 110

Slide 110 text

Future Ideas: Better Algorithms Work Backwards

Slide 111

Slide 111 text

Work Backwards

Slide 112

Slide 112 text

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