Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Algorithms: CLRS in Ruby

listrophy
November 19, 2019

Algorithms: CLRS in Ruby

One of the most celebrated books in Computer Science academia is "Introduction to Algorithms," also known as "CLRS" after its 4 authors. It's the go-to (pun!) textbook for many intermediate college courses, and this talk will introduce some of its many wonderful algorithms in Ruby form, including: various sorting techniques, dynamic programming, and some fun graph techniques. If you want a theory-heavy lecture, this talk is NOT for you!

listrophy

November 19, 2019
Tweet

More Decks by listrophy

Other Decks in Programming

Transcript

  1. ALGORITHMS
    CLRS IN RUBY

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  5. rubyconf 2019
    COMPLEXITY

    View Slide

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

    View Slide

  7. 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

    View Slide

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

    View Slide

  9. rubyconf 2019
    SORTING

    View Slide

  10. rubyconf 2019
    INSERTION SORT

    View Slide

  11. 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

    View Slide

  12. rubyconf 2019
    INSERTION SORT DEMO

    View Slide

  13. rubyconf 2019
    INSERTION SORT
    COMPLEXITY
    O(n²)

    View Slide

  14. rubyconf 2019
    QUICK SORT

    View Slide

  15. 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

    View Slide

  16. rubyconf 2019
    QUICK SORT DEMO

    View Slide

  17. rubyconf 2019
    QUICK SORT
    COMPLEXITY
    O(n log n)

    View Slide

  18. rubyconf 2019
    SORTING
    TWITTER POLL

    View Slide

  19. rubyconf 2019
    BUCKET SORT

    View Slide

  20. 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

    View Slide

  21. rubyconf 2019
    BUCKET SORT DEMO

    View Slide

  22. rubyconf 2019
    BUCKET SORT
    COMPLEXITY
    O(n) ?

    View Slide

  23. rubyconf 2019
    DYNAMIC
    PROGRAMMING

    View Slide

  24. rubyconf 2019
    LONGEST COMMON
    SUBSEQUENCE

    View Slide

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

    View Slide

  26. 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

    View Slide

  27. 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)

    View Slide

  28. 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

    View Slide

  29. rubyconf 2019
    GRAPHS

    View Slide

  30. rubyconf 2019
    MINIMUM SPANNING
    TREE

    View Slide

  31. 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

    View Slide

  32. 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)

    View Slide

  33. rubyconf 2019
    SHORTEST PATH

    View Slide

  34. 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)

    View Slide

  35. rubyconf 2019
    MAX FLOW

    View Slide

  36. 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

    View Slide

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

    View Slide

  38. 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

    View Slide

  39. 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

    View Slide

  40. 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

    View Slide

  41. 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

    View Slide

  42. 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 *|)

    View Slide

  43. 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/

    View Slide