回答紙

回答紙

私はいつも最善の方法が何であるか疑問に思いました。いいねMINBashのランダム性、つまり、とのMAX間で任意の正の整数を取得するプロセスは何ですか?

  1. 範囲は任意に大きくすることができます(または少なくとも最大2 32 -1)。
  2. 値は均等に分布されます(つまり、偏見はありません)。
  3. 効果がある

Bashでランダム性を達成する効果的な方法は、$RANDOM変数を使用することです。しかし、これは 0 と 2 15 -1 の間の値だけをサンプリングするので、すべての目的には十分ではないかもしれません。人々は通常モジュロを使用して目的の範囲に置きます。

MIN=0
MAX=12345
rnd=$(( $RANDOM % ($MAX + 1 - $MIN) + $MIN ))

$MAXさらに、これは正確に2 15 -1 = 32767で除算されない限り偏向を生成します。たとえば、$MIN0と9の場合、絶対32768または32769にすることはできない$MAXため、0〜7の値が8と9の値よりわずかに高い可能性があります。$RANDOMこの偏向は、範囲が増加するにつれてさらに激しくなる。たとえば、$MIN0が$MAX9999の場合、0から2767までの確率は4/32767ですが、 2768から9999までの確率は3/32767にすぎません

したがって、上記の方法は条件3を満足するが、条件1及び2を満足しない。

条件1と2を満たすように努力しながら、これまでに考えた最良の方法は、/dev/urandom次のものを使用することです。

MIN=0
MAX=1234567890
while
  rnd=$(cat /dev/urandom | tr -dc 0-9 | fold -w${#MAX} | head -1 | sed 's/^0*//;')
  [ -z $rnd ] && rnd=0
  (( $rnd < $MIN || $rnd > $MAX ))
do :
done

基本的に、暗号学的に強力な擬似乱数ジェネレータが/dev/urandom必要/dev/randomな場合場所時間またはハードウェア乱数ジェネレータ)、10進数以外のすべての文字を削除し、出力を長さに合わせて折りたたみ、先行$MAXゼロを削除します。偶然 0 だけ取得すると空になるので、$rndこの例ではrndに設定されます0。結果が私たちの範囲外であることを確認し、そうであれば繰り返します。ループをシミュレートするという精神では最初から定義されていないdo ... whileので、ボディが少なくとも1回実行されるように、whileループの「ボディ」をガードに強制的に適用しました。rnd

ここでは条件1と2を満たしていたと思いましたが、今は条件3を台無しにしました。これは少し遅いです。最大1秒程度かかります(運が良ければ10分の1秒程度)。実際にループが終了するという保証もありません(時間が増えるにつれて終了確率は1に収束しますが)。

Bashでは、事前に指定され、潜在的に大きな範囲内で偏向されていない任意の整数を取得する効率的な方法はありますか? (時間が許せば調査を続ける予定ですが、その間、ここで誰かが良いアイデアを持っているかもしれないと思いました!)

回答紙

  1. 最も基本的な(したがって移植可能な)アイデアは、十分に長いランダムなビット文字列を生成することです。任意のビット文字列を生成する方法はいくつかあります。 bashの組み込み変数を使用するか、and(または)を$RANDOM使用できます。乱数が大きい場合は再起動してください。od/dev/urandom/dev/random$MAX

  2. あるいは、外部ツールを使用することもできます。

    • Perlソリューション
      • 利点:携帯性に優れ、シンプルで柔軟です。
      • 対照:2 32 -1より大きい数字には適していません。
    • Pythonソリューション
      • 利点:シンプルで柔軟性があり、大容量データにも適しています
      • 欠点:携帯性が悪い
    • zshソリューション
      • 利点:zshを使用している人にはまだ良いです。
      • 反対:おそらく携帯性が低下します。

ベストアンサー1

もう一つの興味深いアプローチを見ました。ここ

rand=$(openssl rand 4 | od -DAn)

これ一つも良い選択のようです。任意のデバイスから4バイトを読み込み、間0の符号なし整数でフォーマットします2^32-1

rand=$(od -N 4 -t uL -An /dev/urandom | tr -d " ")

おすすめ記事