Gibt es eine Möglichkeit zu messen, wie sortiert eine Liste ist?
Ich meine, es geht nicht darum zu wissen, ob eine Liste sortiert ist oder nicht (boolesch), sondern um ein Verhältnis von "Sortierung", so etwas wie den Korrelationskoeffizienten in der Statistik.
Beispielsweise,
Wenn die Elemente einer Liste in aufsteigender Reihenfolge vorliegen, beträgt ihre Rate 1,0
Wenn die Liste absteigend sortiert ist, beträgt ihre Rate -1,0
Wenn die Liste fast aufsteigend sortiert ist, beträgt ihre Rate 0,9 oder einen Wert nahe 1.
Wenn die Liste überhaupt nicht sortiert ist (zufällig), liegt ihre Rate nahe bei 0
Ich schreibe eine kleine Bibliothek in Scala zum Üben. Ich denke, eine Sortierrate wäre nützlich, aber ich finde keine Informationen über so etwas. Vielleicht kenne ich keine angemessenen Begriffe für das Konzept.
Antworten:
Sie können einfach die Anzahl der Inversionen in der Liste zählen.
Inversion
Eine Inversion in einer Folge von Elementen des Typs
T
ist ein Paar von Folgeelementen, die gemäß einer bestimmten Reihenfolge<
auf der Menge vonT
's in der falschen Reihenfolge erscheinen .Aus Wikipedia :
Betrachten Sie die Beispielsequenz, um diese Definitionen klarer zu machen
9, 5, 7, 6
. Diese Sequenz hat die Inversionen(0,1), (0,2), (0,3), (2,3)
und die Inversionsnummer4
.Wenn Sie einen Wert zwischen
0
und möchten1
, können Sie die Inversionszahl durch dividierenN choose 2
.Um tatsächlich einen Algorithmus zum Berechnen dieser Punktzahl für die Sortierung einer Liste zu erstellen, haben Sie zwei Ansätze:
Ansatz 1 (deterministisch)
Ändern Sie Ihren bevorzugten Sortieralgorithmus, um zu verfolgen, wie viele Inversionen während der Ausführung korrigiert werden. Obwohl dies nicht trivial ist und je nach ausgewähltem Sortieralgorithmus unterschiedliche Implementierungen aufweist, erhalten Sie einen Algorithmus, der (in Bezug auf die Komplexität) nicht teurer ist als der Sortieralgorithmus, mit dem Sie begonnen haben.
Wenn Sie diesen Weg einschlagen, beachten Sie, dass es nicht so einfach ist, "Swaps" zu zählen. Mergesort ist beispielsweise der schlimmste Fall
O(N log N)
. Wenn es jedoch in einer Liste ausgeführt wird, die in absteigender Reihenfolge sortiert ist, werden alleN choose 2
Inversionen korrigiert . Das sindO(N^2)
Inversionen, die imO(N log N)
Betrieb korrigiert wurden. Daher müssen einige Operationen zwangsläufig mehr als eine Inversion gleichzeitig korrigieren. Sie müssen mit Ihrer Implementierung vorsichtig sein. Hinweis: Sie können dies mitO(N log N)
Komplexität tun , es ist nur schwierig.Verwandte: Berechnung der Anzahl der "Inversionen" in einer Permutation
Ansatz 2 (stochastisch)
(i,j)
, wobeii != j
list[min(i,j)] < list[max(i,j)]
(0 oder 1)N choose 2
Ich persönlich würde mich für den stochastischen Ansatz entscheiden, es sei denn, Sie haben ein Erfordernis der Genauigkeit - schon allein deshalb, weil es so einfach zu implementieren ist.
Wenn Sie wirklich einen Wert (
z'
) zwischen-1
(sortiert absteigend) bis1
(sortiert aufsteigend) möchten , können Sie den Bereich über (z
), der zwischen0
(sortiert aufsteigend) und1
(sortiert absteigend) liegt, mit dieser Formel einfach diesem Bereich zuordnen ::quelle
Das traditionelle Maß dafür, wie sortiert eine Liste (oder eine andere sequentielle Struktur) ist, ist die Anzahl der Inversionen.
Die Anzahl der Inversionen ist die Anzahl der Paare (a, b) des Index von a <b UND b
<<
a. Für diese Zwecke steht<<
für jede Bestellbeziehung, die Sie für Ihre bestimmte Sorte wählen.Eine vollständig sortierte Liste enthält keine Inversionen, und eine vollständig umgekehrte Liste enthält die maximale Anzahl von Inversionen.
quelle
5 4 3 2 1
ist vollständig sortiert, da die Reihenfolge nicht angegeben ist, aber ich bin pedantisch :-)<
.n choose 2
.Sie können die tatsächliche Korrelation verwenden.
Angenommen, Sie weisen jedem Element in der sortierten Liste einen ganzzahligen Rang ab Null zu. Beachten Sie, dass ein Diagramm des Positionsindex der Elemente gegenüber dem Rang wie Punkte in einer geraden Linie aussieht (Korrelation von 1,0 zwischen Position und Rang).
Sie können eine Korrelation für diese Daten berechnen. Für eine umgekehrte Sortierung erhalten Sie -1 und so weiter.
quelle
Es gab gute Antworten, und ich möchte der Vollständigkeit halber einen mathematischen Aspekt hinzufügen:
Sie können messen, wie sortiert eine Liste ist, indem Sie messen, wie stark sie mit einer sortierten Liste korreliert. Zu diesem Zweck können Sie die Rangkorrelation verwenden (die bekannteste ist die von Spearman ), die genau der üblichen Korrelation entspricht, jedoch den Rang der Elemente in einer Liste anstelle der analogen Werte der Elemente verwendet.
Viele Erweiterungen existieren, wie ein Korrelationskoeffizient (+1 für genaue Art, -1 für die exakte Umkehrung)
Auf diese Weise können Sie statistische Eigenschaften für diese Kennzahl festlegen, z. B. den Satz der zentralen Permutationsgrenze, mit dem Sie die Verteilung dieser Kennzahl für Zufallslisten ermitteln können.
quelle
Abgesehen von der Inversionszahl ist für numerische Listen ein mittlerer quadratischer Abstand vom sortierten Zustand vorstellbar:
quelle
Ich bin mir der "besten" Methode nicht sicher, aber eine einfache wäre, jedes Element mit dem nachfolgenden zu vergleichen, einen Zähler zu erhöhen, wenn element2> Element 1 (oder was auch immer Sie testen möchten) und dann durch die Gesamtzahl zu dividieren von Elementen. Es sollte Ihnen einen Prozentsatz geben.
quelle
Ich würde Vergleiche zählen und auf die Gesamtzahl der Vergleiche aufteilen. Hier ist ein einfaches Python- Beispiel.
quelle
Wie wäre es mit so etwas?
quelle
Wenn Sie Ihre Liste nehmen, die Ränge der Werte in dieser Liste berechnen und die Liste der Ränge
Y
und eine andere Liste aufrufenX
, die die Ganzzahlen von1
bis enthältlength(Y)
, können Sie durch Berechnung des Korrelationskoeffizienten genau das gesuchte Maß für die Sortierung erhalten ,r
, zwischen den beiden Listen.Für eine vollständig sortierte Liste,
r = 1.0
für eine umgekehrt sortierte Lister=-1.0
und dier
Unterschiede zwischen diesen Grenzwerten für unterschiedliche Sortiergrade.Ein mögliches Problem bei diesem Ansatz besteht je nach Anwendung darin, dass die Berechnung des Ranges jedes Elements in der Liste dem Sortieren entspricht, sodass es sich um eine O (n log n) -Operation handelt.
quelle