Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

Ruby에서 난수 생성

난수는 게임, 암호화 및 건물 시뮬레이션과 같은 다양한 목적에 유용합니다. 기술적으로 컴퓨터는 계산만으로 난수를 생성할 수 없습니다. 결정론적 장치에서 진정한 난수를 생성하는 것은 근본적으로 불가능합니다. 당신이 기대할 수 있는 최선은 무작위로 생성된 것처럼 나타나는 일련의 숫자인 의사 난수입니다.

이 기사에서는 Ruby에서 난수를 생성하는 다양한 방법을 살펴보겠습니다.

Kernel#rand로 난수 생성

시작하려면 rand를 사용하여 난수를 생성해 보겠습니다. 방법. 메서드가 인수 없이 호출되면 0.0보다 크거나 같고 1.0보다 작은 부동 소수점을 반환합니다.

rand()
> 0.7308136972953823

정수를 얻으려면 함수에 정수를 전달합니다. 이 함수는 0보다 크거나 같고 함수에 전달된 정수보다 작은 임의의 정수 값을 반환합니다. 다음을 실행할 때마다 0에서 7 사이의 숫자가 표시됩니다.

rand(8)
> 5

특정 범위 내의 난수에 대해 Range를 rand에 전달합니다. .

다음은 포함을 사용합니다. 하한에서 난수를 생성하는 범위(1 ), 최대(및 포함) 상한선(10) ).

rand(1..10)
> 6

다음 예는 비포함을 사용합니다. 하한에서 상한까지(포함하지 않음) 난수를 생성하는 범위입니다.

rand(1...10)
> 9

범위는 부동 소수점 값 사이일 수도 있습니다.

rand(1.5..3.0)
> 1.7494305393711571

rand와 함께 음수 범위 제한을 사용할 수도 있습니다. .

rand(-5..-1)
> -5

단일 음수를 전달하면 아래와 같이 놀라운 결과가 나타날 수 있습니다.

rand(-100)
> 94
 
rand(-0.5)
> 0.7692627344737486

이는 인수 n 때문입니다. rand로 전달 , rand 0에서 n.to_i.abs까지(포함하지 않음)의 난수를 반환합니다. . 위 예의 경우 (-100).to_i.abs 100입니다. 및 (-0.5).to_i.abs 0입니다. , 따라서 결과 난수입니다.

rand(0) 호출 rand()를 호출하는 것과 유사합니다. . 0.0에서 1.0(포함되지 않음) 사이의 임의의 숫자가 표시됩니다.

Kernel#srand로 재현 가능한 시퀀스 생성

난수를 생성하는 다음 방법으로 넘어가기 전에 먼저 srand 기능.

Kernel#srand Kernel#rand의 시드를 설정합니다. . 이를 사용하여 프로그램의 서로 다른 실행 간에 반복 가능한 난수 시퀀스를 생성할 수 있습니다.

이것이 의미하는 바를 이해하려면 먼저 난수가 생성되는 방식을 이해해야 합니다.

시드에서 "임의" 숫자 생성

앞서 언급했듯이 컴퓨터는 순수하게 계산에서 난수를 생성하지 않습니다. 그들이 하는 일은 무작위로 보이는 일련의 숫자를 생성하는 것입니다. 이를 위해 컴퓨터는 시드 번호로 시작하여 일부 알고리즘을 실행한 다음 무작위로 보이는 출력을 내보냅니다.

시드 번호는 다른 요소의 조합을 사용하여 컴퓨터에 의해 생성됩니다. 타임스탬프, 프로그램의 프로세스 ID 등 이러한 요소는 난수를 생성하기 위한 각 요청에 따라 다르기 때문에 시드 번호는 항상 달라서 다른 번호 시퀀스를 생성하므로 결과적으로 난수 출력이 됩니다. 동일한 시드로 알고리즘을 실행하면 매번 동일한 숫자 시퀀스를 얻을 수 있습니다. 이것은 Kernel#srand 할 수 있습니다.

srand 일반적으로 테스트에 사용됩니다. 무작위이지만 테스트하기에 충분히 예측 가능한 값을 사용하여 무작위성을 처리하는 앱의 코드를 테스트하는 데 유용할 수 있습니다. 또한 버그를 분리하거나 재현하는 데 도움이 될 수 있습니다.

아래에서는 srand를 사용합니다. 시드를 설정한 다음 rand를 호출합니다. 먼저 몇 개의 개별 난수를 생성한 다음 몇 개의 난수 시퀀스를 생성합니다.

srand(777)
 
rand()
> 0.152663734901322
 
rand()
> 0.3023566097075212
 
10.times.map { rand(10) }
> [7, 1, 7, 4, 7, 9, 8, 7, 2, 0]
 
10.times.map { rand(10) }
> [1, 2, 4, 5, 7, 1, 7, 2, 2, 7]

srand를 실행하면 동일한 시드로 다시 동일한 호출을 수행하고 이전에 했던 것과 동일한 호출을 수행하면 동일한 난수를 얻는 것을 볼 수 있습니다.

srand(777)
 
rand()
> 0.152663734901322
 
rand()
> 0.3023566097075212
 
10.times.map { rand(10) }
> [7, 1, 7, 4, 7, 9, 8, 7, 2, 0]
 
10.times.map { rand(10) }
> [1, 2, 4, 5, 7, 1, 7, 2, 2, 7]

난수로 난수 생성

Random 클래스를 사용하여 난수를 생성할 수도 있습니다.

클래스 메소드 rand Kernel#rand의 기본 기능을 제공합니다. 부동 소수점 값의 더 나은 처리와 함께.

Random.rand(1...10)
> 5

Kernel#rand와 달리 , Random.rand인 경우 음수 또는 0이 제공됩니다. 인수가 있으면 ArgumentError가 발생합니다.

정규 분포를 기반으로 난수 생성

현실 세계에서는 많은 것들이 정규 분포를 따르는 경향이 있습니다. 어떤 것이 해당하는 값의 범위가 있는 경우 모든 값의 균등한 분포를 얻는 경우는 거의 없습니다. 대부분 데이터의 대부분은 더 작은 범위에 속하는 경향이 있으며 더 작은 비율은 더 큰 범위에 속합니다. 성인 남성의 키를 예로 들어 보겠습니다. 기록된 가장 짧은 키는 54.6cm(21.5인치)이고 가장 높은 것은 267cm(8'9")입니다. 인구에서 남성의 키를 시뮬레이션하는 데이터를 생성하려는 경우 rand 이러한 제한으로. 8'9" 남자를 얻는 확률이 6' 남자를 얻는 것과 같기를 원하지 않습니다. 왜냐하면 후자가 더 일반적이기 때문입니다.

정규 분포를 따르는 다른 예는 다음과 같습니다.

  • 측정 오류
  • 혈압
  • 테스트 점수
  • 성인 남녀의 체중

이러한 사용 사례에 대해 더 나은 난수를 생성하려면 rubystats를 사용할 수 있습니다. 보석.

$ gem install rubystats
require 'rubystats'
 
adult_male_height = Rubystats::NormalDistribution.new(178, 10)
sample = 50.times.map { adult_male_height.rng.round(1) }
 
> [183.2, 169.5, 189.7, 171.9, 176.0, 179.3, 189.3, 175.3, 188.3, 190.0, 185.5, 182.8, 187.2, 191.6, 185.4, 178.4, 187.1, 183.3, 189.6, 179.7, 172.7, 174.4, 153.8, 197.4, 176.0, 174.6, 181.1, 182.0, 204.7, 185.2, 175.9, 167.7, 160.6, 170.5, 169.3, 160.6, 165.6, 166.4, 182.6, 179.7, 183.1, 171.9, 185.4, 175.4, 179.7, 176.9, 160.6, 173.8, 181.9, 190.2]

위의 경우 남성의 평균 키(178cm)와 표준편차 10cm를 NormalDistribution.new에 전달합니다. , 이 정규 분포에 속하는 50개의 값을 생성하기 전에 수학에 대해 궁금하시다면 이 기사가 흥미로울 것입니다.

무작위 반올림

이것으로 이 토론을 마치겠습니다. rand를 사용하여 Ruby에서 '임의' 숫자를 생성하는 몇 가지 다른 방법을 다루었습니다. , srand , RandomRubystats . 또한 '임의' 숫자가 생성되는 방식에 대해 간략하게 설명하고 결정론적 장치가 실제 난수를 생성할 수 없는 이유를 살펴보았습니다.

다루는 방법이 임의성을 요구하는 모든 사용 사례에 이상적이지는 않다는 점에 유의해야 합니다. 방법으로 생성된 정수 또는 부동 소수점 숫자는 게임에서 기회를 생성하거나 시뮬레이션을 만드는 데 이상적일 수 있지만 예를 들어 암호 재설정 토큰을 생성할 때와 같이 약간의 보안이 필요한 상황에서는 SecureRandom 사용을 고려해야 합니다. SecureRandom 사용 , 16진수, base64, 2진수 및 UUID 문자열을 생성할 수 있으며 일반 숫자에 비해 해독하기 훨씬 더 어렵습니다.

이 중 일부가 흥미로웠기를 바랍니다. 우리가 다룬 내용에 대해 의견이나 질문이 있는 경우 @AppSignal로 문의하세요. 다루고 싶은 주제에 대한 요청을 보낼 수도 있습니다.

2018년 8월 1일에 이 기사를 업데이트하여 SecureRandom에 대한 참고 사항을 포함했습니다.