Вы можете просто посчитать количество инверсий в списке.
инверсия
Инверсия в последовательности элементов типа T
представляет собой пару элементов последовательности, которые появляются не по порядку в соответствии с некоторым порядком <
на множестве T
's.
Из Википедии :
Формально, пусть A(1), A(2), ..., A(n)
будет последовательность n
чисел.
Если i < j
и A(i) > A(j)
, то пара (i,j)
называется инверсией из A
.
Число инверсии последовательности является одной из общих мер ее сортировки.
Формально число инверсии определяется как число инверсий, то есть
Чтобы сделать эти определения более понятными, рассмотрим пример последовательности 9, 5, 7, 6
. Эта последовательность имеет инверсии (0,1), (0,2), (0,3), (2,3)
и номер инверсии 4
.
Если вы хотите значение между 0
и 1
, вы можете разделить число инверсии на N choose 2
.
Чтобы на самом деле создать алгоритм для вычисления этой оценки того, насколько отсортирован список, у вас есть два подхода:
Подход 1 (детерминированный)
Измените свой любимый алгоритм сортировки, чтобы отслеживать, сколько инверсий он исправляет во время работы. Хотя это нетривиально и имеет различные реализации в зависимости от выбранного вами алгоритма сортировки, вы получите алгоритм, который не дороже (с точки зрения сложности), чем алгоритм сортировки, который вы начали.
Если вы выберете этот маршрут, имейте в виду, что это не так просто, как подсчет "свопов". Например, Mergesort является наихудшим случаем O(N log N)
, но если он выполняется в списке, отсортированном в порядке убывания, он исправит все N choose 2
инверсии. Это O(N^2)
инверсии, исправленные в O(N log N)
операциях. Поэтому некоторые операции неизбежно должны корректировать более одной инверсии за раз. Вы должны быть осторожны с вашей реализацией. Примечание: вы можете сделать это со O(N log N)
сложностью, это просто сложно.
Связанный: вычисление количества «инверсий» в перестановке
Подход 2 (Стохастик)
- Случайно выбранные пары
(i,j)
, гдеi != j
- Для каждой пары определите,
list[min(i,j)] < list[max(i,j)]
(0 или 1)
- Вычислить среднее из этих сравнений, а затем нормализовать
N choose 2
Я бы лично использовал стохастический подход, если у вас нет требования к точности - хотя бы потому, что это так просто реализовать.
Если вы действительно хотите получить значение ( z'
) между -1
(отсортировано по убыванию) в 1
(отсортировано по возрастанию), вы можете просто отобразить значение выше ( z
), которое находится между 0
(отсортировано по возрастанию) и 1
(отсортировано по убыванию), в этот диапазон, используя эту формулу :
z' = -2 * z + 1