module RandomData::ArrayRandomizer

Public Instance Methods

rand() click to toggle source

Randomly chooses an element from an array >> [1,2,3].rand = 3 [].rand = nil

# File lib/random_data/array_randomizer.rb, line 11
def rand
  return self[Kernel.rand(self.size)]
end
roulette(k=1) { |i| ... } click to toggle source

Takes an array of non-negative weights and returns the index selected by a roulette wheel weighted according to those weights. If a block is given then k is used to determine how many times the block is called. In this case nil is returned.

# File lib/random_data/array_randomizer.rb, line 22
def roulette(k=1)
  wheel = []
  weight = 0
  # Create the cumulative array.
  self.each do |x|
    raise "Illegal negative weight #{x}" if x < 0
    wheel.push(weight += x)
  end
  # print "wheel is #{wheel.inspect}\n";
  # print "weight is #{weight.inspect}\n";
  raise "Array had all zero weights" if weight.zero?
  wheel.push(weight + 1) #Add extra element
  if block_given?
    k.times do 
      r = Kernel.rand() # so we don't pick up that from array.
      # print "r is #{r.inspect}\n";
      roll = weight.to_f * r
      # print "roll is #{roll.inspect}\n";
      0.upto(self.size - 1) do |i|
        if wheel[i+1] > roll
          yield i 
          break
        end # if
      end # upto
    end # if block_given?
    return nil
  else
    r = Kernel.rand() # so we don't pick up that from array.
    # print "r is #{r.inspect}\n";
    roll = weight.to_f * r
    # print "roll is #{roll.inspect}\n";
    0.upto(self.size - 1) do |i|
      return i if wheel[i+1] > roll
    end
  end
end