Sortowanie patologiczne
Twój szef zażądał opracowania algorytmu sortowania w celu poprawy wydajności aplikacji twojej firmy. Jednak po napisaniu aplikacji wiesz, że prawdopodobnie nie będziesz w stanie znacznie przyspieszyć jej działania. Nie chcąc zawieść swojego szefa, postanowiłeś opracować nowy algorytm, który działa nawet lepiej niż * sortowanie na niektórych zestawach danych. Oczywiście, nie możesz dać do zrozumienia, że algorytm działa tylko w niektórych przypadkach, więc chcesz, aby był jak najbardziej niejasny.
Celem tego konkursu jest napisanie procedury sortowania w wybranym języku, który będzie działał lepiej na określonych zestawach danych niż inne, z powtarzalnymi wynikami. Im bardziej szczegółowa klasyfikacja określa prędkość, tym lepiej. Algorytm musi dokonywać pewnego rodzaju sortowania, więc algorytm, który zależy od danych, które są już całkowicie posortowane (jak w algorytmie, który nic nie robi), lub algorytm, który zależy od danych, które są całkowicie posortowane w odwrotnej kolejności, są nieprawidłowe. Algorytm sortowania musi poprawnie sortować dowolny zestaw danych.
Po przedstawieniu procedury prosimy o wyjaśnienie, dlaczego działa ona tylko na niektórych zestawach danych, oraz na włączenie testów na co najmniej jednym zestawie dobrych (szybkich) danych i jednym zestawie złych (wolnych) danych. Chodzi o to, aby móc udowodnić swojemu szefowi, że natknąłeś się na lepszy sposób sortowania, więc więcej danych testowych jest lepszych. Oczywiście pokażesz swojemu szefowi tylko wyniki testu z dobrych danych, więc wada wymaganych danych testowych nie może być zbyt oczywista. Jeśli dotyczy twojego języka, pokaż, że Twój algorytm jest szybszy niż wbudowany algorytm sortowania w Twoim języku.
Na przykład, można przesłać algorytm sortowania wstawiania, przy czym dobre dane to dane, które są już prawie posortowane, a złe dane to dane całkowicie losowe, ponieważ sortowanie wstawiania zbliża się do O (n) na prawie posortowanych danych. Nie jest to jednak zbyt dobre, ponieważ mój szef prawdopodobnie zauważyłby, że wszystkie dane testowe są już prawie posortowane.
To konkurs popularności , więc wygrywa odpowiedź z największą liczbą głosów po 7 dniach (21 maja).
Jeśli nikt mnie nie pobije, chciałbym przesłać odpowiedź wiki społeczności, która korzysta z równomiernie rozmieszczonych zestawów danych.
źródło
Odpowiedzi:
Minęło sporo czasu, ale pamiętam, że w Algorytmach 101 nauczono nas algorytmu sortowania wykorzystującego losowość. Nie byłem zbyt dobrym uczniem, więc tak naprawdę nie pamiętam, jak poszło i dlaczego zadziałało to średnio.
Mimo to zdecydowałem, że ten problem wymaga rozwiązania wykorzystującego randomizację, które, mam nadzieję, zadziała średnio na moją korzyść.
Ponieważ prawdziwa randomizacja jest ważna, zapewniam RNG odpowiedź na Życie, Wszechświat i Wszystko. Po kilku testach okazuje się, że był to sprytny ruch! Sprawdź, jak szybko posortowane są te 2 całkowicie dowolne listy:
Oba są sortowane tylko w 1 iteracji - nie można chyba poprosić o szybszą funkcję!
Trzeba przyznać, że niektóre inne listy przynoszą nieco gorsze wyniki ...
Są one sortowane odpowiednio w 4176 i 94 523 iteracjach, co w rzeczywistości zajmuje więcej niż sekundę ... ale zatrzymajmy ten fakt dla siebie, aby nikogo nie odwracać uwagi od tego, jak niesamowity jest ten algorytm!
Edytować:
Poproszono mnie o udowodnienie skuteczności mojego algorytmu na liście 100 pozycji, więc proszę:
Nawet ta długa i całkowicie dowolna lista jest natychmiast sortowana! Naprawdę musiałem natknąć się na najlepszy algorytm sortowania na świecie!
źródło
Jeśli możesz tworzyć własne dane, jest to dość proste - uzyskaj dane, które wyglądają losowo, ale zawierają klucz do szybszego sortowania. Wszystkie inne dane używają oryginalnej metody sortowania, więc średni czas jest lepszy.
Jednym prostym sposobem jest upewnienie się, że każdy element danych ma unikalny klucz, a następnie po prostu skróty kluczy. Weźmy na przykład listę z liczbami od 1 do 10 000, wszystkie pomnożone przez 16 i dodaną do niej losową liczbę od 0-15 (patrz fillArray () poniżej). Będą wyglądać losowo, ale każdy z nich ma unikalny klucz sekwencyjny. Aby posortować, podziel przez 16 (w C >> 4 jest bardzo szybki), a następnie po prostu umieść liczbę w tablicy, używając uzyskanego klucza jako indeksu. Jedno przejście i gotowe. Podczas testów odkryłem, że Quicksort był 30 razy wolniejszy przy dziesięciu milionach liczb.
Wszystko, co ma unikalny klucz, można posortować w ten sposób - oczywiście jeśli masz pamięć do przechowywania. Na przykład wiele baz danych używa unikalnego numerycznego identyfikatora klienta - jeśli lista jest wystarczająco mała / sekwencyjna, może być przechowywana w pamięci. Lub inny sposób na przetłumaczenie rekordu na unikalny numer. Aby uzyskać więcej informacji, sprawdź Hash Sorts, ponieważ to właśnie to ...
źródło