Чи потрібна транзитивність для алгоритму сортування


14

Чи можливо використовувати алгоритм сортування з неперехідним порівнянням, і якщо так, то чому транзитивність перерахована як вимога до сортування компараторів?

Фон:

  • Алгоритм сортування, як правило, сортує елементи списку відповідно до функції порівняння C (x, y), з

    C(x,y)={1if xy0if xy+1if xy

    Наскільки я розумію їх вимоги до цього компаратора:

    • рефлексивні: x:C(x,x)=0
    • антисиметричний: x,y:C(x,y)=C(y,x)
    • x,y,z,a:C(x,y)=aC(y,z)=aC(x,z)=a
    • C (x, y) визначається для всіх x і y, а результати залежать лише від x і y

    (Ці вимоги завжди перераховані по-різному в різних реалізаціях, тому я не впевнений, що я їх все добре)

|xy|1

C(x,y)={1if x<y10if |xy|1+1if x>y+1

[ 1, 2, 3, 4, 5][1, 4, 3, 2, 5]C(x,y)0 якщо x надходить до y у списку),
але [1, 4, 2, 3, 5]це не так, оскільки C (4,2) = 1

Цей толерантний компаратор є рефлексивним та антисиметричним, але не перехідним.

тобто C (1,2) = 0, c (2,3) = 0, але C (1,3) = -1, що порушує транзитивність

Але я не можу придумати жодного алгоритму сортування, який би не зміг створити "правильно відсортований" вихід, якщо дано цей компаратор та випадковий список.

Тому транзитивність в цьому випадку не потрібна? І чи є менш сувора версія транзитивності, яка є потрібно для сортування на роботу?

Пов’язані запитання:


Думаю, що не вдасться використати цей компаратор на [3, 2, 1] за допомогою «порівняння завжди вибирати середину» для стрижня.
Г. Бах

2
Я підозрюю, що якийсь неперехідний компаратор, який використовується в алгоритмі сортування, може викликати нескінченний цикл.
Karolis Juodelė

1
aiai+1aiajij
Yuval Filmus

@ G.Bach Я думаю, що quicksort насправді повністю вийде з ладу, якщо ваш масив має n разів 3, один раз 2, n рази 1, а середина 2 використовується як перший шарнір, незалежно від того, що буде після цього.
gnasher729

Відповіді:


12

Ви запитували: чи можемо ми запустити алгоритм сортування, подаючи його неперехідний компаратор?

Відповідь: Звичайно. Ви можете запустити будь-який алгоритм з будь-якого вводу.

Однак ви знаєте правило: сміття в, ​​сміття поза. Якщо ви запускаєте алгоритм сортування з неперехідним компаратором, ви можете отримати нісенітницю. Зокрема, немає гарантії, що вихід буде "відсортований" відповідно до вашого компаратора. Отже, запуск алгоритму сортування з неперехідним компаратором, ймовірно, не буде корисним так, як ви, напевно, сподівалися.

[3,2,1] використовуючи ваш компаратор, залишив би список не зміненим - все ж отриманий список вихідних даних не знаходиться в упорядкованому порядку (відповідно до вашого компаратора).


1
моя перша думка полягала в тому, що список [3,2,1] є в упорядкованому порядку за моїм порівняльником, тому, звичайно, сорт повинен залишити його незмінним; але я, можливо, використовував неправильне визначення відсортованого. Я просто порівнюю кожен елемент із його прямими сусідами, але це може бути занадто слабким обмеженням для розгляду списку, відсортованого
HugoRune

4
@HugoRune Ну, це цікавий момент. Що ви маєте на увазі під сортуванням ? Якщо ви зможете показати алгоритм сортування, він припиняється, якщо не перехідний порівняльник, і щоразу, коли алгоритм припиняється, деяка умова є істинною, і ця умова полягає в тому, що ви приймаєте сортування ... тоді, звичайно, цей алгоритм буде сортувати ваш список щоразу для цього визначення сортованості . Якщо порівняльник не є транзитивним, можливо, не має сенсу приймати визначення відсортованого, яке вимагає попарного порівняння всіх елементів у відсортованому списку.
Patrick87

3
@HugoRune, "зіставляються лише сусіди" вам, мабуть, потрібен спеціальний сорт. Стандартні алгоритми передбачають транзитивність, щоб уникнути зайвих порівнянь. Або ви можете вбудувати своє неперехідне замовлення в перехідне. Чи, можливо, ви шукаєте щось у напрямку топологічного сортування ?
vonbrand

Я наткнувся на це деякий час назад і виявив, що сортування бульбашок насправді працює чудово, оскільки воно лише коли-небудь порівнює сусідні елементи.
Mooing Duck

4

Враховуючи набір елементів і бінарне відношення впорядкування, необхідна транзитивність для повного впорядкування елементів. Насправді транзитивність навіть необхідна для визначення часткового порядку на елементах. http://en.m.wikipedia.org/wiki/Total_order

Вам потрібно набагато ширше визначення того, що означає "сортування", щоб сортувати елементи без перехідності. Важко бути самопослідовним. Інша відповідь говорить: "Зокрема, немає гарантії, що вихід буде" відсортований "відповідно до вашого компаратора." Але ми можемо сказати щось набагато сильніше. Ви гарантуєте, що вихід не буде відсортований відповідно до вашого компаратора.

a<bb<cc<a


1
Я інтерпретував це запитання як сортування за допомогою часткових упорядкувань (таким чином, що порівняння, які говорять про те, що речі є нерівними, є транзитивними, але ті, що стосуються предметів, не відрізняються). Сортування на основі часткового впорядкування іноді корисне, але в гіршому випадку потребує порівняння N (N-1) / 2. Будь-який алгоритм сортування, який у гіршому випадку складає менше N (N-1) / 2 порівнянь, не зможе правильно класифікувати частково упорядковані елементи з причин, описаних у моїй відповіді.
суперкарт

2

Здається, що ви хочете, щоб розташувати предмети таким чином, щоб усі чіткі рейтинги були правильними, але близькі пункти можна вважати "нерозрізненими". Можна розробити алгоритми сортування, які працюватимуть з такими порівняннями, але, якщо немає обмежень, скільки порівнянь можуть повідомити про те, що речі не відрізняються, немає ніякого способу уникнути того, щоб вони вимагали порівняння N (N-1) / 2. Щоб зрозуміти, чому, виберіть деяке число N та будь-який алгоритм сортування, що робить менше порівняння N (N-1) / 2. Потім заповніть список L [0..N-1], встановивши кожен елемент L [I] на I / N і "сортуйте" його за допомогою свого компаратора (мінімальне значення буде 0, а максимальне (N-1) / N , тому різниця буде (N-1) / N, що менше 1).

Оскільки є N (N-1) / 2 пари предметів, які можна порівняти, а сортування не зробило таких порівнянь, має бути пара елементів, які безпосередньо не порівнювались один з одним. Замініть те, що в одному з них було відсортовано спочатку 1, а інше -1 / N, поверніть усі елементи до початкового положення та повторіть операцію сортування. Кожна операція порівняння дасть нуль, як і вперше, так що будуть проведені ті ж порівняння, а елементи будуть в тій же послідовності. Щоб правильно сортувати список, "1" повинен був би сортувати після "-1 / N" (оскільки вони відрізняються більш ніж на один), але оскільки алгоритм сортування ніколи не порівнюватиме ці два елементи безпосередньо один проти одного, він не знав би цього.


0

Заповніть масив з n елементів значеннями n, n-1, n-2, ..., 2, 1. Потім спробуйте сортувати за допомогою алгоритму "прямої вставки". Ви побачите, що кожен елемент вважається рівним елементу безпосередньо перед ним, тому не переміщується. Результатом "сортування" є той самий масив.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.