飲み会のグループわけを偏りなく行いたい
大勢のいる飲み会で、一度に全員が話すのは大変なのでいくつかのグループにわかれることがある。
色んな人と話すために、グループを入れ替えるのだが、ランダムに行うと、同じ人と何度も同じグループになったり、一度も同じグループにならないひとが出てくる。
なるべく偏りなく多くの人と話せるようにグループわけを行いたい。
解決方法を考える
ランダムで何パターンかグループわけをして、そのパターンのなかで一番ばらつきが小さいパターンを選ぶようにすれば単純に実装できないだろうか。
実装方法を考える
- 各メンバーごとに、これまでに何回同じグループになったのかというデータを保持する。
- そのデータから分散を計算する。
- 複数のグループ分けのパターンに対して、一番分散の小さいグループわけを選ぶ。
- これをグループの入れ替え回数だけ繰り返す。
コードで書くとこのような感じになる。
// roundCount: グループの入れ替え回数 for (let i = 0; i < roundCount; i++) { // もっともばらつきが小さいパターンを入れておくための変数 let leastVarianceGroups; // 比較するための値を入れるための変数 let leastMaxVariance = Number.MAX_VALUE; // tryCount回試行して、最もばらつきが少ないグループを採用する for (let j = 0; j < tryCount; j++) { const groups = makeGroups(names) // 分散を計算するための一時的なデータを作る const tempData = makeTempData(data, groups) // 分散を計算する const tempVariances = calculateVariances(tempData); // ばらつきを比較する値として一番大きい分散を選ぶ const tempMaxVariance = max(tempVariances); // ばらつきが小さいグループを採用する if (tempMaxVariance < leastMaxVariance) { leastMaxVariance = tempMaxVariance; leastVarianceGroups = groups; } } // 選ばれたグループわけを保持する rounds.push(leastVarianceGroups); // データを更新する updateData(data, leastVarianceGroups); }
実装して公開する
実装してみた。
ブラウザだけで動くアプリなのでユーザーの入力データをサーバーに送ったりはしない。使用したツールやプログラミング言語は以下の通り。
仕事でフロントエンドを触る機会が増えそうだったので、軽く触っておこうかなというのも実は目的の一つだった。久しぶりにReactを触って、最近のHookを使った書き方ができてよかったと思ってる。
デザインとか、細かいところの改善をすれば飲み会だけじゃなくてワークショップとか、色んなシチュエーションで使えるのではと思ってるので時間を見つけて細かい改善はやりたいなと思ってる。