random.uniform (0,1)이 0 또는 1을 생성 할 수 있습니까?


9

에서 문서 가 기회가 있다고한다 uniform(0,1)값을 생성 할 수 있습니다 0및이 1.

나는 uniform(0, 1)10000 번 실행 했지만 결코 0을 생성하지 않았습니다. 의 경우에도 uniform(0, 0.001).

또는 random.uniform(0,1)생성 할 수 있습니까 ?01


3
이론적으로는 가능하지만 실제로는 절대 발생하지 않습니다. 수학적 경우 표준 균일 확률 변수 1. 0의 구간에서 임의의 값을 취할 수있는 X ~ U(0,1), 다음이 P(X=x)있다 거의 확실하게 0 X의 모든 값에 대해. (간격에 가능한 많은 값이 있기 때문입니다.) 정확히 0 또는 1을 찾으려면 다른 기능을 사용해야합니다 (예random.choice
pault

1
@pault 거의 확실히 우리는 이산 분포하지 연속 간격이 있기 때문에 정말 여기에 이해가되지 않습니다 수학에서 매우 특별한 의미를 가지고 있습니다. 0과 1 사이에는 유한 한 수의 플로트 만 있습니다.
wim

2
@pault 그렇다면 OP가 구현에 대해 물을 때 왜 수학적으로 말하고 random.uniform있습니까?
wim

1
해당 문서가 정확하다면 0과 1을 모두 생성하는 방법에 대해 궁금합니다 . [0, 1과 같은)이 훨씬 쉽습니다 ( Math.random()예를 들어 JavaScript에서 작동 하는 방식).
Ry-

1
첫 번째 사람이 임의의 시드를 게시 random.uniform(0, 1)하면 첫 번째 통화에서 0을 반환하는 50 포인트 현상금
wim

답변:


13

uniform(0, 1)생산할 수는 0있지만 결코 생산 하지는 않습니다1 .

문서는 엔드 포인트가 있음을 알려줍니다 b 생성 된 값에 포함 :

종점 값 b은 방정식의 부동 소수점 반올림에 따라 범위에 포함되거나 포함되지 않을 수 있습니다 a + (b-a) * random().

따라서로 단순화 uniform(0, 1)된 공식 은 정확하게 생산할 수 있어야 합니다. 1.0 random () 1.0` 인 경우에만 발생합니다 .0 + (1-0) * random()1 * random()1random.random()exactly. However,*never* produces

random.random()문서 인용 :

[0.0, 1.0) 범위에서 다음 임의의 부동 소수점 숫자를 반환합니다.

표기법 [..., ...)은 첫 번째 값이 가능한 모든 값의 일부이지만 두 번째 값은 그렇지 않음을 의미합니다. random.random()대부분의 농산물 값에 의지 가까이1.0. 파이썬의 float유형은 IEEE 754 base64 부동 소수점 값으로 , 을 구성하는 많은 이진 분수 (1/2, 1/4, 1/5 등) 를 인코딩하며 random.random()생성 되는 값 은 단순히 2 ** -1(1/2)에서 2 ** -53(1/9007199254740992) 까지 이러한 53 개의 분획의 무작위 선택 .

그러나 1.0부동 소수점 숫자를 곱할 때 발생하는 반올림 오류와 함께 매우 가까운 값을 생성 할 수 있으므로 및의 일부 값에 b대해 생성 할 수 있습니다 . 그러나 및 해당 값 사이에 없습니다.ab01

random.random() 0.0을 생성하므로 a항상 사용할 수있는 값에 포함되어있다 random.uniform()( a + (b - a) * 0 == a). 생산할 수 있는 2 ** 53다른 값 random.random()(53 개의 이진 분수의 모든 가능한 조합)이 2 ** 53있기 때문에 그 일이 발생할 확률은 1 in (9007199254740992의 1)입니다.

따라서 random.random()생산할 수 있는 가장 높은 값 은 1 - (2 ** -53); b - a더 높은 random.random()값을 곱할 때 반올림이 시작되도록 충분히 작은 값을 선택하십시오 . 작을 b - a수록 그 가능성이 커집니다.

>>> import random, sys
>>> def find_b():
...     a, b = 0, sys.float_info.epsilon
...     while random.uniform(a, b) != b:
...         b /= 2
...     else:
...         return b
...
>>> print("uniform(0, {0}) == {0}".format(find_b()))
...
uniform(0, 4e-323) == 4e-323

를 누르면 b = 0.01023 번을 나눈 값이며, 위의 값은 1019 나누기 후에 운이 좋았다는 의미입니다. 지금까지 찾은 가장 높은 값 (위의 루프에서 위의 함수를 실행 max())은 8.095e-320(1008 나누기)이지만 더 높은 값이있을 수 있습니다. 그것은 모두 우연의 게임입니다. :-)

또한 사이하지 많은 이산 단계가있는 경우 발생할 수 ab때 같은 ab높은 지수를 가지고 지금까지 아파트로 나타날 수 있습니다. 부동 소수점 값은 여전히 ​​근사치이며 인코딩 할 수있는 값의 수는 한정되어 있습니다. 예를 들어, sys.float_info.max과 의 차이는 1 진 sys.float_info.max - (2 ** 970)소수만이므로 50-50 확률 random.uniform(sys.float_info.max - (2 ** 970), sys.float_info.max)sys.float_info.max다음과 같습니다.

>>> a, b = sys.float_info.max - (2 ** 970), sys.float_info.max
>>> values = [random.uniform(a, b) for _ in range(10000)]
>>> values.count(sys.float_info.max)  # should be roughly 5000
4997

5

"여러 번"으로는 충분하지 않습니다. 10,000이면 충분하지 않습니다. random.uniform2 ^ 53 (9,007,199,254,740,992)의 다른 값 중에서 선택합니다. 두 가지 에 관심 이 있습니다. 따라서 정확히 0 또는 1의 값을 얻기 전에 몇 조의 임의의 값 을 생성해야 하므로 가능할 수는 있지만 절대로 관찰하지는 않을 것입니다.


2
들어 uniform(0, 1)그 것이다 불가능 생산하는 1결과로. 그의 기능은 간단하게 정의되기 때문에 def uniform(a, b): return a + (b - a) * random()하고 random()생산할 수 없다 1.0.
Martijn Pieters

2
@MartijnPieters 나는 당신이 옳다고 생각하고 당신의 대답을 찬성했습니다. 나는 많이 의심했지만 확실하지 않았고, 그것은 내 대답의 주요 추력과는 거리가 있었으므로 나는 그렇게했다 :)
hobbs

1

정확한 0을 표시하기 위해 필요한 반복 횟수를 계산하는 루프를 시도하고 생성 할 수 있습니다.

또한 Hobbs가 언급했듯이 uniformly샘플링되는 값의 양은 9,007,199,254,740,992입니다. 이는 0을 볼 확률이 정확히 1 / 9,007,199,254,740,992임을 의미합니다. 일반적인 용어와 반올림 은 0을 찾기 위해 평균 10 조원 샘플 이 필요함을 의미 합니다. 물론 처음 10 번의 시도에서 찾거나 결코 찾지 못할 수 있습니다.

값에 정의 된 구간이 괄호로 닫히므로 1을 포함하지 않으므로 샘플링 1은 불가능합니다.


1

확실한. 당신은 uniform(0, 0.001)대신 에 시도와 함께 이미 올바른 길을 가고 있었습니다. 더 빨리 일어날 수 있도록 범위를 계속 제한하십시오.

>>> random.uniform(0., 5e-324)
5e-324
>>> random.uniform(0., 5e-324)
5e-324
>>> random.uniform(0., 5e-324)
0.0
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.