Мы знаем, что теоретически информация о количестве сравнений для алгоритма сортировки на основе сравнения равна ceil (lg (n!)), Где lg обозначает логарифм с основанием 2.
Мы можем построить противника, где мы выберемупорядочение путем подсчета количества линейных расширений для частичного порядка в обоих случаях, если меньше или больше.Какой бы путь не имел более высоких линейных расширений, выберите этот путь.(Это автоматически устраняет несоответствия, потому что если ответ с одной стороны непоследователен, он будет равен нулю, а другой будет таким же, как предыдущий)
Однако такой злоумышленник неэффективен, так как подсчет числа линейныйрасширение до частичного заказа составляет # P-complete .
Другой вариант - использовать более простого противника за полиномиальное время, которое делает:
- a> b, если a никогда не проигрывал, а b проигрывал хотя бы один раз.
- a> b, если как непобедимый, так и a имеет больше побед, чем b.
- a> b, если частичный порядок заставляет a> b
- a выберите любой другой вариант.
Этот злоумышленник взят из книги «Искусство компьютерного программирования», том 3, второе издание, стр. 209. Он хорошо работает для таких задач, как поиск второго по величине элемента, поскольку он вызывает n + ceil (lg (n)) - 2 сравнения.К сожалению, это не навязывает теоретическую информацию для сортировки.Это остается верным, даже если я добавлю больше эвристик, таких как доминирующий счетчик (количество значений, которое оно больше, чем), для сравнения вместо случайного выбора порядка.
Я знаю, что это не принудительно, поскольку Collections.sort () вJava 8 сортирует 23-элементный массив в 74 сравнениях, когда нижняя граница равна 75. Исходный код показывает, что для всех чисел, меньших 23, он смог форсировать нижнюю границу, для 100 чисел sort () удалосьделать 506 сравнений, когда нижняя граница равна 525.
Существует ли эффективный противник за полиномиальное время, который заставляет алгоритмы сортировки использовать хотя бы информационную теоретическую границу?