Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Secret santa algorithm

Every Christmas we draw names for gift exchanges in my family. This usually involves mulitple redraws until no one has pulled their spouse. So this year I coded up my own name drawing app that takes in a bunch of names, a bunch of disallowed pairings, and sends off an email to everyone with their chosen giftee.

Right now, the algorithm works like this (in pseudocode):

function DrawNames(list allPeople, map disallowedPairs) returns map     // Make a list of potential candidates     foreach person in allPeople         person.potentialGiftees = People         person.potentialGiftees.Remove(person)         foreach pair in disallowedPairs             if pair.first = person                person.Remove(pair.second)      // Loop through everyone and draw names     while allPeople.count > 0         currentPerson = allPeople.findPersonWithLeastPotentialGiftees         giftee = pickRandomPersonFrom(currentPerson.potentialGiftees)         matches[currentPerson] = giftee         allPeople.Remove(currentPerson)         foreach person in allPeople             person.RemoveIfExists(giftee)      return matches 

Does anyone who knows more about graph theory know some kind of algorithm that would work better here? For my purposes, this works, but I'm curious.

EDIT: Since the emails went out a while ago, and I'm just hoping to learn something I'll rephrase this as a graph theory question. I'm not so interested in the special cases where the exclusions are all pairs (as in spouses not getting each other). I'm more interested in the cases where there are enough exclusions that finding any solution becomes the hard part. My algorithm above is just a simple greedy algorithm that I'm not sure would succeed in all cases.

Starting with a complete directed graph and a list of vertex pairs. For each vertex pair, remove the edge from the first vertex to the second.

The goal is to get a graph where each vertex has one edge coming in, and one edge leaving.

like image 886
Eclipse Avatar asked Nov 07 '08 20:11

Eclipse


People also ask

How do you randomly assign Secret Santa?

Members of a group of friends, family, or coworkers draw random names to become someone's Secret Santa. The Secret Santa is given a wish list of gift ideas to choose from to give to their chosen giftee. After opening their present, the giftee has to guess which member of the group was their Secret Santa.

What is a Secret Santa generator?

What is Secret Santa? It's a free online Secret Santa gift exchange organizer / Kris Kringle generator! Organize a Secret Santa party with friends, family or even co-workers. After receiving the Secret Santa mail you can add your own wishlist, which will be delivered to your Secret Santa.

Which Secret Santa generator is the best?

Elfster is by far the best Secret Santa app on iOS and Android. In addition to creating a Secret Santa event with a custom name, time, and date, Elfster also lets organizers set a gift budget and offer gift suggestions to their mystery Kris Kringle through a built-in wish list feature.


1 Answers

Just make a graph with edges connecting two people if they are allowed to share gifts and then use a perfect matching algorithm. (Look for "Paths, Trees, and Flowers" for the (clever) algorithm)

like image 50
Watson Ladd Avatar answered Sep 20 '22 17:09

Watson Ladd