Skip to content

szymon-przybyl/weighted_random

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

51 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Weighted Random

Weighted randomization extension for ActiveRecord.

Gives ability to get weighted random record from particular database relation.

Installation

Gem

gem 'weighted_random'

Model

Generate model with weight and cumulative_weight integer attributes:

rails g model your_model [your_attributes] weight:integer cumulative_weight:integer

Or add these two attributes into migration of existing model:

create_table :your_table, do |t|
  t.integer :weight
  t.integer :cumulative_weight
end

It is a good idea to add index on cumulative_weight attribute:

add_index :your_table, :cumulative_weight

Based on Benchmark.bmbm times, it makes creating of records 2 times faster and getting a random record 11 times faster!

Finally, load weighted randomization stuff into desired model and set accessibillity of weight attribute:

class YourModel < ActiveRecord::Base
  weighted_randomizable
  attr_accessible :weight
end

Usage

Importing data

Just create records, each must contain weight value:

LastName.create [
  {:name => 'Smith',    :weight => 10},
  {:name => 'Johnson',  :weight => 8},
  {:name => 'Williams', :weight => 7},
  {:name => 'Jones',    :weight => 6},
  {:name => 'Brown',    :weight => 6},
  {:name => 'Davis',    :weight => 5},
  {:name => 'Miller',   :weight => 4},
  {:name => 'Wilson',   :weight => 3}
]

It automatically sets cumulative_weight attribute for each record.

Here is an example of importing data from CSV file:

db/seeds/last_names.csv:

name,weight
Smith,10
Johnson,8
Williams,7
Jones,6
Brown,6
Davis,5
Miller,4
Wilson,3

db/seeds.rb:

LastName.create(
  CSV.table(File.expand_path('seeds/last_names.csv', File.dirname(__FILE__))).collect(&:to_hash)
)

Weighted randomization

To get weighed random record simply run:

LastName.weighted_rand

Demonstration:

10.times { puts LastName.weighted_rand.name }
Johnson
Brown
Johnson
Smith
Smith
Jones
Smith
Williams
Miller
Jones

Author

Szymon Przybył (github.com/apocalyptiq)

About

Weighted randomization extension for ActiveRecord

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages