Javscript의 Math.random과 정규분포에 대해

2022. 1. 28. 00:38·Programming/Javascript
728x90

요새 Nature of Code 라는 책을 간간히 보고 있는 중인데,

Javascript의 Math.random 이라는 함수가 단순히 난수를 생성하는 지 또는 정규분포를 나타내는지 궁금하여 알아보게 되었다.

 

수학적 지식이 뛰어나지는 못해 작성한 것이 정확하진 않을 수 있습니다. 참고만 해주세요... 오류가 있다면 지적 부탁드립니다.


ECMA 공식 문서를 참고해보면, Math.random에 대해 다음과 같이 적혀있다.

US: Returns a Number value with positive sign, greater than or equal to +0𝔽 but strictly less than 1𝔽, chosen randomly or pseudo randomly with approximately uniform distribution over that range, using an implementation-defined algorithm or strategy. This function takes no arguments.

KO: 구현-정의 알고리즘 또는 전략을 사용하여, 0 ≤ x < 1 범위에서 거의 균등한 분포로 랜덤 혹은 유사하게 양의 기호의 수를 반환한다.
이 함수는 arguments 를 가지지 않는다.

 

즉, 이 말에 따르면 다음 그림과 같이 Math.random 함수가 정규분포가 아닌 거의 균등한 확률로 난수를 만들어 내는 함수임을 알 수 있다.

Pseudo Random

그럼, 어떻게 해야 정규분포를 따르게 하는 함수를 만들 수 있을까.

이 부분에 관련해서는 여러 글들을 살펴보았고 간편하게 쓸 수 있을 법한 답변을 위주로 살펴보았다.

 

1.  만들어 놓은 라이브러리를 사용한다.

https://github.com/errcw/gaussian

 

GitHub - errcw/gaussian: A JavaScript model of the normal distribution

A JavaScript model of the normal distribution. Contribute to errcw/gaussian development by creating an account on GitHub.

github.com

 

이미 엄청난 사람들이 만들어 두었다. 그냥 다운받아 쓰기만 하면 된다.

하지만.. 나같이 그냥 라이브러리 같은 것을 사용하고 싶지 않은 사람들을 위해..

 

2. Math.random을 더해 평균값으로 정규화를 해본다.

function randomG(v) {
    var r = 0;
    for (var i = v; i > 0; i--) {
        r += Math.random();
    }
    return r / v;
}

가장 간단한 식으로 표현할 수 있다. 하지만 내가 원하는 정도의 분포는 나오지 않았다.

테스트 케이스가 큰 상황에서 사용하면 괜찮을 것 같기도 하다.

분포가 너무 고르지 못하다.

3. 척도(Scaled) 정규 분포의 사용

function gaussianRand() {
    let rand = 0;
    for (let i = 0; i < 6; i += 1) {
        rand += Math.random();
    }
    return rand / 6;
}
function gaussianRandom(start, end) {
    return Math.floor(start + gaussianRand() * (end - start + 1));
}

//출처: https://stackoverflow.com/questions/25582882/javascript-math-random-normal-distribution-gaussian-bell-curve/39187274#39187274

표준 편차가 1이 나오지 못한다. 그래서 완전한 정규 분포라고 보긴 어렵다고 한다.

극점에 있는 값들이 잘 안나오는 건 아쉽지만 괜찮은 코드인 것 같다.

4. Box-Muller 변환을 이용한 정규분포

function randn_bm(min, max, skew) {
    let u = 0, v = 0;
    while (u === 0) u = Math.random() //Converting [0,1) to (0,1)
    while (v === 0) v = Math.random()
    let num = Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v)

    num = num / 10.0 + 0.5 // Translate to 0 -> 1
    if (num > 1 || num < 0)
        num = randn_bm(min, max, skew) // resample between 0 and 1 if out of range

    else {
        num = Math.pow(num, skew) // Skew
        num *= max - min // Stretch to fill range
        num += min // offset to min
    }
    return num
}

//출처: https://stackoverflow.com/questions/25582882/javascript-math-random-normal-distribution-gaussian-bell-curve/39187274#39187274

이것도 마찬가지로 극 값이 잘 안나오긴 하지만, 평균값을 기준으로 균등하게 잘 나오는 것 같다.

하지만 수식을 이정도로 써야한다면 그냥 라이브러리 쓸 것 같기도 하다.


참고하면 좋은 사이트

 

Implementing a Simple Skew-normal PRNG in JavaScript

A quick overview of what skew-normal distributions are and a simple way to implement one in JavaScript without additional libraries.

spin.atomicobject.com

 

 

JavaScript Math.random Normal distribution (Gaussian bell curve)?

I want to know if the JavaScript function Math.random uses a normal (vs. uniform) distribution or not. If not, how can I get numbers which use a normal distribution? I haven't found a clear answer...

stackoverflow.com

 

저작자표시

'Programming > Javascript' 카테고리의 다른 글

만약 영상에 배속기능이 없다면? (ex. 학교 강좌)  (4) 2022.08.12
OverRiding(오버라이딩)과 OverLoading(오버로딩) 간단 정리  (0) 2021.06.05
간단하게 훑어보는 함수형 프로그래밍 #1  (0) 2020.05.04
ES6 Class  (0) 2020.04.23
한 줄짜리 if 문, for 문 그리고 함수  (0) 2020.04.22
'Programming/Javascript' 카테고리의 다른 글
  • 만약 영상에 배속기능이 없다면? (ex. 학교 강좌)
  • OverRiding(오버라이딩)과 OverLoading(오버로딩) 간단 정리
  • 간단하게 훑어보는 함수형 프로그래밍 #1
  • ES6 Class
기짜낭
기짜낭
생각이 많지만, 지금 내가 해야할 것을 하자.
  • 기짜낭
    So tired
    기짜낭
    • 분류 전체보기 (203) N
      • Programming (14) N
        • HTML (0)
        • CSS (0)
        • Javascript (18)
        • SVG (1)
        • SASS (SCSS) (1)
        • Node.js (1)
        • MySQL (2)
        • Canvas (8)
        • React (14)
        • Typescript (6)
        • C (3)
        • Java (1)
      • 활동 (57)
        • 개인 프로젝트 (33)
        • 나눔 서포터즈 3기 (9)
        • 멋쟁이 사자처럼 (7)
        • 0&1 C++ 자료구조 스터디 (0)
        • 제 9회 창업 아이디어톤 (3)
        • Poom (ZeroWasteShop) (3)
        • 해커톤 (2)
      • Algorism(PS) (27)
        • 알고리즘 정리 (5)
        • 백준 (18)
        • 프로그래머스 (4)
      • 취미 (5)
        • 강연 (5)
      • 생각 (16)
      • 기타 (8)
      • Reference (17)
        • 용어 사이트 (7)
        • 유용한 사이트 (10)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

    • ※ 예전 블로그
  • 인기 글

  • 태그

    1주에 1권씩
    1주 1권
    우테코
    에리카
    타입스크립트
    react
    tutorial
    백준
    디자인
    CSS
    나눔 서포터즈
    개념
    SVG
    대학
    TypeScript
    프로젝트
    3기
    개발자
    프론트엔드
    알고리즘
    한양대학교
    군대
    canvas
    Erica
    Javascript
    HTML
    독후감
    프로그래밍
    ES6
    HTML5
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
기짜낭
Javscript의 Math.random과 정규분포에 대해
상단으로

티스토리툴바