【Unity】UnityEngine.Randomの分布を軽く調べてみた


はじめに

UnityEngine.Randomが出力するランダム値がどのような分布に従うのか気になったので、調べてみました。

今回調べたものは以下の二つです。
・Random.value
・Random.Range(0f, 1f)

上記二つをそれぞれ100万回実行し、得られた数値でヒストグラムを作ってみました。

環境

Unity2018.1.0f2
Windows 10

Random.valueを100万回実行

Random.valueを100万回実行して得られた数値をヒストグラムにしてみました。

ヒストグラムから、Random.valueは一様分布に従っていることが読み取れます

ヒストグラムはExcelで作成しています。

Random.Range(0f, 1f)を100万回実行

Random.Range(0f, 1f)を100万回実行して得られた数値をヒストグラムにしてみました。

一様分布に従っていることが読み取れます

関連

【Unity道場スペシャル 2017札幌】乱数完全マスター
https://www.slideshare.net/UnityTechnologiesJapan/unity-2017-81056841

ソースコード

計測に使用したソースコードです。

乱数の計測

TestRandom.cs
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEditor;

public class TestRandom : MonoBehaviour
{
    const int k_LoopMax = 1000000;

    void Start()
    {
        Debug.Log("計測を開始します");

        var sb = new StringBuilder();
        sb.AppendFormat("計測日時 : {0}\n", System.DateTime.Now);
        sb.AppendFormat("Unityバージョン : {0}\n", Application.unityVersion);
        sb.AppendFormat("ループ回数 : {0}\n", k_LoopMax);
        sb.AppendFormat("i,UnityEngine.Random.value\n");

        for (int i = 0; i < k_LoopMax; i++)
        {
            sb.AppendFormat("{0},{1}\n", i, UnityEngine.Random.value);
            // sb.AppendFormat("{0},{1}\n", i, UnityEngine.Random.Range(0f, 1f));
        }

        Debug.Log("計測が完了しました");

        // CSV書き出し
        string csvText = sb.ToString();
        FileManager.Save("UnityRandom", csvText);

        Debug.Log("CSV書き出しが完了しました");

        EditorApplication.isPlaying = false;
    }
}

CSVの書き出し

FileManager.cs
using UnityEngine;
using System.IO;
using System;

/// <summary>
/// csvファイルの書き出しを行う
/// </summary>
public class FileManager
{
    // ファイル書き出し
    public static void Save(string name, string text)
    {
#if UNITY_EDITOR
        var now = System.DateTime.Now;
        var datetime = string.Format("{0}_{1:D2}_{2:D2}_{3:D2}_{4:D2}_{5:D2}", now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second);
        var path = Application.dataPath + "/" + string.Format("{0}_{1}.csv", name, datetime);

        System.IO.StreamWriter sw = new System.IO.StreamWriter(path, false, System.Text.Encoding.GetEncoding("shift_jis"));

        sw.Write(text);
        sw.Flush();
        sw.Close();

        UnityEditor.AssetDatabase.Refresh();
#endif
    }
}