Non-uniform random number

You are given numbers from t0.. tn and probabilities from p0.. pn which sum up to 1. Given a random number generator that generates random numbers uniformly between [0,1], how would generate a number in T which obey the specified probabilities.

Solution

  • Hint: Think of placing the probabilities along the number line and picking the number from T along this line.
  • Create a probability sum array p0, p0+p1, p0+p1+p2 ..
    def partial_sum(p)
    i = 0
    result = []
    result << 0
    while i < p.size
      result << result.inject(:+) + p[i]
    end
    end
    
  • Now generate a random number and find where it lies in this probability sum array
  • Use binary search to find it in O(log n)

    def search(arr, k)
    # Setup for binary search
    low = 0
    high = arr.size - 1
    mid = (low + high) / 2
    
    # Search for element until high and low become equal
    while low < high
      if arr[mid] == k
        return mid
      elsif arr[mid] < k
        low = mid + 1
      else
        high = mid - 1
      end
    
      # Return the next largest element to k from the array
      arr[mid] > k ? return mid : return mid + 1
    end
    end
    
  • Now index the array T and return the respective number

Code

def generate(t, p)
  # Create probability sum array (number line)
  probability = partial_sum(p)

  # Generate random number between [0,1]
  rand = get_random_number(0, t.size)

  # Return the matching element from t
  return t[search(probability, rand)]
end

Time Complexity

O(n) to setup the probability sum array and O(log n) to search each time.

results matching ""

    No results matching ""