mardi 4 avril 2017

How to implement semi-random groups with Ruby?

suppose I've got groups:

{1=>[1,1,1,1,1,1], 2=>[2,2,2], 3=>[3,3,3,3,3,3], 4=>[4,4,4,4,4,4]}

the keys represent teams, and the values within the arrays represent employees. Imagine I wish to match employees in a semi-random way. I want to make groups of 3's-5's like this:

[1,1,2,3,5], [1,2,3,4], [1,2,3,3], [1,3,4,1,4]

I have the wish to create groups and have a bias for matching team members of opposite teams, but not an absolute bias. Also you must match every member of each team with a group.

How would you solve this?

This is how I've done it:

group_by_team = records.group_by {|x| x.team_id}.values
mixed_groups = group_by_team.each{|x| x.shuffle!}

# take 1 element from each team and mix
# the number of teams is defined as a constant so we don't have to hit the db with a count
for index in (1..(TEAMS-1))
  zipped_groups ||= mixed_groups[0]
  zipped_groups = zipped_groups.zip(mixed_groups[index])
end 

# flatten the arrays to produce one large Array
# remove nil values from ziped steps with compact!
zipped_groups = zipped_groups.flatten!.compact!
lunch_groups = zipped_groups.each_slice(3)


# we can no longer reduce table size, so lets join two small lunch groups
if lunch_groups.any?{|x| x.size<3}
  lunch_groups = self.merge_last_two(lunch_groups)
end

But the problems with my implementation are vast. I have is groups size is fixed at 3. And its no exactly elegant, or efficient.

How would you make semi-random groups happen?




Aucun commentaire:

Enregistrer un commentaire