2009-06-30 3 views
3

Unrand 시스템에서 srandom() 및 random()을 사용하여 c에서 임의의 숫자를 생성하고 있습니다. 여러 개의 RNG를 갖고 싶습니다. 동일한 시드가 주어지면 각 시퀀스는 동일한 시퀀스를 출력해야합니다. 나는 또한 각각의 상태를 저장하고 복원하고 싶다. 다음은 의사 코드 예제입니다.c/Unix의 다중 난수 생성기 상태

R1 = new_rng(5); //5 is the seed 
R2 = new rng(5); //5 is the seed here, too. 
a = R1.random(); 
b = R1.random(); 
d = R2.random(); //a == d 
s1 = R2.get_state(); //save the state of R2 
e = R2.random(); //b == e 
R2.set_state(s1); //restore the state of R2 
f = R2.random(); //b == f 

어떻게하면됩니까? 때로는 RNG가 다른 스레드로 분기 할 것이므로 새로운 스레드를 생성 할 때 RNG의 상태를 복제해야합니다.

+0

음, "추한"솔루션은 시드를 저장하고 무작위로 여러 번 호출 한 클래스를 만들어서 상태를 복원하는 것입니다. 물론, 많은 숫자를 사용하면 속도가 느려질 것입니다. –

답변

6

erand48()/nrand48()/jrand48()을 사용하면 배정 밀도 부동 소수점, 음수가 아닌 긴 정수 또는 부호가있는 긴 정수 난수를 각각 생성 할 수 있습니다. 이러한 함수를 사용하면 원하는만큼 독립적 인 시퀀스를 가질 수 있습니다. 상태는 인수로 전달되며 쉽게 저장하고 복원 할 수 있습니다. 또한 시퀀스는 표준에 의해 정의되며 다른 플랫폼에서도 실행에 따라 달라지지 않습니다.

일부 다른 답변은 rand_r()을 제안합니다. 이 함수는 POSIX.1-2008에서 더 이상 쓸모없는 난수 생성기를 제공합니다 :

이 함수는 훨씬 더 정교한 난수 생성기를 제공합니다.

하나의 함수 호출과 다른 의미에서 전달 될 수있는 상태의 양에 대한 제한은 의사 난수 생성 프로그램의 모든 요구 사항을 만족하는 방식으로 구현 될 수 없습니다. 그러므로이 기능은 안전을 포함하여 사소한 요구 사항이 충족되어야 할 때마다 피해야합니다.

rand_r() 기능은 차후 버전에서 제거 될 수 있습니다.

+0

drand48를 다른 대답)를 참조하십시오 : 새로운 난수 = 된 난수 * A + C 정말 겁쟁이 보인다! 확실하게 random()이 그보다 더 강했다. – Eyal

+1

아니, 정말로. 많은 "랜덤"구현은 비슷한 곱셈이있는 생성기 또는 이와 유사한 간단한 LFSR입니다. – ephemient

+0

사실 그것은 new_state = old_state * a + c입니다. 상태 및 산술은 48 비트이며 결과는 상태의 상위 비트에서 가져옵니다. 힘을 원한다면 암호로 안전한 난수 생성기를 사용해야합니다. 일반적으로 저장 속도가 느려지고 저장/복원 속도가 더 빨라집니다. OP는 반복성 및 저장/복원 기능에 더 관심이있었습니다. – mark4o

0

PRNG를 사용하여 실제로 동일한 시드가 제공된 동일한 시퀀스를 생성 할 수 있는지 확신하지 못합니다. 나는 몇몇 방법이 그런 식으로 작동한다는 것을 알고 있지만, 더 좋은 것들 중에는 일정량의 비 결정론이 포함되어 있기 때문에 동일한 씨앗이 다른 순서로 이어질 수 있다고 생각합니다. 이음새가있는 빗으로 libc 문서를 살펴보고 이것이 어딘가에 언급되어 있는지 확인해야 할 것이다. 그렇지 않은 경우 코드를 확인하십시오 (코드에 액세스 할 수있는 운이 좋은 경우).

어쨌든이 방법은 응용 프로그램을 libc의 PRNG 구현과 매우 밀접하게 연결합니다. 당신은 확실히 당신이 개발하고있는 libc의 풍미와 아마도 libc 버전에 묶일 것입니다. 이 기능이 매우 중요하다면, 이식성과 재현성을 보장하기 위해 앱에서 난수 생성을 다시 구현해야 할 수도 있습니다.

+2

안돼. PNRG는 매번 동일한 순서를 재생해야합니다. 디버깅을 위해 테스트를 반복하지 않으면 어떻게 될까요? 파손되지 않은 PNRG. – Eyal

1

다양한 UNIX 맛에 약간의 C 라이브러리 확장이 있습니다 : 임의 같은

  • BSD는 initstate/setState를
  • _r 변종 (random_r, srandom_r 확인 initstate_r 등)
  • rand_r (stdlib.h) 대상 UNIX에 의해

맛을 지원?

1

srand()rand() 대신 rand_r(unsigned *seed)을 사용하십시오. 그렇게하면 여러 개의 무작위 종자를 유지할 수 있습니다.

+0

이는 rand_r()를 사용하지 않아야라고 (와 이유를 제공) ( – user9876