2013-07-12 6 views
3

Javacript에서 사용자 정의 선형 합동 생성기 (glibc에서 사용되는 것)를 작성하려고합니다.
그 성질은 on wikipedia입니다. m=2^31, a=1103515245, c=12345입니다. 발전기가 작동하는 것 같다 있지만 Javascript의 사용자 정의 선형 합동 생성기

는 지금은

x = (1103515245 * x + 12345) % 0x80000000 ; // (the same as &0x7fffffff) 

으로 다음 시드 값을 얻고 있지만 번호가 캔버스에 테스트 할 때 :

cx = (x & 0x3fffffff) % canvasWidth; // coordinate x (the same for cy) 

그들은 끔찍하게 바이어스 것 같다 : http://jsfiddle.net/7VmR9/3/show/

왜 이런 일이 발생했는지에 대한 아이디어가 있습니까? 다른 모듈을 선택하면 시각적 테스트의 결과가 훨씬 좋아집니다.

테스팅 jsfiddle은 여기에서 : http://jsfiddle.net/7VmR9/3/

업데이트 I이 화학식과 좌표 캔버스 변환 고정 마침내

:

var cx = ((x & 0x3fffffff)/0x3fffffff*canvasWidth)|0 

이제 픽셀 좌표 그렇게하지 모듈러스 연산을 사용할 때와 같이 많이 변형됩니다.
업데이트 바이올린 : 나는 당신이 내가이 너무로 바이올린을 업데이트 최적화하려고 실현

current = (multiplier * current * modul + addend) % modulus)/modulus 

: 공식은 발전기에 대한 http://jsfiddle.net/7VmR9/14/

+0

내게는 값이 1 빗나가는 것처럼 보였습니까? 아마도 2^31 +1일까요? 다른 값을 보여주기 위해 애니메이션을 만들었습니다. http://jsfiddle.net/cHbXk/ –

답변

2

는 (첫 번째 부분에있는 계수를 잊었) 당신은 최적화를위한 기초로 사용할 수 있습니다

http://jsfiddle.net/AbdiasSoftware/7VmR9/12/

+1

안녕하세요 Ken, 맞습니다. 두 캔버스 좌표를 잘못 생성했습니다. 마지막으로 나는이 변환을 사용했다.'var cx = ((x & 0x3fffffff)/0x3fffffff * canvasWidth) | 0;'http://jsfiddle.net/7VmR9/14/ 도움을 주셔서 감사합니다! 친애하는 – Stano

2

예, 보이는 당신이 그것을 해결처럼. 나는 똑같은 짓을 했어. 그것에서 실제 난수를받을 때

 
seed = (seed * factor + offset) % range; 

는하지만, 가장 중요한 것은, 다음 가 작동하지 않습니다 :

random = seed % random_maximum;

이를

선형 합동 생성기의 형식은 두 번째 모듈이 발전기의 영향을 막는 것처럼 보이기 때문에 작동하지 않습니다. 대신 사용할 필요가 :

 
random = floor (seed/range * random_maximum); 

(이 임의의 정수가 될 것이다 임의의 플로트를 얻기 위해 floor 호출을 제거합니다.)


마지막으로는, 내가 당신을 경고합니다 :에서 자바 스크립트, dword 한도를 초과하는 숫자로 작업 할 때 정밀도가 떨어집니다.따라서 LCG의 무작위 결과는 무작위 일 수 있지만 C++ 또는 dword 수학을 실제로 지원하는 다른 저수준 언어로 구현 된 동일한 LCG의 결과와 일치하지 않을 가능성이 높습니다.

부정확도 때문에 LCG의주기가 크게 줄어들 가능성이 높습니다. 예를 들어, 참조하는 glibc LCG의주기는 아마도 40 억입니다 (다시 시작하기 전에 40 억 개의 임의 숫자를 생성하고 정확한 숫자 세트를 다시 생성합니다). 이 js 구현은 인수를 곱하면 40 억을 초과하고 정밀도를 잃어 버리기 때문에 10 억 또는 그보다 훨씬 적을 수 있습니다.

관련 문제