2011-12-20 8 views
2

시드 java.util.Randomlong을 제공하는 것과 관련하여, 개체를 한 번 인스턴스화하면 프로그램의 수명에 만족할 시드로 시간이 걸리는 것 같습니다. 목적은 nextDouble()에 대한 일련의 호출 결과가 임의로 보임을 의미합니다.최적의 Java 랜덤 시드

코드 단순화 이유로 인해 Random을 인스턴스화하고 여러 번 사용한 다음 다시 인스턴스를 생성하고 반복합니다. 종자가 유사하게 제공된다면 종자는 시간에 근거하기 때문에 비슷하고 증가 할 것입니다. 증가량은 1970 년 1 월 1 일 이후의 초 수 인 경우 값에 비해 작을 것입니다. (편집 :이 질문은 2011 년에 요청되었습니다.)

nextDouble()의 출력을 체인하면, Random의 인스턴스화가 아닌 임의의 시간 기반 시드를 사용하면 nextDouble()의 출력 체인에 미묘한 패턴이 표시됩니다. 이 질문을 표현하는 또 다른 방법은 다음과 같습니다. long 집합에서 균일하게 그려진 시드가 필요합니까?

답변

7

실제로 동일한 밀리 초 단위로 생성되는 경우 동일한 시드가 할당되는 상황이 발생할 가능성이 큽니다. 일부 시스템은 15 밀리 초 또는 그 이상의 낮은 해상도를 가지므로 더 큰 문제가됩니다.

이 문제를 해결하는 방법 중 하나는 Math.random()입니다. 처음 사용되었을 때만 인스턴스화되는 시스템 전체 무작위 인스턴스를 사용합니다. 기본 인스턴스에 액세스 할 수 있다고 생각하지 않으므로 nextInt()을 사용할 수는 없지만 복식에 Math.random()을 사용하거나 직접 임의의 객체를 원하면 doubleMath.random()에서 가져 와서 해당 비트를 변환하십시오. long에 입력하고 의 시드로 long을 사용하십시오.

무작위로 오라클 문서는 here입니다.

// create new random with seed from system random 
Random r = new Random(Double.doubleToLongBits(Math.random())); 
+1

와우, 고맙습니다. 나를 1.4.2 문서에 링크 시켰습니다. 분명히 Java 7이 출시되었다는 메모를 얻지 못했습니까? – corsiKa

+0

나는 모든 자바 검색 쿼리에 java6을 추가하는 습관을 가지고있다. :-) 어쨌든 java6 링크로 업데이트한다. – paxdiablo

+0

아마도 랜덤이 기본적으로하는 것보다 이것이 어떻게 더 좋은지 설명 할 수 있습니다. ;) (내 대답 참조) –

2

물론 제너레이터에 따라 다르지만 내 경험상 시드에 대한 작은 변화는 생성되는 값에 큰 영향을 미칩니다.

약간의 작업으로도 감지 할 수 있지만 고급 작업이나 암호화 작업을 수행하지 않는 한 약간의 차이는 없습니다. 당신 도메인의 유형에라면 어떤 경우

, 당신은 아마도

+2

또는 동굴에 앉아있는 '9, 9, 9, 9'라는 트롤은 무작위로 말썽을 일으킬 수 있습니다. – corsiKa

+1

시도해보십시오. 'randoms = new random (441287210); (int i = 0; i <10; i ++) 시스템 용 .out.print (random.nextInt (10) + ""); }'prints '1 1 1 1 1 1 1 1 1 1' –

+0

그리고 계속하면 다른 숫자를 갖기 시작할 것입니다. @Peter는 사용 된 표현의 흥미로운 속성을 설명하지 않는 한 당신의 요점을 완전히 확신하지 못합니다. Java PRNG는 '1 1 1 1 1 1 1 1 1 1 1'이 동일한 probab을 가지고 있기 때문에 '3 1 4 1 5 9 2 6 5 3' 또는'2 7 1 8 2 8 1 8 2 8'로 표시됩니다. – paxdiablo

4

:-) 소스의 3 켈빈 배경 방사선 같은 것을 사용하여, 하드웨어 기반 난수 생성을 할 것이다 자동으로 생성 된 무작위 종자는 System.nanoTime과 카운터를 사용하여 항상 다른 것을 보장합니다. IMHO, 임의성

public Random() { 
    this(seedUniquifier()^System.nanoTime()); 
} 

private static long seedUniquifier() { 
    // L'Ecuyer, "Tables of Linear Congruential Generators of 
    // Different Sizes and Good Lattice Structure", 1999 
    for (;;) { 
     long current = seedUniquifier.get(); 
     long next = current * 181783497276652981L; 
     if (seedUniquifier.compareAndSet(current, next)) 
      return next; 
    } 
} 

랜덤 48 비트 종자를 사용하고 가능한 모든 long 또는 double 값을 생성 할 수 없음을 의미 매 2^48 호출을 반복을 향상시키기 위해 씨앗을 연주 할 필요가 없습니다.

씨를 뿌리면 실제로 도움이되지 않는 3 중 랜덤 전략처럼 들립니다. http://thedailywtf.com/Articles/Random-Char-and-TriplyRandom-Double.aspx

임의성을 더 높이려면 매번 1의 시드를 제공하더라도 동일한 임의의 시퀀스를 제공하지 않는 SecureRandom을 사용하십시오.모든 가능한 longdouble 값을 생성 할 수 있습니다.