2010-12-04 1 views
0

난수 C#을 1 개 순서, LINQ 이상 :더 난 숫자의 임의의 순서로 생성이 코드를 사용했다

var sequence = Enumerable.Range(0, 9).OrderBy(n => n * n * (new Random()).Next()); 

모든 것이 내가이 코드에 내가 전화, 하나 개 이상의 순서를 필요까지 확인되었다 루틴 10 회, 그리고 결과는 내 문제, 모든 시퀀스가 ​​동일합니다.

 int i = 0; 
     while (i<10) 
     { 
      Console.Write("{0}:",i); 
      var sequence = Enumerable.Range(0, 9).OrderBy(n => n * n * (new Random()).Next()); 
      sequence.ToList().ForEach(x=> Console.Write(x)); 
      i++; 
      Console.WriteLine(); 
     } 

누군가 다른 순서를 생성하는 방법에 대한 힌트를 줄 수 있습니까? LINQ를 사용하여 잘만하면

+1

그리고 'OrderBy'가 키 선택기를 두 번 이상 호출하는 경우 (나는 문서에서 보장 여부를 찾지 못했습니다. 한 번만 부름) 비교 자 계약이 위반 되었기 때문에 코드가 잘못되었습니다. – CodesInChaos

답변

5

각 반복마다 Random의 새 인스턴스를 만드는 것이 문제입니다. 각 인스턴스는 현재 시간에서 초기 시드를 가져 오며, 이는 대리인이 실행되는 빈도와 비교할 때 상대적으로 드물게 변경됩니다. 인스턴스를 Random으로 반복하여 만들고 사용할 수 있습니다. 자세한 내용은 내 article on randomness을 참조하십시오.

그러나 나는 또한 (예 : this one 같은 스택 오버플로에 대한 예제가 많이있다) 당신이 값을 셔플하기 위해 Fisher-Yates shuffle 대신 OrderBy 사용하는 것이 좋습니다 것입니다 ... 당신이하려는 것처럼 보이지만 임의성을 어느 정도 편향 시키십시오. 에 대한 자세한 내용을 알려 주시면 수행하고자하는 작업이 정확히 개가 될 수 있습니다.

+0

안녕하세요, 유전자 알고리즘을위한 개인을 만드는 중입니다. 나는 결과 생성 점을 그리는이 시퀀스 생성기의 goodnes를 테스트한다 (한 점을 사용하고 다음에 사각형에 좌표 x, y가있다). 결과는 좋았고, 나는 어떤 그림도 보지 못했다. 씨앗 값에 대해 읽었습니다. 코드에서 "i"를 시드로 추가하면 모든 시퀀스가 ​​다르고 괜찮습니까? 시드에 추가 속성이 있어야합니까? – mjsr

+0

@voodoomsr : 예상 할 수 있는지 여부에 달려 있습니다. 예측할 수없는 상황이 필요한 경우 예측할 수없는 시드가 필요합니다. 매번 동일한 시드를 통과하면 매번 같은 결과가 나옵니다. –

+0

음 내가 실제로 다른 임의의 숫자 인 씨앗을 만들면 다른 결과가 나올 수 있습니다. 예측할 수 없다고 생각합니다. 나는 Fisher-Yates 알고리즘을 더 자세히 살펴볼 것입니다. 첫눈에 구현하기가 어렵지 않습니다. – mjsr

2

무작위의 인스턴스 10 개를 연속적으로 만들고 각각에서 첫 번째 의사 난수를 가져옵니다. 나는 그들이 모두 같다고 놀랍지 않습니다. 내가 몇 년 전에 쓴이 정적 메소드를 사용하여 내 코드에서

Random r = new Random(); 
var sequence = Enumerable.Range(0, 9).OrderBy(n => n * n * r.Next()); 
0

, 그리고 여전히 좋은 무작위 보여줍니다 :

이 시도

using System.Security.Cryptography; 
... 

public static int GenerateRandomInt(int from, int to) 
{ 
    byte[] salt = new byte[4]; 
    RandomNumberGenerator rng = RandomNumberGenerator.Create(); 
    rng.GetBytes(salt); 
    int num = 0; 
    for (int i = 0; i < 4; i++) 
    { 
    num += salt[i]; 
    } 
    return num % (to + 1 - from) + from; 
} 

자세하게 예를 설명 할 수 없음을 , 기억을 되 찾을 시간이 필요합니다.)

+0

1024보다 큰 숫자를 원한다면별로 쓸모가 없을 것입니다. 그렇습니까? 그리고 1-700을 물어 보면 좋은 분배를하지 못한다는 것을 알게 될 것입니다. 또한 매번 새로운 난수 생성기를 만드는 것은 좋은 생각이 아닙니다. 암호로 안전한 난수가 필요한 경우 RandomNumberGenerator의 인스턴스에 위임 한 Random의 하위 클래스를 갖는 것이 좋습니다. 그렇지 않으면 무작위를 사용하십시오. –

+0

-1에 투표 한 사람에게 :이 코드를 사용해 보셨습니까? 별도의 농담 스타일의 대답과 질문을 잘못 이해한다 – Genius

+0

@ Jon Skeet, 1) 코드를 약간 수정하여 좋은 배포를 수행합니다 (답변은 지침이 아닌 아이디어로 참조하십시오). 2) 왜 random number를 만드는 것이 좋은 생각이 아닌가? 공연? 누가이 질문에 신경 쓰나요? 3) RandomNumberGenerator from Cryptographic 및 Random from System 매우 다른 구현을 가진 다른 클래스입니다. – Genius