これは SO に尋ねるには多すぎるかもしれませんが、問題は非常に興味深いと思うので、ここにいくつかの考えを示します。
Victor Hurdugaciが言うように、これは主に言語に依存しないアルゴリズムの問題です (ただし、以下の例が LINQ で実装されているのを見てみたいです!)
あなたの質問で説明されている問題は、完全な結果をもたらすことはできません。つまり、それは最適化問題です (したがって、制約統計アルゴリズムで解決することはできません)。結果の良さを示す何らかの関数 (フィットネス関数と呼ばれる) に基づいて、考えられるすべての結果のセットから最良の結果を見つけるアルゴリズムを見つける必要があります。
素朴なブルート フォース ソリューション (疑似コード)
人々のセットから始めます (ここでは単純化するために 4 人):
people = { a, b, c, d }
choose
演算子を使用して、固定サイズ (ここでは 2) のすべての可能なサブグループを見つけることができます。
groups = people.choose(2) // = { {a,b} {a,c} {a,d} {b,c} {b,d} {c,d} }
choose
演算子を再度使用して、サブグループのすべての可能な組み合わせを見つけることができます。
combi = groups.choose(4/2) // = { {ab,ac} {ab,ad} {ab,bc} {ab,bd}
// {ab,cd} {ac,ad} {ac,bc} {ac,bd}
// {ac,cd} {ad,bc} {ad,bd} {ad,cd}
// {bc,bd} {bc,cd} {bd,cd} }
明らかに、人々が同時に 2 つのグループに属することはできないため、無効な組み合わせをすべて削除します。
combi2 = combi.select(g => g.bigUnion().size == 4)
// = { {ab,cd}, {ac,bd}, {ad,bc} }
ここで、フィットネス関数に基づいて「最良の」アイテム、つまり好みを考慮して最高のスコアが得られる組み合わせを見つける必要があります。
result = combi2.maximumBy(g => fitness(g))
たとえば、 とにa
優先度があり、 に優先度がない場合、とよりも に対して高いスコアを返す必要があります。b
b
c
d
calculateScore
{ab,cd}
{ac,bd}
{ad,bc}
改善されたソリューション
この種の最適化問題を扱うアルゴリズムはいくつかあります。ヒル クライミングアルゴリズムがここに適していると思います。