毎年クリスマスに、家族のプレゼント交換のために名前を描きます。これには通常、誰も配偶者を引っ張らなくなるまで、複数回の再描画が含まれます。そこで今年、私は独自の名前描画アプリを作成しました。このアプリは、たくさんの名前と許可されていない組み合わせを取り込んで、選択した贈り先を全員にメールで送信します。
現在、アルゴリズムは次のように機能します (疑似コード):
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
グラフ理論について詳しく知っている人は、ここでうまく機能する何らかのアルゴリズムを知っていますか? 私の目的では、これは機能しますが、興味があります。
編集: 電子メールはしばらく前に送信されたので、何かを学びたいと思っているだけなので、これをグラフ理論の質問として言い換えます。除外がすべてペアである特殊なケースにはあまり興味がありません (配偶者が互いに得られない場合など)。私は、解決策を見つけるのが難しい部分になるほどの除外がある場合にもっと興味があります。上記の私のアルゴリズムは単純な貪欲なアルゴリズムであり、すべての場合に成功するかどうかはわかりません。
完全な有向グラフと頂点ペアのリストから始めます。頂点ペアごとに、最初の頂点から 2 番目の頂点へのエッジを削除します。
目標は、各頂点に 1 つのエッジが入り、1 つのエッジが出るグラフを取得することです。