array[i] == array[i+1] が可能な限り回避されるように、重複を含む要素のリストをシャッフルする「最良の」方法があるかどうか疑問に思っています。
重み付けされた広告表示に取り組んでおり (特定の広告主のローテーションあたりの表示数を調整できます)、同じ広告主が 2 回続けて表示されるのを避けたいと考えています。
array[i] == array[i+1] が可能な限り回避されるように、重複を含む要素のリストをシャッフルする「最良の」方法があるかどうか疑問に思っています。
重み付けされた広告表示に取り組んでおり (特定の広告主のローテーションあたりの表示数を調整できます)、同じ広告主が 2 回続けて表示されるのを避けたいと考えています。
これは、この質問によく似ています。あちらの例の A、B、C をあなたの広告主に置き換えると、同じ問題に到達すると思います。そのために提案された解決策のいくつかがあなたを助けることができるかもしれません。
基本的なランダム化では、大規模なセットで十分な分散が発生するはずです。
それをさらに最小限に抑えたい場合 (セットによっては必要ではない場合もあります)、最も簡単な方法は、ランダム化後に重複したものを確実に見つけて移動することです (ただし、パターンを作成することはできます)。より良いアプローチは、並列複製を含むサブセットを作成し、ランダム化をやり直すことです。
より小さなセットの場合、複製の数によっては、何もできない場合があります。したがって、非常に小さなセットの解決策は、適切な基本的なランダム化だけです (そして、最初の文に戻ります)。
個人的には、これを処理する最も簡単な方法は、配列をランダム化し、隣り合った同じ値を持つ 2 つの要素が見つかるまで反復することだと思います。同じ値が 2 つ並んでいるのを見つけたら、同じ値の別の場所と並んでいない場所が見つかるまで、配列を反復処理して、後の方を配列内の別の場所に移動します。値が見つからない場合は、そのままにして、配列の次の要素に進みます。これはおそらく最適な解決策ではありませんが、小さなデータ セットには問題なく、おそらく最も簡単にプログラムできます。
あなたが持っている可能性のある重複の最大数は何ですか? 2、3、どれ?
参考までに、私の(非常に)素朴なアプローチは次のようなものでした(実際にはLINQ / SQL呼び出しを使用していますが、これは単純化されています):
var advertisers = getAdvertisers();
var returnList = new List();
int totalWeight = sumOfAllAdvertisersWeight();
while (totalWeight > 0)
{
for (int i=0; i<advertisers.Count; i++)
{
if (advertisers[i].Weight > 0)
{
returnList.add(advertisers[i]);
advertisers[i].Weight--;
totalWeight--;
}
}
}
return returnList;
これにより、最後まで重複を回避できますが、後で returnList を逆方向にチェックして、テーリングの重複がある場合は、それらをミックスに配置してみてください。