Ty szukasz derangement swoich wpisów.
Po pierwsze, twój algorytm działa w tym sensie, że wysyła losowe zakłócenie, tj. Permutację bez stałego punktu. Jednak ma on ogromną wadę (której możesz nie mieć nic przeciwko, ale warto o tym pamiętać): niektórych zakłóceń nie można uzyskać za pomocą algorytmu. Innymi słowy, daje prawdopodobieństwo zerowe niektórym możliwym zakłóceniom, więc wynikowy rozkład nie jest zdecydowanie losowy.
Jednym z możliwych rozwiązań, jak zasugerowano w komentarzach, byłoby użycie algorytmu odrzucenia:
- wybrać permutacji równomiernie losowo
- jeśli hax ma stałych punktów, zwrócić go
- inaczej Ponów próbę:
Asymptotycznie prawdopodobieństwo uzyskania zmiany jest bliskie 1/e
= 0,3767 (zgodnie z artykułem wikipedii). Co oznacza, że aby uzyskać zmianę, trzeba wygenerować średnią permutacji e
= 2,718, co jest dość kosztowne.
Lepszym sposobem na to byłoby odrzucenie na każdym etapie algorytmu. W Pseudokod, coś jak to (zakładając, że tablica oryginalna zawiera i
w pozycji i
, tj a[i]==i
):
for (i = 1 to n-1) {
do {
j = rand(i, n) // random integer from i to n inclusive
} while a[j] != i // rejection part
swap a[i] a[j]
}
Główną różnicą od algorytmu jest to, że pozwalają j
być równa i
, ale tylko wtedy, gdy to robi nie wytwarzają stałego punktu. Jest nieco dłuższy do wykonania (ze względu na odrzucenie) i wymaga, abyś mógł sprawdzić, czy wpis jest na swoim oryginalnym miejscu, czy nie, ale ma tę zaletę, że może wytworzyć każde możliwe zakłócenie (jednolicie, dla tego materia).
Zgaduję, że algorytmy odrzucania nie powinny istnieć, ale uważam, że są mniej proste.
Edit:
Mój algorytm jest rzeczywiście zły: wciąż masz szansę kończąc na ostatnim punkcie unshuffled i dystrybucja nie jest przypadkowa w ogóle, zobacz marginalne rozkładów symulacji:
Algorytm generujący równomiernie rozłożone zakłócenia można znaleźć pod here, z pewnym kontekstem problemu, dokładnymi objaśnieniami i analizami.
Druga Edycja:
Właściwie Twój algorytm jest znany jako Sattolo's algorithm, i wiadomo, że produkują wszystkie cykle z jednakowym prawdopodobieństwem. Tak więc żadne zakłócenie, które nie jest cyklem, lecz produktem kilku rozłącznych cykli, nie może być uzyskane za pomocą algorytmu. Na przykład, w przypadku czterech elementów, permutacja, która wymienia 1 i 2 oraz 3 i 4, jest zaburzeniem, ale nie cyklem.
Jeśli nie masz nic przeciwko uzyskiwaniu tylko cykli, to algorytm Sattolo jest do zrobienia, w rzeczywistości jest znacznie szybszy niż jakikolwiek jednolity algorytm zakłóceń, ponieważ nie jest konieczne odrzucanie.
Położyć każdą pozycję w innej pozycji losowo. Jest mała szansa, że nie możesz znaleźć pozycji na ostatnią, ale zacznij od nowa. – adrianm
https://en.wikipedia.org/wiki/Sattolo's_algorithm – Bergi
Skończona powtarzalność udowodniłaby matematycznie, że działa twój algorytm: na końcu iteracji i, element na pozycji i nie jest już oryginalnym elementem. Przy iteracji n-2 dane [n-2] są automatycznie tasowane danymi [n-1]. Tak więc, jeśli dane [n-1] nadal zachowują swoją pierwotną wartość, zostaną one zamienione w ostatniej iteracji. To samo dotyczy danych [n-1]. – Rerito