에 맞게 충분히 빨리 될 생각은 순열을 얻을 수 get_nth_permutation
를 사용할 필요합니다. 그냥 목록을 섞어 라!
>>> import random
>>> l = range(21)
>>> def random_permutations(l, n):
... while n:
... random.shuffle(l)
... yield list(l)
... n -= 1
...
>>> list(random_permutations(l, 5))
[[11, 19, 6, 10, 0, 3, 12, 7, 8, 16, 15, 5, 14, 9, 20, 2, 1, 13, 17, 18, 4],
[14, 8, 12, 3, 5, 20, 19, 13, 6, 18, 9, 16, 2, 10, 4, 1, 17, 15, 0, 7, 11],
[7, 20, 3, 8, 18, 17, 4, 11, 15, 6, 16, 1, 14, 0, 13, 5, 10, 9, 2, 19, 12],
[10, 14, 5, 17, 8, 15, 13, 0, 3, 16, 20, 18, 19, 11, 2, 9, 6, 12, 7, 4, 1],
[1, 13, 15, 18, 16, 6, 19, 8, 11, 12, 10, 20, 3, 4, 17, 0, 9, 5, 2, 7, 14]]
확률은 len(l)
> 15 n
< 100000이 목록에 나타나는 중복에 대해 압도적이지만, 당신이, 또는 len(l)
의 낮은 값에 대한 보증을 필요로하는 경우, 단지 인 경우에 중복을 기록하고 건너 뛸 set
를 사용 우려 (비록 당신이 당신의 의견에서 관찰했듯이, n
가 len(l)!
에 가까워지면, 이것은 멈출 것이다). 뭔가 같은 : len(l)
이 더 길고 더 길어지면
def random_permutations(l, n):
pset = set()
while len(pset) < n:
random.shuffle(l)
pset.add(tuple(l))
return pset
그러나, random.shuffle
이 덜 신뢰할되기 때문에 난수 발생기의 기간을 넘어 목록 증가의 가능한 순열의 수! 따라서 모든 순열이 l
으로 생성 될 수는 없습니다. 이 시점에서 get_nth_permutation
을 일련의 난수에 매핑해야 할뿐만 아니라 0
과 len(l)
사이의 모든 난수를 생성 할 수있는 난수 생성기가 필요합니다! 비교적 균일 한 분포를 갖는다. 따라서 더 강력한 임의성의 소스를 찾아야 할 수도 있습니다.
그러나 일단 그렇게하면 해결 방법은 Mark Ransom의 대답과 같이 간단합니다.
len(l)
의 경우 random.shuffle
이 신뢰할 수없는 이유를 이해하려면 다음을 고려하십시오. random.shuffle
은 0
과 len(l) - 1
사이의 임의의 숫자 만 선택하면됩니다. 그러나 내부 상태를 기반으로 숫자를 선택하며 한정된 (고정 된) 상태 수만 사용할 수 있습니다. 마찬가지로, 전달할 수있는 가능한 시드 값의 수는 유한합니다.이것은 생성 할 수있는 고유 한 일련의 수의 집합도 유한하다는 것을 의미합니다. 전화 번호는 s
입니다. len(l)! > len(s)
의 경우 해당 순열에 해당하는 시퀀스가 s
이 아니기 때문에 일부 순열을 생성 할 수 없습니다.
정확히 길이가 문제가되는 것은 무엇입니까? 나는 잘 모르겠다. 그러나 가치가있는 무엇을 위해, random
에 의해 실행되는 메르 센 트위스터의 기간은 2**19937-1입니다. shuffle docs은 일반적인 방식으로 내 요점을 반복합니다. 또한 위키 피 디아가이 문제에 관해 무엇을 말하고 있는지 확인하십시오. here.
범위 (len (population))에 random.shuffle을 호출하고 이전에 본 적이 있는지 확인할 수 없습니까? (가능한지 확인하기 위해 몇 가지 검사를 실시합니다. 즉, [0,1]에서 10 개의 고유 샘플을 요청하지 않는 것입니다. – DSM
흥미 롭습니다. python3에는이 제한이 없습니다. '>>> range (math.factorial (10000))'도 몇 초 내에 반환됩니다. 그러나,'>>> len (range (math.factorial (10000)))'yields :'OverflowError : 파이썬 int가 너무 커서 Csize_t' – ch3ka
@ ch3ka로 변환 할 수 없다. 파이썬 3에서는'range'가 생성자를 반환하기 때문이다. 그러나 생성자를 '범위'에서 목록으로 강제 변환하려고하면 (길이를 확인하기 위해) 'OverflowError'가 발생합니다. @Wilduck 물론. – Wilduck