6

スキームでランダムを生成するにはどうすればよいですか? 特別なフォームはありますか、それとも手順を作成する必要がありますか? もしそうなら、どうすればいいですか?(2 つの戦略を入力し、ランダムに 1 つを返す、random-choice と呼ばれる手順を作成しようとしています。)

4

3 に答える 3

9

標準スキームは乱数ジェネレーターを提供しません。ほとんどのスキーム実装は乱数ジェネレーターを提供しますが、詳細が異なる傾向があります。移植可能な Scheme プログラムを書きたい場合、独自の乱数ジェネレータを作成するのは簡単です。ここにクヌースによる方法があります:

(define random
  (let ((a 69069) (c 1) (m (expt 2 32)) (seed 19380110))
    (lambda new-seed
      (if (pair? new-seed)
          (set! seed (car new-seed))
          (set! seed (modulo (+ (* seed a) c) m)))
      (/ seed m))))

呼び出す(random)と、0 (含む) と 1 (含まない) の間のランダムな分数が返されます。ランダムな分数は周期m で循環します。を呼び出す(random seed)と、乱数ジェネレーターのシードがリセットされるため、同じシードから始まる 2 つの乱数シーケンスは同一になります。YYYYMMDD の形式の日付は良いシードになります (上記のクヌースの誕生日です)。コインを投げたい場合は、次のように言います(if (< (random) 1/2) 'heads 'tails)

範囲内のランダムな整数が必要な場合があります。以下に示す関数は、範囲lo (含む) からhirandint (含まない)のランダムな整数を返します。loのデフォルトは 0 です。

(define (randint . args)
  (cond ((= (length args) 1)
          (floor (* (random) (car args))))
        ((= (length args) 2)
          (+ (car args) (floor (* (random) (- (cadr args) (car args))))))
        (else (error 'randint "usage: (randint [lo] hi)"))))

このような乱数は単純なシミュレーションには十分ですが、暗号化アプリケーションには適していないことに注意してください。興味があれば、私のブログで、暗号化アプリケーションに適したものを含む、いくつかの乱数ジェネレーターを用意しています。

于 2013-02-03T17:25:19.910 に答える
6

驚くべきことに、プロシージャーが呼び出されrandomます。正確な構文は、使用している Scheme インタープリターによって異なる場合がありますが (ドキュメントを読んでください!)、一般的な考え方は次のとおりです。

(random)
=> 0.9113789707345018

2 つの可能な値のうちの 1 つを返すために、これは Racket でトリックを実行します。

(define (random-choice a b)
  (if (zero? (random 2)) a b))

2に渡された引数randomにより、2 つの可能な値0またはのいずれかがランダムに返されることに注意してください1。したがって、(random 2)評価された場合は0thenaが返され、そうでない場合bは返されます。

(random-choice 4 2)
=> 4
(random-choice 4 2)
=> 2
于 2013-02-03T15:48:11.770 に答える
1

あなたのもう 1 つの質問は、DrRacket での宇宙船ゲームの実装に関するものだったので、Scheme とは、DrRacket の教育用言語の 1 つを意味していると思います。

DrRacket で利用可能な機能に関する情報を見つける方法は簡単です。randomたとえば、対話ウィンドウに書き込みます。カーソルを一番上に置き、F1 キーを押します。

randomhtdp-languagesのドキュメントは次のとおりです。

http://docs.racket-lang.org/htdp-langs/beginner.html?q=random#(def.htdp-beginner.((lib._lang/htdp-beginner..rkt)._random ) )

ランダムな値を返す 1 つの方法:

(list-ref (list "one" "two") (random 2))

ここで (ランダム 2) は 0 または 1 を返します。したがって、list-ref は、リストのインデックス 0 またはインデックス 1 を持つエントリを返します。

上記のアプローチを使用する利点は、3 つ以上の値に簡単に拡張できることです。

于 2013-02-03T18:40:57.010 に答える