Puoi semplicemente contare il numero di inversioni nell'elenco.
Inversione
Un'inversione in una sequenza di elementi di tipo Tè una coppia di elementi di sequenza che appaiono fuori ordine secondo alcuni ordinamenti <sull'insieme di T's.
Da Wikipedia :
Formalmente, A(1), A(2), ..., A(n)sia una sequenza di nnumeri.
Se i < je A(i) > A(j), la coppia (i,j)viene chiamata inversione di A.
Il numero di inversione di una sequenza è una misura comune della sua ordinamento.
Formalmente, il numero di inversione è definito come il numero di inversioni, ovvero

Per rendere più chiare queste definizioni, considerare la sequenza di esempio 9, 5, 7, 6. Questa sequenza ha le inversioni (0,1), (0,2), (0,3), (2,3) e il numero di inversione 4 .
Se si desidera un valore tra 0e 1, è possibile dividere il numero di inversione per N choose 2.
Per creare effettivamente un algoritmo per calcolare questo punteggio per quanto è ordinato un elenco, hai due approcci:
Approccio 1 (deterministico)
Modifica il tuo algoritmo di ordinamento preferito per tenere traccia di quante inversioni corregge durante l'esecuzione. Anche se questo non è banale e ha implementazioni variabili a seconda dell'algoritmo di ordinamento che scegli, finirai con un algoritmo che non è più costoso (in termini di complessità) rispetto all'algoritmo di ordinamento che hai iniziato.
Se segui questa strada, tieni presente che non è semplice come contare gli "swap". Mergesort, ad esempio, è il caso peggiore O(N log N), ma se viene eseguito in un elenco ordinato in ordine decrescente, correggerà tutte le N choose 2inversioni. Sono O(N^2)inversioni corrette nelle O(N log N)operazioni. Quindi alcune operazioni devono inevitabilmente correggere più di una inversione alla volta. Devi stare attento con la tua implementazione. Nota: puoi farlo con O(N log N)complessità, è solo complicato.
Correlato: calcolo del numero di "inversioni" in una permutazione
Approccio 2 (stocastico)
- Campionare casualmente coppie
(i,j), dovei != j
- Per ogni coppia, determinare se
list[min(i,j)] < list[max(i,j)](0 o 1)
- Calcola la media di questi confronti e poi normalizza per
N choose 2
Personalmente seguirei l'approccio stocastico a meno che tu non abbia un requisito di precisione, se non altro perché è così facile da implementare.
Se quello che vuoi veramente è un valore ( z') tra -1(in ordine decrescente) a 1(in ordine crescente), puoi semplicemente mappare il valore sopra ( z), che è tra 0(in ordine crescente) e 1(in ordine decrescente), a questo intervallo usando questa formula :
z' = -2 * z + 1