challenge シードを固定した乱数

シードを固定した疑似乱数を出力してください。
数回実行して、常に同じ結果が出力されることを確認してください。

Posted feedbacks - Nested

Flatten Hidden
一番乗り?
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.Arrays;
import java.util.Random;

public class RandomWithSeed {
    public static void main(String[] args) {
        final long seed = 1234567890L;
        final int count = 10;
        System.out.println(Arrays.toString(getRandomValuesWithSeed(seed, count)));
        System.out.println(Arrays.toString(getRandomValuesWithSeed(seed, count)));
        System.out.println(Arrays.toString(getRandomValuesWithSeed(seed, count)));
    }

    private static int[] getRandomValuesWithSeed(
            final long seed, final int count) {
        Random random = new Random(seed);
        int[] randomValues = new int[count];
        for (int i = 0; i < randomValues.length; i++) {
            randomValues[i] = random.nextInt();
        }
        return randomValues;
    }
}

何回やっても0.771320643266746が返ってきます。

1
2
srand(10)
p rand
組み込みの機能で。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#const CONST_SEED 32

*main
    dim pt, 2, 2
    
    repeat
        gosub *LResetPoint
        gosub *LRedraw
        
        wait 120
    loop
    stop
    
*LResetPoint
    dim pt, 2, 2
    
    // 座標4点は固定シード
    randomize CONST_SEED
    repeat length2(pt)
        pt(0, cnt) = rnd(640), rnd(480)
    loop
    
    return
    
*LRedraw
    redraw 2
    color : boxf
    
    // 色は適当シード => 毎回変化する
    randomize
    color rnd(256), rnd(256), rnd(256)
    boxf pt(0, 0), pt(1, 0), pt(0, 1), pt(1, 1)
    
    redraw
    return
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
using System;
class P
{
    static void Main()
    {
        Random rand = new Random(32);
        for (int i = 0; i< 10; i++)
                Console.WriteLine(rand.Next());
    }
}

常に 0.00115966796875 が出てきました。

1
2
srand 0;
print rand

pythonの標準モジュールです。 seedにはハッシュ可能な任意のオブジェクトをとれます。

1
2
3
4
5
#!/usr/bin/python
import random

random.seed('ja.doukaku.org')
print [random.random() for i in range(10)]
Haskell で。コンパイルしちゃうと表示されませんが、まあ runhaskell なりで

$ runhaskell random.hs

とでもすればちゃんと答えが返ってくると思います。

main :: IO Int

の Int のところを Float なり Double なり Char なりに変えることで別の型の乱数も生み出せたりします。結果は型できちんと一定になります。

Int, Integer : -1673289139
Float : 0.110407025
Double : 0.11040701265689151
Char : '\41423'
1
2
3
4
import System.Random

main :: IO Integer
main = return $ fst $ random $ mkStdGen 42

ちょっと遊んでみました。こちらのコードは擬似乱数を10個出力します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import java.util.Random;

public class RandomPrint {
    public static void main(String[] args) {
        Random random = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 10; i++) {
            sb.append(random.nextInt());
            sb.append(" ");
        }
        System.out.println(sb.toString());
    }
}

で、こちらは擬似乱数のシードを固定し、RandomPrint を数回実行し、常に同じ結果が出力されることを確認するテストケースです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import static jp.co.dgic.testing.common.virtualmock.MockObjectManager.*;
import static org.junit.Assert.*;
import java.util.*;
import jp.co.dgic.testing.common.virtualmock.*;
import org.junit.*;

public class RandomPrintTest implements IReturnValueProvider {
    private int seed;
    
    @Before
    public void setUp() {
        seed = new Random().nextInt();
    }
    
    @Test
    public void testMain() {
        // 擬似乱数のシードを固定する
        setReturnValueAtAllTimes("java.util.Random", "<init>", this);
        
        // 数回実行する
        final int count = 10;
        for (int i = 0; i < count; i++) {
            RandomPrint.main(null);
        }
        
        // 常に同じ結果が出力されることを確認する
        String arg1 = (String) getArgument("PrintStream", "println", 0, 0);
        assertNotNull(arg1);
        for (int i = 1; i < count; i++) {
            String arg2 = (String) getArgument("PrintStream", "println", i, 0);
            assertEquals(arg1, arg2);
        }
    }
    
    @Override
    public Object createReturnValue(Object[] arg0) {
        return new Random(seed);
    }
}

Squeak Smalltalk で。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
3 timesRepeat: [
    | rand |
    rand := Random seed: 123.
    Transcript cr.
    5 timesRepeat: [Transcript space; show: rand next]
]

"=>
 0.00096264341890935 0.1791479416094478 0.939454629989087 0.4139662265842623 0.530370201696814
 0.00096264341890935 0.1791479416094478 0.939454629989087 0.4139662265842623 0.530370201696814
 0.00096264341890935 0.1791479416094478 0.939454629989087 0.4139662265842623 0.530370201696814
"

 scalaで。

1
2
3
4
5
6
7
8
import    scala.util.Random

try {
    val    r:Random = new Random(args.first.toInt)
    1.to(10).foreach((_) => println(r.nextInt.toString))
} catch {
    case ex => ex.printStackTrace
}

srfi-27で.

1
2
3
4
5
6
(use srfi-27)
(define (main . args)
  (define s (make-random-source))
  (begin
    (random-source-pseudo-randomize! s 1 2)
    (print ((random-source-make-reals s)))))

こんな感じでいいのかしら。

1
2
3
4
$ groovy -e '3.times{println new Random(0).nextInt()}'
-1155484576
-1155484576
-1155484576
「?.」の片側型がシード値を固定した乱数を返す動詞です。
乱数の生成方法は、デフォルトでは、Mersenne Twister ですが
他の方法も選択可能なようです。
   ?.10000
6146
   ?.10000
6146
1
exit echo ?.10000
Limboには擬似乱数を扱うモジュールがあります。
randモジュールのinitメソッドにシードを与えます。

このプログラムを実行すると
57 98 98 72 50 40 81 88 52 38 
と表示され、何度実行しても同様です。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
implement d279;

include "sys.m";
include "draw.m";
include "rand.m";

sys: Sys;

d279: module
{
    init: fn(ctxt: ref Draw->Context, argv: list of string);
};

init(ctxt: ref Draw->Context, argv: list of string)
{
    sys = load Sys Sys->PATH;
    rand := load Rand Rand->PATH;
    i: int;
    
    rand->init(1024);
    
    for(i = 0; i < 10; i ++){
        sys->print("%d ", rand->rand(100));
    }
    sys->print("\n");
}

D 2.031で。 Mt19937インスタンスは一種の無限リストで、frontメソッドで先頭要素を読み出し (除去はしない)、popFrontで除去します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import std.random;

static const uint COUNT = 16;
static const uint SEED = 1337;
static const uint NUM_TRIALS = 42;

void main()
{
    uint[COUNT] randomNumbers;
    Mt19937 gen;        // 2^19937周期のMersenne Twister

    // シードを設定し、COUNT個の乱数を憶えておく
    gen.seed(SEED);
    foreach (i; 0 .. COUNT) {
        randomNumbers[i] = gen.front;
        gen.popFront;
    }

    foreach (i; 0 .. NUM_TRIALS) {
        // 同じシードを再設定し、出てくるCOUNT個の乱数が
        // 最初のと同じであることを確認
        gen.seed(SEED);
        foreach (j; 0 .. COUNT) {
            assert(randomNumbers[j] == gen.front);
            gen.popFront;
        }
    }
}

なでしこで。

1
2
3
10回
    1で乱数初期化
    10の乱数を表示
1
2
3
import random
random.seed(42)
print random.random()
1
2
srand(42);
echo rand();
TR1のRandomを使いました。gのコンストラクタ引数42が種です。なお、Boost.Randomでもほぼ同じコードになります。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <random>

void output_mt19937()
{
    std::tr1::mt19937 g(42);
    for (int i = 0; i < 5; ++i)
    {
        std::cout << g() << ' ';
    }
}

int main()
{
    for (int i = 0; i < 3; ++i)
    {
        std::cout << i << "回目の試行\n";
        output_mt19937();
        std::cout << std::endl;
    }
}
Visual Stuido 2008以降のテスティングフレームワークを使用。
値の確認をする程度なら、テスティングフレームワーク+SequenceEqual使えば目視の必要なんぞナッシング。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;
using System.Collections.Generic;

namespace TestProject1
{
    [TestClass()]
    public class FilterContextTest
    {
        [TestMethod()]
        public void RandomTest01()
        {
            int seed = 33;
            for (int i = 0; i < 13; i++)
            {
                var ary1 = CreateRandomArray(seed);
                var ary2 = CreateRandomArray(seed);
                Assert.IsTrue(ary1.SequenceEqual(ary2));
            }
        }

        public IEnumerable<int> CreateRandomArray(int seed)
        {
            Random rand = new Random(seed);
            return Enumerable.Range(1, 20).Select(num => rand.Next(num));
        }
    }
    //(中略)
}

伝統的BASICです。N88互換のつもりですが、ActiveBasic 2.62で動作確認しています。手元のリファレンスマニュアルを参考にN88でダメな構文は避けているつもりです。可読性のため、インデントしていますがご容赦ください。

RANDOMIZEが種を指定する命令語で、RNDが乱数を取得する関数です。それぞれ、Cでいうところのsrandとrandですね。なお、PRINT RND(1)の後ろのセミコロンは、ここで改行せず空白を置くという書式指定です(すなわち、シード固定の乱数という本題とは関係ありません)。

1
2
3
4
5
6
7
10 FOR I = 0 TO 3
20    RANDOMIZE 42
30    FOR J = 0 TO 5
40        PRINT RND(1);
50    NEXT J
60    PRINT
70 NEXT I

コマンドレットだけで

1
Get-Random -SetSeed 10
BASH の RANDOM は数値を代入すると初期化されます。
1
2
3
#!/bin/bash
RANDOM=0
echo $RANDOM

SQL Server 2008 で確認しました。

1
SELECT RAND(0);
こういうのでいいのだろうか?
1
let fixed_seed_rand num = Random.init 10; Random.float num;;
1
2
3
4
5
6
7
local i, j
for j = 1, 3 do
   math.randomseed(123)
   for i = 1, 10 do
      print(math.random())
   end
end

ガバレッジをあげる為と自分の勉強の為に投稿いたしました

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#import <Foundation/Foundation.h>
#define SEED srand(64)

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    int r;
    SEED;
    for (int i = 0; i < 10; i++) {
        r = rand();
    }
    NSLog(@"%d",r);    
    [pool drain];
    return 0;
}

well.. it's like I said!

Index

Feed

Other

Link

Pathtraq

loading...