Simplemente puede contar el número de inversiones en la lista.
Inversión
Una inversión en una secuencia de elementos de tipo T
es un par de elementos de secuencia que aparecen fuera de orden de acuerdo con algún orden <
en el conjunto de T
's.
De Wikipedia :
Formalmente, seamos A(1), A(2), ..., A(n)
una secuencia de n
números.
Si i < j
y A(i) > A(j)
, entonces el par (i,j)
se llama inversión de A
.
El número de inversión de una secuencia es una medida común de su clasificación.
Formalmente, el número de inversión se define como el número de inversiones, es decir,
Para aclarar estas definiciones, considere la secuencia de ejemplo 9, 5, 7, 6
. Esta secuencia tiene las inversiones (0,1), (0,2), (0,3), (2,3)
y el número de inversión 4
.
Si desea un valor entre 0
y 1
, puede dividir el número de inversión entre N choose 2
.
Para crear realmente un algoritmo para calcular este puntaje según la clasificación de una lista, tiene dos enfoques:
Enfoque 1 (determinista)
Modifique su algoritmo de clasificación favorito para realizar un seguimiento de cuántas inversiones está corrigiendo mientras se ejecuta. Aunque esto no es trivial y tiene implementaciones diferentes según el algoritmo de clasificación que elija, terminará con un algoritmo que no es más costoso (en términos de complejidad) que el algoritmo de clasificación con el que comenzó.
Si toma esta ruta, tenga en cuenta que no es tan simple como contar "intercambios". Mergesort, por ejemplo, es el peor de los casos O(N log N)
, pero si se ejecuta en una lista ordenada en orden descendente, corregirá todas las N choose 2
inversiones. Eso es O(N^2)
inversiones corregidas en las O(N log N)
operaciones. Por lo tanto, algunas operaciones inevitablemente deben corregir más de una inversión a la vez. Tienes que tener cuidado con tu implementación. Nota: puedes hacer esto con O(N log N)
complejidad, es complicado.
Relacionado: calcular el número de "inversiones" en una permutación
Enfoque 2 (estocástico)
- Muestra aleatoria de pares
(i,j)
, dondei != j
- Para cada par, determine si
list[min(i,j)] < list[max(i,j)]
(0 o 1)
- Calcule el promedio de estas comparaciones y luego normalice por
N choose 2
Yo personalmente seguiría el enfoque estocástico a menos que tenga un requisito de exactitud, aunque solo sea porque es muy fácil de implementar.
Si lo que realmente quiere es un valor ( z'
) entre -1
(ordenado descendente) a 1
(ordenado ascendente), simplemente puede asignar el valor anterior ( z
), que está entre 0
(ordenado ascendente) y 1
(ordenado descendente), a este rango utilizando esta fórmula :
z' = -2 * z + 1