0에서 1 사이의 C++ 랜덤 수

0에서 1 사이의 C++ 랜덤 수

2022-06-04 last update

8 minutes reading C++
무작위 수는 최소 수에서 최대 수까지의 범위 내에서 생성된다.이 최소값과 최대값이 1보다 크다고 가정하십시오.이 범위 내에서 생성된 숫자를num로 만듭니다. 최소 숫자를min으로, 최대 숫자를max로 만듭니다. 이 경우 숫자를 0에서 1 사이로 변환하기 위해 다음 공식을 사용하십시오.
random_number = (num – min)/(max – min)
random\u 숫자는 현재 0과 1 사이여야 합니다.
다음 문제는 랜덤 수를 어떻게 생성하고 최소값과 최대값을 어떻게 확정하는가이다. 사실상 C++20규범에서 기술한 바와 같이 랜덤 수는 사실상 위조 랜덤 수이다.C++20 규범은 진정한 랜덤 수(비확정적 랜덤 수)를 생성하는 지침을 제공합니다.이런 진정한 랜덤 생성기의 문제는 컴파일러나 프로그래머의 책임이 비확정적인 랜덤 생성으로 간주되는 알고리즘을 제공하는 데 있다.본고는 불확실성 랜덤수를 토론하지 않는다.
위조 랜덤 수는 숫자 서열(순서)에 따라 생성되어 랜덤 수처럼 보인다.무작위 수의 생성은 이른바 씨앗이 필요하다.씨앗은 시작 값입니다.본고는 C++20에서 무작위 수 생성에 대한 기초 지식을 소개한다.결과 숫자가 1보다 크면 위의 공식을 사용하여 0에서 1 사이로 낮춥니다.프로그램에는 랜덤 수나 랜덤 수열을 얻기 위해 C++ 라이브러리가 포함되어야 합니다.

문장 내용







  • 할당 균등 분포


    균등 분포란 한 숫자의 확률이 서열 중의 숫자 총수의 1을 가리킨다.다음 순서를 고려합니다.
    0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100
    만약 이 열한 개의 숫자가 일련의 랜덤수라면, 모든 숫자는 열한 번의 출현에서 한 번 출현한 적이 있다.이것은 그것이 고르게 분포되어 있다는 것을 의미한다.실천에서 모든 사람이 한 번씩 나타나는 것은 아니다.한 개, 두 개 또는 세 개가 여러 번 나타날 수 있으며 일반적인 순서대로 나타나지 않습니다.
    랜덤 수가 40이면 프로그램을 사용해야 합니다
    random_number = (40 – 0)/(100 – 0)
    
    = 4/10 = 0.4
    여기,num은 40입니다.최소값은 0, 최대값은 100이다.

    이항 분포


    두 항목의 분포는 고르게 분포되지 않는다."Bi"는 2항식의 접두사로 2를 의미한다.C++에서 두 분포 값의 수량은 t로 표시됩니다.분포와 관련된 bi 수가 2와 3인 경우 t가 1인 경우 시퀀스는 다음과 같습니다.
    2, 3
    만약 같은bi수(2와 3)의 t가 2이면 서열은
    4, 12, 9
    만약 같은bi수(2와 3)의 t가 3이면 서열은
    8, 36, 54, 27
    만약 같은bi수(2와 3)의 t가 4라면 서열은
    16, 96, 216, 216, 81
    t는 4보다 클 수 있는 정수이다.t의 모든 값에 대해 시퀀스에 t+1개의 요소가 있습니다.서열은 선택한 비 수와 t 값에 달려 있습니다. 비 수는 13과 17과 같은 쌍일 수 있습니다.bi수의 합도 중요하다.서열은 이항식 정리에서 발전한 것이다.
    C++의 랜덤 라이브러리에는 다른 분포가 있습니다.

    선형 동여 엔진


    C++에는 많은 랜덤 엔진이 있습니다.선형 동여 엔진이 그 중의 하나다.이 엔진은 피드를 가져와 곱셈기와 곱한 다음 상수 c를 곱셈에 추가하여 첫 번째 무작위 수를 얻습니다.첫 번째 랜덤 수가 새 씨앗이 되었다.이 새 씨앗은 같은'a'를 곱하고 그 곱셈은 같은 c에 더하여 두 번째 무작위 수를 얻는다.두 번째 랜덤 수는 다음 랜덤 수의 새로운 씨앗이 된다.프로그래머의 요구에 따라 임의의 여러 개의 무작위 수에 대해 이 과정을 반복합니다.
    이곳의 씨앗은 색인 작용을 한다.기본 시드는 1입니다.
    linear\u Conformential\u 엔진의 구문은 다음과 같습니다.
    linear_congruential_enginelce
    lce는 프로그래머가 선택한 이름입니다.이 구문은 기본 피드 1을 사용합니다.이곳의 첫 번째 템플릿 매개 변수는 "unsigned int"로 전문화해야 한다.두 번째와 세 번째는'a'와 c의 실제 값을 가져야 한다. 네 번째는 예상한 최대 무작위 수의 실제 값을 가지고 1을 더해야 한다.
    값 2의 피드가 필요한 경우 구문은 다음과 같습니다.
    linear_congruential_enginelce(2)
    lce 뒤쪽 괄호 속의 씨앗을 주의하십시오.
    다음 프로그램은 기본 피드가 1인 linear\u Congressional\u 엔진을 사용합니다.
    #include 
    
    #include 
    
    using namespace std;
    
    
    int main()
    
    {
    
    linear_congruential_enginelce;
    
    
    cout <
    출력:
    4
    
    13
    
    40
    
    121
    
    364
    
    
    0
    
    499
    엔진의lce 대상의 실례화 방식을 주의하십시오.여기서'a'는 3, c는 1, 최대치, 희망은 숫자, m는 500입니다.m는 사실상 하나의 모델이다. 다음 문장을 보십시오.여기서 사용하는lce () 는 구조 함수가 아닙니다.이 연산자는 출력 시퀀스에서 엔진에 필요한 다음 랜덤 수를 되돌려줍니다.이 프로젝트의 최소값은 0이고 최대값은 499입니다. 이 값은 되돌아오는 숫자를 0과 1 사이의 숫자로 변환하는 데 사용할 수 있습니다. 아래를 참고하십시오.
    되돌아오는 첫 번째 랜덤 수는 4입니다.그것은 1 X 3 + 1 = 4와 같다.4 새로운 씨앗이 된다.다음 랜덤 수는 13으로 4 X 3+1=13과 같다.13 새로운 씨앗이 된다.다음 랜덤 수는 40입니다. 13 X 3+1=40입니다.이렇게 하면 후속 랜덤 수는 121과 364이다.
    다음 코드는 피드가 2인 linear\u Conformential\u 엔진의 사용을 설명합니다.
    linear_congruential_enginelce(2);
    
    
    cout <
    출력:
    7
    
    22
    
    67
    
    202
    
    607
    
    
    0
    
    999
    여기서 원하는 최대 랜덤 수는 1000입니다.이 프로젝트의 최소값은 여전히 0이며, 최대값은 현재 999입니다. 이 값을 사용하여 되돌아오는 숫자를 0에서 1 사이의 숫자로 변환할 수 있습니다. - 다음 참조.
    되돌아오는 첫 번째 랜덤 수는 7이다.그것은 2 X 3 + 1 = 7과 같다.7 새로운 씨앗이 된다.다음 랜덤 수는 22로 7 X 3 + 1 = 22입니다.22 새로운 씨앗이 되다.다음 랜덤 수는 67로 22 X 3 + 1 = 67입니다.이렇게 하면 후속 랜덤 수는 202와 607이다.
    다음 코드는 상기 공식을 사용하여 이 엔진에 대해 0과 1 사이의 무작위 수를 생성합니다.
    linear_congruential_enginelce(2);
    
    
    unsigned int num = lce();  // normal random number
    
    unsigned int min = lce.min();
    
    unsigned int max = lce.max();
    
    
    float random_number = ((float)(num - min))/((float)(max - min));
    
    
    cout <
    출력:
    0.00700701
    여기,num은 7이다.
    random_number = (7 – 0)/(999 – 0) = 7/999 = 0.00700701 rounded to 8 decimal places.
    선형 동여 엔진은 랜덤 라이브러리에서 유일한 전용 엔진이 아니다.다른 것도 있어요.

    default\u random\u 엔진


    이것은 마치 유니버설 엔진과 같다.그것은 무작위 수를 생성한다.서열의 순서가 확실하지 않다는 것을 보장할 수 없다.그러나 프로그래머는 순서를 모를 수도 있다.다음 두 줄은 이 엔진을 사용하는 방법을 보여 줍니다.
    random_device rd;
    
    default_random_engine eng(rd());
    random\u device는 에서 rd를 실례화하는 클래스입니다.엔진 매개 변수 목록에서 rd의 괄호를 주의하십시오.세일즈맨은 이 엔진을 실행해야 합니다. 아래를 참조하십시오.

    무작위 수 분포 클래스 uniform\u int\u 배포


    uniform\u int\u 배포
    어떤 숫자가 나타날 확률은 1을 제외하고 이런 숫자의 총수이다.예를 들어 10개의 출력 가능한 숫자가 있으면 각 숫자의 확률은 1/10이다.다음 코드는 다음과 같습니다.
    random_device rd;
    
    default_random_engine eng(rd());
    
    uniform_int_distributiondist(3, 12);
    
    
    cout <
    작성자 컴퓨터의 출력은 다음과 같습니다.
    9 8 3 5 12
    
    7 4 11 7 6
    불행히도 7은 두 번이나 나타났고 대가는 10번이었다.dist의 매개 변수는 숫자 3과 13입니다. (연속 정수 10개 포함)dist (eng) 는 다음 숫자를 되돌려주는 연산자입니다.그것은 엔진을 사용한다.int 템플릿의 전문적인 사용을 주의하십시오.
    이 경우num,min,max를 찾지 않고 상기 공식을 사용하여 0과 1 사이의 숫자를 얻을 필요가 없습니다.이것은 이 종류에float를 전문화하는float 등가물이 있기 때문이다.실행할 때마다 출력이 달라집니다.

    균등실분포


    uniform\ureal\u 분포는 uniform\u int\u 분포와 유사합니다.0과 1 사이의 숫자를 얻기 위해서는 0과 1을 매개 변수로 사용해야 합니다.다음 코드는 다음과 같습니다.
    random_device rd;
    
    default_random_engine eng(rd());
    
    uniform_real_distributiondist(0, 1);
    
    
    cout <
    작성자 컴퓨터의 출력은 다음과 같습니다.
    0.384051 0.745187 0.364855 0.122008 0.580874
    
    0.745765 0.0737481 0.48356 0.184848 0.745821
    부동 소수점 템플릿의 특수한 사용에 주의하십시오.실행할 때마다 출력이 달라집니다.

    이항식 분포


    이런 분포에서 각 출력수의 확률은 다르다.두 항목의 분포는 상기와 같다.다음 코드는 두 가지 분포를 사용하여 10개의 무작위 수를 생성하는 방법을 보여 줍니다.
    random_device rd;
    
    default_random_engine eng(rd());
    
    binomial_distributiondist(10);
    
    
    cout <
    작성자 컴퓨터의 출력은 다음과 같습니다.
    5 3 5 5 7
    
    6 6 5 8 3
    실행할 때마다 출력이 달라집니다.여기서 사용하는 템플릿은 int입니다.
    다음 코드는 상기 공식을 사용하여 이 분포에 대해 0과 1 사이의 무작위 수를 생성합니다.
    random_device rd;
    
    default_random_engine eng(rd());
    
    binomial_distributiondist(10);
    
    
    unsigned int num = dist(eng);  // normal random number
    
    unsigned int min = dist.min();
    
    unsigned int max = dist.max();
    
    cout <
    작성자 컴퓨터의 출력은 다음과 같습니다.
    0
    
    10
    
    
    7
    
    0.7

    더 좋은 랜덤 수


    UNIX Epoch 이후의 초는 씨앗으로 사용할 수 있습니다.해커는 씨앗을 알기 어렵다.다음 프로그램은 linear\u Conformential\u 엔진으로 설명합니다.
    #include 
    
    #include 
    
    #include 
    
    using namespace std;
    
    
    int main()
    
    {
    
    const auto p1 = chrono::system_clock::now();
    
    unsigned int seed = chrono::duration_cast<:chrono::seconds>(p1.time_since_epoch()).count();
    
    
    linear_congruential_enginelce(seed);
    
    
    cout <
    작성자 컴퓨터의 출력은 다음과 같습니다.
    91 274 823 470 411
    
    
    0
    
    999
    chrono 라이브러리가 이미 포함되어 있음을 주의하십시오.실행할 때마다 출력이 다릅니다.

    결론


    무작위 수를 0과 1 사이에 두는 가장 간단한 방법은 random\u 장치, 기본\u random\u 엔진과 통일된\u real\u 분포 (인자 0과 1 포함) 를 사용하는 것이다.사용하는 다른 엔진이나 분포는 공식random\unumber=(num-min)/(max-min)가 필요할 수 있습니다.