Czy można zastosować algorytm sortowania z nieprzechodnim porównaniem, a jeśli tak, dlaczego wymienność przechodni jest wymieniona jako wymóg dla sortujących komparatorów?
Tło:
Algorytm sortowania ogólnie sortuje elementy listy według funkcji komparatora C (x, y), przy pomocy
Wymagania dla tego komparatora są, o ile je rozumiem:
- zwrotny:
- antysymetryczny:
- przechodnie:
- C (x, y) jest zdefiniowane dla wszystkich x i y, a wyniki zależą tylko od x i y
(Te wymagania są zawsze wymienione inaczej w różnych implementacjach, więc nie jestem pewien, czy dobrze je zrozumiałem)
Teraz zastanawiam się nad „tolerancyjną” funkcją komparatora, która przyjmuje liczby x, y jako podobne, jeśli : C ( x , y ) = { - 1, jeśli x < y - 1 0, jeśli | x - y | ≤ 1 + 1, jeżeli x > y + 1
Przykłady: obydwa [ 1, 2, 3, 4, 5]
i [1, 4, 3, 2, 5]
prawidłowo sortowane w kolejności rosnącej zgodnie z porównawczy tolerancyjnej ( gdy X jest przed Y na liście)
, ale nie jest, ponieważ C (4,2) = 1[1, 4, 2, 3, 5]
Ten tolerancyjny komparator jest refleksyjny i antysymetryczny, ale nie przechodni.
tj. C (1,2) = 0, c (2,3) = 0, ale C (1,3) = -1, naruszając przechodniość
Jednak nie mogę wymyślić żadnego algorytmu sortowania, który nie dałby „poprawnie posortowanego” wyjścia, gdy otrzyma ten komparator i losową listę.
Czy zatem w tym przypadku przechodnie nie jest wymagane? Czy istnieje mniej ścisła wersja przechodniości, która jest wymagana, aby sortowanie działało?
Powiązane pytania:
- Dlaczego do sortowania porównawczego potrzebna jest antysymetria? (o antysymetrii)
- Algorytmy sortowania, które akceptują losowy komparator (około losowego C (x, y))
- OrderBy z nieprzechodnym IComparer (o moim algorytmie sortowania c #)
źródło
Odpowiedzi:
Zapytałeś: Czy możemy uruchomić algorytm sortowania, który zapewni mu nieprzechodni komparator?
Odpowiedź: oczywiście. Możesz uruchomić dowolny algorytm z dowolnym wejściem.
Znasz jednak zasadę: Garbage In, Garbage Out. Jeśli uruchomisz algorytm sortowania z nieprzechodowym komparatorem, możesz otrzymać nonsensowne dane wyjściowe. W szczególności nie ma gwarancji, że dane wyjściowe zostaną „posortowane” według komparatora. Tak więc uruchomienie algorytmu sortowania z nieprzechodnim komparatorem prawdopodobnie nie będzie przydatne w sposób, w jaki prawdopodobnie oczekiwałeś.
źródło
Biorąc pod uwagę zestaw elementów i binarną relację porządkującą, przechodnie jest wymagane do całkowitego uporządkowania elementów. W rzeczywistości przejściowość jest nawet wymagana do zdefiniowania częściowego porządku na elementach. http://en.m.wikipedia.org/wiki/Total_order
Potrzebowałbyś znacznie szerszej definicji tego, co oznacza „posortowane”, aby posortować elementy bez przechodniości. Trudno być samowystarczalnym. Inna odpowiedź brzmi: „W szczególności nie ma gwarancji, że dane wyjściowe zostaną„ posortowane ”według komparatora.” Ale możemy powiedzieć coś znacznie silniejszego. Masz gwarancję, że dane wyjściowe nie zostaną posortowane według twojego komparatora.
źródło
Brzmi tak, jakbyś chciał ułożyć przedmioty w taki sposób, aby wszystkie dostrzegalne pozycje w rankingu były poprawne, ale przedmioty, które są blisko, można uznać za „nierozróżnialne”. Możliwe jest zaprojektowanie algorytmów sortowania, które będą działać z takimi porównaniami, ale jeśli nie ma ograniczeń co do liczby porównań, które mogą wskazywać, że rzeczy są nierozróżnialne, nie ma sposobu, aby uniknąć konieczności ich porównywania N (N-1) / 2. Aby zrozumieć dlaczego, wybierz pewną liczbę N i dowolny algorytm sortujący, który wykonuje mniej niż N (N-1) / 2 porównań. Następnie wypełnij listę L [0..N-1], ustawiając każdy element L [I] na I / N i „sortuj” go za pomocą komparatora (minimalna wartość to 0, a maksymalna (N-1) / N , więc różnica będzie wynosić (N-1) / N, czyli mniej niż 1).
Ponieważ istnieje N (N-1) / 2 pary elementów, które można porównać, a sortowanie nie wykonało tak wielu porównań, musi istnieć pewna para elementów, które nie zostały bezpośrednio porównane ze sobą. Zastąp, którykolwiek z nich zostanie posortowany najpierw przez 1, a drugi przez -1 / N, przywróć wszystkie pozycje do ich początkowej pozycji i powtórz operację sortowania. Każda pojedyncza operacja porównania da zero, tak samo jak za pierwszym razem, więc zostaną wykonane te same porównania, a elementy skończą w tej samej kolejności. Aby lista była poprawnie posortowana, „1” musiałoby sortować po „-1 / N” (ponieważ różnią się o więcej niż jeden), ale ponieważ algorytm sortowania nigdy nie porównałby tych dwóch elementów bezpośrednio względem siebie, to nie byłby w stanie tego wiedzieć.
źródło
Wypełnij tablicę n elementów wartościami n, n-1, n-2, ..., 2, 1. Następnie spróbuj posortować przy użyciu algorytmu „prostego wstawiania”. Przekonasz się, że każdy element jest uważany za równy pierwiastkowi tuż przed nim i dlatego nie jest przenoszony. Wynikiem „sortowania” jest ta sama tablica.
źródło