입력 튜플에 대해 다음과 같은 결정 론적 (비교기없이) 알고리즘이 작동합니다. (a1,…,an):
- 할 일 피셔 - 예이츠 셔플 일부 정적 쌍으로 비교를 사용하여 (예를 들어a1<a2)를 코인 플립으로 사용합니다 (수락 거부 샘플링 수행). 비교기가 출력되는 경우1 처음에는 결정적 인 경우 무한 거부 루프를 피하기 위해 거꾸로 사용하십시오.
- (옵션 속도 향상 : 한 쌍을 시도하십시오 n 시간, 어디서 n길이 또는 입력입니다. 두 출력이 다르면 (1)에서 얻은 순열을 반환합니다.
- 병합 정렬을 사용하여 배열을 정렬하십시오.
비교 자로 결정 론적 순서 관계가 주어지면이 알고리즘은 배열을 시간순으로 정렬합니다. O(nlogn) Fisher-Yates 셔플이 실행되기 때문에 O(n) 최대를 사용하여 O(logn)각 단계 및 병합 정렬에서 비 랜덤 "랜덤 비트"(예 : 비교기 호출)는 동일한 점으로 복잡합니다. 이 경우 (1)의 결과는 전혀 쓸모가 없지만 실제 정렬이 이루어 지므로 아무런 해가 없습니다.
비교기 (1)가 각 순열에 대해 동일한 확률로 배열을 순열하고 실제 (3)을 생략 해야하는 경우 (2) 또는 (2) 임의성을 결정하지 못한 경우) 실제 동전 뒤집기를 고려할 때 이것은 아닙니다 결과 분포는 (1) 때문에 모든 순열에 균일하게 분포 된 입력 순서에만 의존하므로 전체 알고리즘의 결과도 균일하게 분포되기 때문에 해가 발생합니다. 각 합격-거부 샘플링을 반복해야하는 횟수는 기하 분포 (확률로 거부)<12) 따라서 예상 값이 있습니다 <2. 각 반복은 최대 사용logn런타임 분석은 결정 론적 경우와 거의 동일하지만, 그래서 비트, 우리는 단지 얻을 것으로 예상 런타임 의를O(nlogn)비 종료의 가능성으로 ( 거의 확실하게 종료합니다 ).
Joe가 지적한대로 : (1)의 첫 번째 비트에 대한 테스트가 마음에 들지 않으면 (3)을 수행 한 다음 (1)을 사용하십시오. an<a1 항상 0결정적인 경우에 배열이 이미 정렬되어 있기 때문입니다. 또한 난수의 상한이 동일한 순열을 생성하므로 루프 범위의 상한에서 난수를 빼야합니다. 그러나 몸값의 경우 항상 셔플을 수행해야하므로 (2)는 금지되어 있습니다.
(1)과 (3)에 대해 동일한 호출을 비교기에 사용할 수 있지만 결과가 균일하게 분포되어 있음을 증명하는 것이 가능하다면 적어도 훨씬 더 어려워집니다.
The following algorithm is has no distinct phases to shuffle and sort, but is asymptotically slower. It's essentially
insertion sort with
binary search. I will use
a=(a1,…,an) to denote the input and
bk=(bk,1,…,bk,k) to denote the result after the
k-th round:
- Set b1,1=a1
- If a2<a1 then b2=(a2,a1) and (c,d):=(2,1) else b2=(a1,a2) and (c,d):=(1,2). In either case ad<ac will always be 0 (i.e. false) for a nonrandom comparator.
- To obtain bk for k≥3 obtain bk−1 first.
- Let l=⌈log2k⌉ and k′=2l, i.e. k′ is the least power of 2 not smaller than k.
- Let i0=0. For every j∈{1,…,l} let
ij=⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪ij−1+2l−jij−1ij−1+2l−jij−1ij−1+2l−j>k−1∧ad<acij−1+2l−j>k−1∧¬(ad<ac)ij−1+2l−j≤k−1∧bk−1,ij−1+2l−j<akij−1+2l−j≤k−1∧¬(bk−1,ij−1+2l−j<ak)
- If il>k repeat (5.) else bk=(bk−1,1,…,bk−1,il−1,ak,bk−1,il,…,bk−1,k−1)
- Output bn
Random case: 5 + the if clause of 6 is essentially acceptance-rejection sampling. The rest of the algorithm is a naive shuffle: shuffle the first k−1 elements and add the k-th element to each position with equal probability. If we used the normal insertion sort, we would get a binomial distribution instead.
Note that this algorithm is inefficient in both modes compared to the Fisher-Yates shuffle and merge sort as inserting an element to an arbitrary position is expensive if using an array and binary search needs linear time if using a list. But perhaps a modification of heap sort or tree sort in a similar way could lead to a faster algorithm.