Slide 1

Slide 1 text

ALGORITHMS CLRS IN RUBY

Slide 2

Slide 2 text

rubyconf 2019 BRAD GRZESIAK ‣ 2002 ICPC WORLD FINALS: 11TH PLACE ‣ FORMER AEROSPACE ENGINEER ‣ FOUNDER/CEO OF BENDYWORKS ‣ PORTED matrix TO ruby @LISTROPHY

Slide 3

Slide 3 text

rubyconf 2019 SYLLABUS ‣ COMPLEXITY ‣ INSERTION SORT ‣ QUICK SORT ‣ BUCKET SORT ‣ LONGEST COMMON SUBSEQUENCE ‣ MINIMUM SPANNING TREE ‣ SHORTEST PATH ‣ MAX FLOW

Slide 4

Slide 4 text

rubyconf 2019 INTRODUCTION TO ALGORITHMS ‣ CORMEN ‣ LEISERSON ‣ RIVEST ‣ STEIN

Slide 5

Slide 5 text

rubyconf 2019 COMPLEXITY

Slide 6

Slide 6 text

rubyconf 2019 COMPLEXITY hNoHereComes ( _ ) O thing(s)!

Slide 7

Slide 7 text

rubyconf 2019 COMPLEXITY 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 O(1) a[4] O(n) a.map O(log n) a.bsearch V D T X B F N R U W Y P H L J A C E G I K M O Q S U V W X Y Z

Slide 8

Slide 8 text

rubyconf 2019 COMPLEXITY O(1) O(log n) O(n) O(n log n) O(n²) great! ok hmmm uffda oh no

Slide 9

Slide 9 text

rubyconf 2019 SORTING

Slide 10

Slide 10 text

rubyconf 2019 INSERTION SORT

Slide 11

Slide 11 text

rubyconf 2019 SORTING INSERTION SORT (1...length).each do |right| subject = self[right] left = right - 1 while left > -1 && self[left] > self[right] self[left + 1] = self[left] left += 1 end self[left + 1] = subject end

Slide 12

Slide 12 text

rubyconf 2019 INSERTION SORT DEMO

Slide 13

Slide 13 text

rubyconf 2019 INSERTION SORT COMPLEXITY O(n²)

Slide 14

Slide 14 text

rubyconf 2019 QUICK SORT

Slide 15

Slide 15 text

rubyconf 2019 SORTING QUICK SORT def quicksort qsort_help(0, self.length - 1) end def qsort_help(p, r) return unless p < r q = partition(p, r) qsort_help(p, q - 1) qsort_help( q + 1, r) end def partition(p, r) x = self[r] i = p - 1 (p...r).each do |j| if self[j] <= x i += 1 swap(i, j) end end swap(i + 1, r) i + 1 end

Slide 16

Slide 16 text

rubyconf 2019 QUICK SORT DEMO

Slide 17

Slide 17 text

rubyconf 2019 QUICK SORT COMPLEXITY O(n log n)

Slide 18

Slide 18 text

rubyconf 2019 SORTING TWITTER POLL

Slide 19

Slide 19 text

rubyconf 2019 BUCKET SORT

Slide 20

Slide 20 text

rubyconf 2019 SORTING BUCKET SORT def bucket_sort b = Array.new(length) each_with_index do |val, idx| b[val] = val end replace(b) end def bucket_sort b = Array.new(length) mx = max (0...length).each do |i| idx = length * (self[i] / mx) b[idx] ||= [] b[idx] << self[i] end b.each(&:insertion_sort!) replace(b.flatten.compact) end

Slide 21

Slide 21 text

rubyconf 2019 BUCKET SORT DEMO

Slide 22

Slide 22 text

rubyconf 2019 BUCKET SORT COMPLEXITY O(n) ?

Slide 23

Slide 23 text

rubyconf 2019 DYNAMIC PROGRAMMING

Slide 24

Slide 24 text

rubyconf 2019 LONGEST COMMON SUBSEQUENCE

Slide 25

Slide 25 text

rubyconf 2019 DYNAMIC PROGRAMMING LONGEST COMMON SUBSEQUENCE ATCGG G C TTTGC ACCAC G C TAACA

Slide 26

Slide 26 text

rubyconf 2019 DYNAMIC PROGRAMMING LONGEST COMMON SUBSEQUENCE def command return @command if @command @command = Message::Command... @command ||= Message::Command... ... end def subject @subject ||= sentence .nouns .reject... end def command @command = Message::Command... @command ||= Message::Command... ... end def subject @subject ||= sentence.nouns.reject... end github.com/CoralineAda/alice

Slide 27

Slide 27 text

rubyconf 2019 DYNAMIC PROGRAMMING LONGEST COMMON SUBSEQUENCE ( ABCDEF 㱻 BDF ) A B C D E F B D F 0 1 1 1 1 1 0 1 1 2 2 2 0 1 1 2 2 3 if match?(top, left) 1 + ⬉ else [‐, ‏].max end O(n∙m)

Slide 28

Slide 28 text

rubyconf 2019 LONGEST COMMON SUBSEQUENCE def lcs setup compute_matrix @matrix.last.last end def setup @matrix = Array.new(@a.length + 1) do Array.new(@b.length + 1, 0) end end def compute_matrix (1..(@a.length)).each do |i| (1..(@b.length)).each do |j| compute_cell(i, j) end end end def compute_cell(i, j) @matrix[i][j] = if @a[i - 1] == @b[j - 1] matches(i, j) else does_not_match(i, j) end end def matches(i, j) @matrix[i - 1][j - 1] + 1 end def does_not_match(i, j) [ @matrix[i - 1][j], @matrix[i][j - 1] ].max end

Slide 29

Slide 29 text

rubyconf 2019 GRAPHS

Slide 30

Slide 30 text

rubyconf 2019 MINIMUM SPANNING TREE

Slide 31

Slide 31 text

rubyconf 2019 GRAPHS MINIMUM SPANNING TREE A H G F E I B C D 8 4 11 7 1 2 4 8 7 14 10 9 2

Slide 32

Slide 32 text

rubyconf 2019 GRAPHS MINIMUM SPANNING TREE (PRIM'S ALGORITHM) A H G F E I B C D 8 4 11 7 1 2 4 8 7 14 10 9 2 vertices.map { |u| u.key = ∞ } queue = PQueue.new(vertices) until queue.empty? u = queue.extract u.neighbors.each do |v, w| if queue.has?(v) && w < v.key v.parent = u v.key = w end end end A B H G F C I D E O(E+V log V)

Slide 33

Slide 33 text

rubyconf 2019 SHORTEST PATH

Slide 34

Slide 34 text

rubyconf 2019 GRAPHS SHORTEST PATH (DIJKSTRA'S ALGORITHM) A H G F E I B C D 8 4 11 7 1 2 4 8 7 14 10 9 2 queue = PQueue.new(nodes) until queue.empty? u = queue.extract_first adj[u.name].each_pair do |v, w| u.relax(v, w) end end class Node # ... def relax(other, w) if other.d > (d + w) other.d = d + w other.parent = self end end end A B H G F C I D E 0 8 4 12 15 9 11 25 21 14 19 O(E+V log V)

Slide 35

Slide 35 text

rubyconf 2019 MAX FLOW

Slide 36

Slide 36 text

rubyconf 2019 GRAPHS MAX FLOW (FORD-FULKERSON ALGORITHM) loop do # find any path from s to t p = find_path(s, t, edges.reject {|_names, e| e.capacity == 0 }) break if p.empty? # find the segement with least remaining capacity segs = segments(p) residual_capacity_p = segs.map do |uv| edges[uv].residual_capacity end.min segs.each do |(u, v)| # add that capacity to each edge edges[[u, v]].flow += residual_capacity_p # if we need to reverse the flow in the future: edges[[v, u]].flow = -edges[[u, v]].flow end end

Slide 37

Slide 37 text

rubyconf 2019 GRAPHS MAX FLOW (FORD-FULKERSON ALGORITHM) S D C B A T 16 13 4 10 12 9 14 7 20 4

Slide 38

Slide 38 text

rubyconf 2019 GRAPHS MAX FLOW (FORD-FULKERSON ALGORITHM) S D C B A T 16 13 4 10 12 9 14 7 20 4 4 4 4

Slide 39

Slide 39 text

rubyconf 2019 GRAPHS MAX FLOW (FORD-FULKERSON ALGORITHM) S D C B A T 16 13 4 10 12 9 14 7 20 4 12 4 4 12 4 12

Slide 40

Slide 40 text

rubyconf 2019 GRAPHS MAX FLOW (FORD-FULKERSON ALGORITHM) S D C B A T 16 13 4 10 12 9 14 7 20 4 12 4 4 12 7 4 12

Slide 41

Slide 41 text

rubyconf 2019 GRAPHS MAX FLOW (FORD-FULKERSON ALGORITHM) S D C B A T 16 13 4 10 12 9 14 7 20 4 12 11 11 12 7 4 19

Slide 42

Slide 42 text

rubyconf 2019 GRAPHS MAX FLOW (FORD-FULKERSON ALGORITHM) S D C B A T 16 13 4 10 12 9 14 7 20 4 12 0 0 11 11 0 12 7 4 19 O(E |f *|)

Slide 43

Slide 43 text

rubyconf 2019 THANK YOU @listrophy @bendyworks COMPLEXITY INSERTION SORT QUICK SORT BUCKET SORT LONGEST COMMON SUBSEQUENCE MINIMUM SPANNING TREE SHORTEST PATH MAX FLOW gitlab.com/listrophy/clrs-algorithms/