既知のビットマスクからランダムなビット数を選択したいと思います。理想的には、これらのビットもランダムな順序で選択したいのですが、タスクは後で選択してシャッフルすることに分割できます。
データのいくつかの追加特性:
- ビットマスクの長さは 64 ビットです
- 選択されたビットの数は、4、8、16、または 32 のいずれかです
- 通常、40 ~ 60 ビットが設定されます (常に少なくとも半分)。
- 1 つのビットマスクに対して何百万ものランダムな選択が必要です (結果は統計シミュレーションに使用されます)
マスクと私が期待するものの例を次に示します(ランダムな4ビットを選択):
mask 0111111011111011111110111111111111111101111111100111101111111111
random4 ....1...........1........1...............1......................
shuffled bit positions: 41, 16, 4, 25
この例では、既に無効になっているため、ビット位置 0 を返すべきではありません。
これはアルゴリズムの既知のホットスポットであるため、可能な限り多くのパフォーマンスを絞り出したいと思います (ランダム選択のテストは、現在のランダム選択の実装よりも ~2 倍長くかかります)。私の現在の考えは、ビットマスクに設定されたビットの位置で最初のn
数字を埋めることです。char positions[64]
したがって、上記の例では、次のようになります[1, 2, 3, 4, 5, 6, 8, 9, ...]
。次に、0
との間の乱数の選択を開始n
して、ランダムなビット位置を選択します。各選択の後、位置を -1 に設定し、もう一度 -1 をヒットした場合はランダムな選択を繰り返します。
これは 4 つの数字を選択するのに最適ですが、32 の数字を選択すると、あまりにも頻繁に選択が繰り返されます。
もう 1 つのアイデアは、上記のように位置の配列を作成し、Fisher-Yates を使用してそれをシャッフルし、最初のn
位置を選択することです。これには、配列へのより多くの書き込みが必要であり、設定されたビットと同じ数の乱数を常に生成する必要があるため、4 ビットのみを選択するのはやり過ぎになる可能性があります。
このデータを生成するより高速な方法はありますか? シミュレーションの精度を目指しているので、1 秒間に何回ランダムな反復をチェックできるかが重要です。
言語はそれほど重要ではありませんが、ここでは C が優勢になると思います。