Binary search

August 22, 2018

Slicker binary search: make jumps and then slow the speed of the jumps when you get closer to the target.

def binary_search(A, x):
    # assume sorted A as usual
    n = len(A)
    b, k = n//2, 0
    while b >= 1: # when b == 0 we've exhausted all window resolutions
        # b is the jump, k is the location
        while A[k+b] <= x and k+b < n:
            k += b
        b /= 2;
    if A[k] == x:
        return k

You can use this version of binary search to efficiently find where the value of a function changes (e.g. from False to True)

def change_search(ok, N):
    k = -1
    b = z = N # some index for which we know ok(N) == True
    while b >= 1:
        while !ok(k+b):
            k += b
    return k+1 # is the largest value which is False

You can then use this technique to $max$ of $ f $: find a position $k$ such that:

  • $ f\left( x \right) < f\left( x + 1 \right) $ when $ x < k $ and
  • $ f\left( x \right) > f\left( x + 1 \right) $ when $ x \geq k $

Hence the idea is use binary search to find largest value of $x$ such that $ f\left( x \right) < f\left( x + 1 \right) $

    def find_max_fn(fn, N):
       k = -1
       b = z = N
       while b >= 1:
           while fn(k+b) < f((k+b)+1):
               k += b
       return k+1