Skip to content

Instantly share code, notes, and snippets.

@lazyatom
Created July 26, 2012 12:28
Show Gist options
  • Save lazyatom/3181755 to your computer and use it in GitHub Desktop.
Save lazyatom/3181755 to your computer and use it in GitHub Desktop.
Testing Harmonia's fairness algorithm
{"blog"=>{"Alice"=>2422, "Bob"=>2542, "Clare"=>2503, "Dave"=>2533},
"invoice"=>{"Alice"=>2504, "Bob"=>2493, "Clare"=>2535, "Dave"=>2468},
"fire_log"=>{"Alice"=>2488, "Bob"=>2500, "Clare"=>2479, "Dave"=>2533}}
require "pp"
# The essential algorithm from Harmonia
def random_available_person_for(task)
task_counts = @people.inject({}) do |h, person|
h[person] = assigned_tasks_ignoring(task, person).count
h
end
@people.select { |person| task_counts[person] == task_counts.values.min }.shuffle.first
end
def assigned_tasks_ignoring(task, person)
# This has been slightly modified for simplicity
@assignments[person] - [task]
end
# ... now to run it.
@people = %w(Alice Bob Clare Dave)
@tasks = %w(blog invoice fire_log)
base_stats = @people.inject({}) { |h,p| h[p] = 0; h }
statistics = {}
@tasks.each do |task|
statistics[task] = base_stats.dup
end
10000.times do
@assignments = Hash.new { [] }
@tasks.each do |task|
person = random_available_person_for(task)
@assignments[person] << task
statistics[task][person] += 1
end
end
pp statistics
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment