[0,1] 실수 랜덤값 발생시키는 함수로 [0,n) 정수 랜덤값 발생시키는 함수 만들기???
글쓴이: ckebabo / 작성시간: 화, 2009/03/10 - 3:17오후
randf()함수가 [0,1]범위의 실수를 균등분포로 발생시킨다고 할때, 이를 이용해서 [0,n)범위의 정수값을 발생시키는 함수를 만들어야 합니다.
간단하게는 아래과 같이 할 수 있습니다.
int rand_int(int n) { double r; /* 1. 나오는 경우 배제 */ while((r=randf()) >= 1.); return (int)(r*n); }
그런데 제가 의문시 되는 부분은 위와 같이 강제로 1이 발생되는 것을 무시하게되면 값이야 [0,n)으로 나오겠지만, 이것이 얼마나 큰 영향을 미치는 것인지 하는 것입니다. 물론 1. 이 발생할 확률은 엄청나게 작지만 이것이 과연 무시할만한 것인지 아닌것인지는 쉽게 판단이 서질 않네요.
Forums:
randf()를 어떻게
randf()를 어떻게 구현했는지에 따라 달라지겠지요.
보통은 0-RAND_MAX 까지의 random interger를 발생시키는 함수로부터
님께서 말씀하시는 randf 같은 함수를 구현합니다.
그렇다면 1/RAND_MAX의 확률로 1인값이 나오겠지요.
보통은 반대로 하지 않나요?
물리적인 아날로그 회로로부터 어떤 식으로 신호를 받아서 실수 난수를 발생시키는 게 아닌 다음에야
보통은 컴퓨터에서는 정수 난수발생기로 실수 난수를 만들텐데요. 컴퓨터는 정수 연산이 기본이니까요.
왜 반대로 하시려는지 그 이유가 궁금하네요.
임예진 팬클럽 ♡예진아씨♡ http://cafe.daum.net/imyejin
[예진아씨 피카사 웹앨범] 임예진 팬클럽 ♡예진아씨♡ http://cafe.daum.net/imyejin
그렇죠
정수를 실수로 만들어서 다시 정수로 만드는 길이죠. :-)
그냥 정수 발생기를 modulo n 으로 나눠서 쓰면 되고, 단 RAND_MAX 와 가장 가까운 n의 배수와 RAND_MAX 사이의 값은 버려야겠죠.
randf()가 rand()같은
randf()가 rand()같은 정수 난수를 실수로 변환시키는게 아니라, 특별한 알고리즘을 이용한다면 randf를 이용하는게 좋겠지만, 그렇지 않다면 imyejin님 말씀처럼 정수난수를 이용해서 (double(rand() - 1)/RAND_MAX)*n 와 같이 하는게 낫지 않나 싶습니다.
뭐 이경우는 1/RAND_MAX보다 작은 간격으로는 난수가 발생이 불가능합니다만...
1을 제외하는 것 자체는 관련이 없습니다.
0 과 1 사이의 균등분포 실수를 0,...,n-1 의 균등 분포 정수로 선형 변환하려면 [0,1) -> {0,...,n-1} 이 되어야 합니다. [0,1] 에서는 ax+b 꼴의 선형 변환으로는 균등분포를 만들 수가 없죠. 즉 1을 빼는 것 자체는, (잘못이 있는데 영향이 작아서 무시하는 게 아니라) 정확하게 하고 있는 겁니다.
단 전제는 randf() 에서 1을 제외한 나머지가 "진짜" 균등분포에 가깝게 숫자를 뱉어내느냐가 문제이죠. randf() 가 숫자 1을 50% 의 확률로 발생시키더라도 상관없습니다 (대신 시간이 오래 걸리겠죠). 중요한 것은 1을 제외한 나머지를 얼마나 균일하게 발생시키냐입니다. 즉 만약 0에서 9 사이의 10개 숫자를 만들고 싶다면, 이를테면 [0,0.1) 안의 실수가 발생할 확률이 [0,0.8) 안의 실수가 발생할 확률과 같은지가 중요하죠.
댓글 달기