Che cos'è la stabilità negli algoritmi di ordinamento e perché è importante?


292

Sono molto curioso, perché la stabilità è o non è importante negli algoritmi di ordinamento?


2
Ai fini della parallelizzazione? ad esempio: unisci ordinamento è stabile e può essere parallelizzato bene, così come quicksort.
DarthVader,

13
Classic QuickSort è instabile
Konstantin Spirin,

9
stable sort algo -IBM (Insertion, Bubble, Merge)
roottraveller

Una nota per coloro che potrebbero aver frainteso il concetto come me: l'ordine di elementi uguali è garantito per essere preservato. significa: se gli elementi in ordine stabile sono considerati uguali, seguiranno l'ordine precedente. Non è quello che pensavo: se gli elementi nell'ordine precedente fossero considerati uguali, nel prossimo ordinamento stabile, seguiranno l'ordine precedente. Anche se potresti trovare quest'ultima comprensione ha anche senso in molti casi.
Rick,

Risposte:


371

Si dice che un algoritmo di ordinamento è stabile se due oggetti con chiavi uguali compaiono nello stesso ordine nell'output ordinato come appaiono nell'array di input da ordinare. Alcuni algoritmi di ordinamento sono stabili per natura come Inserimento ordinamento, Merge Sort, Bubble Sort, ecc. E alcuni algoritmi di ordinamento non lo sono, come Heap Sort, Quick Sort, ecc.

Background : un algoritmo di ordinamento "stabile" mantiene gli articoli con la stessa chiave di ordinamento in ordine. Supponiamo di avere un elenco di parole di 5 lettere:

peach
straw
apple
spork

Se ordiniamo l'elenco solo per la prima lettera di ogni parola, allora un ordinamento stabile produrrebbe:

apple
peach
straw
spork

In un algoritmo di ordinamento instabile , strawo sporkpossono essere scambiati, ma in uno stabile, rimangono nelle stesse posizioni relative (cioè, poiché strawappare prima sporknell'input, appare anche prima sporknell'output).

Potremmo ordinare l'elenco di parole usando questo algoritmo: ordinamento stabile per colonna 5, quindi 4, quindi 3, quindi 2, quindi 1. Alla fine, verrà ordinato correttamente. Convinciti di quello. (a proposito, quell'algoritmo si chiama radix sort)

Ora per rispondere alla tua domanda, supponiamo di avere un elenco di nomi e cognomi. Ci viene chiesto di ordinare "per cognome, poi per primo". Potremmo prima ordinare (stabile o instabile) per nome, quindi ordinare stabile per cognome. Dopo questi tipi, l'elenco viene ordinato principalmente in base al cognome. Tuttavia, dove i cognomi sono gli stessi, i nomi vengono ordinati.

Non è possibile impilare tipi instabili allo stesso modo.


Quindi, come si chiamerebbe questo tipo per rendere le parole nel corretto ordinamento della cannuccia sportiva pesca mela? L'ordinamento stabile ci ha fornito spork di paglia di pesca di mele, tuttavia la m dovrebbe essere dopo sp (alfabeticamente corretta), quindi l'ultimo ordinamento corretto dovrebbe essere lo sport di pesca di mele
user1416486

2
@ user1416486: stiamo ordinando solo per la prima lettera. Con tale presupposto, strawe sporkconfrontare uguale. L'ordinamento stabile manterrà l'ordine di input, mentre l'ordinamento instabile non garantisce tale garanzia. "Corretto" dipende dall'applicazione. La funzione di ordinamento nella maggior parte dei linguaggi di programmazione consente all'utente di fornire una funzione di ordinazione personalizzata. Se la funzione dell'utente considera diversi articoli uguali (ad es. Stesso nome, cognome diverso), aiuta a sapere se l'ordine originale verrà conservato. Vedi le funzioni di ordinamento degli array di OCaml per un esempio reale.
Joey Adams,

3
Non capisco la linea .. stessa chiave di ordinamento ? Cosa intendi per chiave qui? Spiegare la frase .. stessa chiave di ordinamento
saplingPro

2
@saplingPro: per "chiave di ordinamento", intendo la cosa per cui stai ordinando gli oggetti. Quindi, quando si ordina per prima lettera, quindi per ogni elemento, la sua "chiave di ordinamento" è la sua prima lettera.
Joey Adams,

12
Esempio: supponiamo di avere un elenco con ciascun elemento contenente informazioni sulla destinazione del volo e l'orario di partenza. Prima devi ordinare l'elenco in base al tempo. Quindi lo ordiniamo in base alla destinazione. Se il secondo tipo è stabile , ora abbiamo tutti i voli associati alla stessa destinazione insieme e in ordine crescente di orario di partenza. Se non fosse stabile, non sarebbero in ordine crescente di tempo.
Roottraveller,

55

Un algoritmo di ordinamento stabile è quello che ordina gli elementi identici nel loro stesso ordine come appaiono nell'input, mentre l'ordinamento instabile potrebbe non soddisfare il caso. - Ringrazio il mio docente di algoritmi Didem Gozupek per aver fornito informazioni sugli algoritmi .

Algoritmi di ordinamento stabili:

  • Ordinamento inserzione
  • Unisci ordinamento
  • Bubble Sort
  • Tim Sort
  • Conteggio ordinamento
  • Block Sort
  • Quadsort
  • Ordinamento libreria
  • Agitatore per cocktail Sort
  • Gnome Sort
  • Ordinamento dispari-pari

Algoritmi di ordinamento instabili:

  • Ordinamento dell'heap
  • Ordinamento di selezione
  • Ordinamento Shell
  • Ordinamento rapido
  • Introsort (soggetto a Quicksort)
  • Ordinamento degli alberi
  • Ordinamento del ciclo
  • smoothsort
  • Ordinamento del torneo (soggetto a Hesapsort)

inserisci qui la descrizione dell'immagine


2
I tuoi valori non sono uguali. Confronti 9,7 e 9,8 ma, secondo il controllo di stabilità, hai bisogno degli stessi valori di entrambi 9,7 o entrambi 9,8. E che gli stessi valori dovrebbero essere ordinati nello stesso in algoritmi stabili.
Erhun,

1
No, per verificare la stabilità i tuoi valori dovrebbero essere gli stessi. Intendo supporre che tu usi due 9,7 e lo chiami sul nodo A e sul nodo B. Se ogni ordinamento è come A, B (invece che sono uguali) capisci che l'algoritmo di ordinamento è stabile (come unisci ordinamento). Se l'ordine A, B cambia quando li ordina più volte (1. ordina A, B poi B, A di nuovo A, B ecc.), Capisci che l'algoritmo di ordinamento è instabile (come l'ordinamento rapido) @snr
erhun

@snr [9, 6] non è presente nell'array di input. Penso che intendessi [9, 8] nell'ultima striscia di array.
Usman,

4
@erhun Credo che stia ordinando solo per il primo numero (quello prima della virgola) e usando il secondo numero solo come riferimento per farti vedere che il primo 9 è diverso dal secondo 9.
Tiago

20

Stabilità dell'ordinamento significa che i record con la stessa chiave mantengono il loro ordine relativo prima e dopo l'ordinamento.

Quindi la stabilità conta se, e solo se, il problema che stai risolvendo richiede il mantenimento di quell'ordine relativo.

Se non hai bisogno di stabilità, puoi utilizzare un algoritmo veloce e con memoria da una libreria, come heapsort o quicksort, e dimenticartene.

Se hai bisogno di stabilità, è più complicato. Gli algoritmi stabili hanno un utilizzo maggiore della CPU e / o della memoria big-O rispetto agli algoritmi instabili. Quindi, quando si dispone di un set di dati di grandi dimensioni, è necessario scegliere tra battere la CPU o la memoria. Se sei limitato su CPU e memoria, hai un problema. Un buon algoritmo stabile di compromesso è un ordinamento ad albero binario; l' articolo di Wikipedia ha un'implementazione C ++ pateticamente semplice basata sull'STL.

È possibile trasformare un algoritmo instabile in uno stabile aggiungendo il numero del record originale come chiave dell'ultimo posto per ciascun record.


1
Gli algoritmi stabili come Merge Sort hanno la stessa complessità O (NlogN) di Quicksort; il moltiplicatore costante dello sforzo è però più grande.
Jonathan Leffler,

Sì, e l'utilizzo della memoria in Merge Sort è O (N), mentre in Quicksort è O (log N). Il motivo per cui ho citato Quicksort è che qsort () è una routine di libreria standard C, quindi è davvero disponibile.
Bob Murphy,

1
Migliore risposta generale IMHO. la tecnica multi-chiave menzionata in altre è interessante ma sopravvalutata; è semplice da applicare, ma tende ad essere molto più lento delle alternative ovvie (basta usare un ordinamento con un confronto multi-chiave; o ordinare per la prima chiave quindi identificare e ordinare tutte le liste secondarie con duplicati). Il fatto che l'ordinamento stabile produca un risultato prevedibile può essere importante in alcune app. In particolare se si hanno due elenchi di input A, B che sono identici tranne che l'elenco B ha una voce aggiuntiva, le uscite per un ordinamento stabile saranno identiche tranne che B ha quella stessa voce aggiuntiva. E +1 per l'ultimo pgph.
Greggo,

16

Dipende da cosa fai.

Immagina di avere alcuni record di persone con un campo nome e cognome. Innanzitutto ordina l'elenco per nome. Se poi si ordina l'elenco con un algoritmo stabile per cognome, si avrà un elenco ordinato per nome E cognome.


4
Penso che intendi "cognome E nome". Il cognome è in genere il cognome.
Bacon Bits

14

Ci sono alcuni motivi per cui la stabilità può essere importante. Uno è che, se non è necessario scambiare due record scambiandoli, è possibile causare un aggiornamento della memoria, una pagina viene contrassegnata come sporca e deve essere riscritta su disco (o un altro supporto lento).


Cosa ha a che fare lo scambio di record con la stabilità?
user1683793

4

Si dice che un algoritmo di ordinamento è stabile se due oggetti con chiavi uguali compaiono nello stesso ordine nell'output ordinato come appaiono nell'array di input non ordinato. Alcuni algoritmi di ordinamento sono stabili per natura come Inserimento ordinamento, Merge Sort, Bubble Sort, ecc. E alcuni algoritmi di ordinamento non lo sono, come Heap Sort, Quick Sort, ecc.

Tuttavia, qualsiasi dato algoritmo di ordinamento che non è stabile può essere modificato per essere stabile. Ci possono essere modi specifici di ordinamento per renderlo stabile, ma in generale, qualsiasi algoritmo di ordinamento basato sul confronto che non è stabile per natura può essere modificato per essere stabile cambiando l'operazione di confronto dei tasti in modo che il confronto di due tasti consideri la posizione come un fattore per oggetti con chiavi uguali.

Riferimenti: http://www.math.uic.edu/~leon/cs-mcs401-s08/handouts/stability.pdf http://en.wikipedia.org/wiki/Sorting_algorithm#Stability


3

So che ci sono molte risposte per questo, ma per me questa risposta , di Robert Harvey , l'ha sintetizzata molto più chiaramente:

Un ordinamento stabile è uno che preserva l'ordine originale del set di input, in cui l'algoritmo [instabile] non distingue tra due o più elementi.

fonte


1

Se supponi che ciò che stai ordinando siano solo numeri e solo i loro valori li identificano / li distinguono (ad es. Elementi con lo stesso valore sono identici), allora il problema di stabilità dell'ordinamento è insignificante.

Tuttavia, gli oggetti con la stessa priorità nell'ordinamento possono essere distinti e talvolta il loro ordine relativo è un'informazione significativa. In questo caso, l'ordinamento instabile genera problemi.

Ad esempio, hai un elenco di dati che contiene il costo del tempo [T] di tutti i giocatori per pulire un labirinto con Livello [L] in una partita. Supponiamo di dover classificare i giocatori in base alla velocità con cui puliscono il labirinto. Tuttavia, si applica una regola aggiuntiva: i giocatori che puliscono il labirinto con un livello superiore hanno sempre un rango più alto, indipendentemente da quanto tempo sia il costo.

Naturalmente potresti provare a mappare il valore accoppiato [T, L] su un numero reale [R] con un algoritmo che segue le regole e quindi classificare tutti i giocatori con valore [R].

Tuttavia, se è possibile un ordinamento stabile, puoi semplicemente ordinare l'intero elenco per [T] (prima i giocatori più veloci) e poi per [L]. In questo caso, l'ordine relativo dei giocatori (in base al costo del tempo) non verrà modificato dopo averli raggruppati per livello di labirinto che hanno pulito.

PS: ovviamente l'approccio per ordinare due volte non è la soluzione migliore al problema particolare, ma per spiegare la questione del poster dovrebbe essere sufficiente.


0

L'ordinamento stabile restituirà sempre la stessa soluzione (permutazione) sullo stesso input.

Ad esempio [2,1,2] verrà ordinato usando l'ordinamento stabile come permutazione [2,1,3] (prima l'indice 2, quindi l'indice 1 quindi l'indice 3 nell'output ordinato) Ciò significa che l'output viene sempre mischiato allo stesso modo. Un'altra permutazione non stabile, ma ancora corretta è [2,3,1].

L'ordinamento rapido non è un ordinamento stabile e le differenze di permutazione tra gli stessi elementi dipendono dall'algoritmo per la selezione del perno. Alcune implementazioni prendono a caso e ciò può rendere veloce l'ordinamento producendo permutazioni diverse sullo stesso input usando lo stesso algoritmo.

L'algoritmo di ordinamento stabile è deterministico necessario.


2
Non è questo che significa stabilità. Vedi en.wikipedia.org/wiki/Sorting_algorithm#Stability
Luís Oliveira

Dovrei correggere l'ultima frase che l'ordinamento non stabile può produrre una soluzione diversa anche tra la stessa implementazione, dove qualsiasi ordinamento stabile produce la stessa soluzione.
Luka Rahne,

1
Perché -1? Qualcuno può far notare per favore cosa c'è di sbagliato qui? Non si tratta dell'ordinamento stabile, ma dell'ordinamento stabile delle proprietà.
Luka Rahne,

Se l'ordinamento è deterministico o meno non determina se è stabile. Sono in grado di scrivere un algoritmo di ordinamento deterministico non stabile definendo un diverso comportamento di rottura (ad esempio, con il sotto-ordinamento di parti non chiave). L'ordinamento stabile implica specificamente che l'ordine relativo pre-ordinato degli elementi venga preservato quando vengono ordinati i legami. esempio di un'uscita di una sorta stabile: sort([(5,3),(1,5),(3,3),(1,3)], x) => [(1,5),(1,3),(3,3),(5,3)]. Posso fare un ordinamento deterministico che produce sempre (deterministicamente): [(1,3),(1,5),(3,3),(5,3)]ma questo non è un ordinamento stabile.
cowbert,

@cowbert È più un'affermazione sulla proprietà che ha ogni tipo stabile. Non importa se viene utilizzato un algoritmo o un'implementazione di ordinamento stabile, ogni volta che si otterrà lo stesso risultato. È più difficile mantenere tale proprietà tra diverse implementazioni di ordinamento non stabili.
Luka Rahne,

0

Alcuni altri esempi del motivo per volere tipi stabili. I database sono un esempio comune. Prendiamo il caso di una base di dati di transazione che include cognome | nome, data | ora di acquisto, numero articolo, prezzo. Supponiamo che il database sia normalmente ordinato per data | ora. Quindi viene eseguita una query per creare una copia ordinata della base di dati in base al cognome |, poiché un ordinamento stabile preserva l'ordine originale, anche se il confronto delle richieste comporta solo il cognome |, le transazioni per ciascun | cognome essere nell'ordine di data | time.

Un esempio simile è Excel classico, che ha limitato l'ordinamento a 3 colonne alla volta. Per ordinare 6 colonne, viene eseguito un ordinamento con le 3 colonne meno significative, seguito da un ordinamento con le 3 colonne più significative.

Un classico esempio di ordinamento radix stabile è uno smistatore di carte, utilizzato per ordinare in base a un campo di 10 colonne numeriche di base. Le carte sono ordinate dalla cifra meno significativa alla cifra più significativa. Ad ogni passaggio, un mazzo di carte viene letto e diviso in 10 diversi contenitori in base alla cifra in quella colonna. Quindi i 10 scomparti di carte vengono rimessi nell'hopper di input in ordine (prima le carte "0", le ultime "9"). Quindi un altro passaggio viene eseguito dalla colonna successiva, fino a quando tutte le colonne non vengono ordinate. I selezionatori di carte effettivi hanno più di 10 scomparti poiché ci sono 12 zone su una carta, una colonna può essere vuota e c'è un cestino erroneamente letto. Per ordinare le lettere, sono necessari 2 passaggi per colonna, 1 ° passaggio per cifra, 2 ° passaggio per la zona 12 11.

Più tardi (1937) c'erano macchine per la raccolta (fusione) di carte che potevano unire due mazzi di carte confrontando i campi. L'input consisteva in due mazzi di carte già ordinati, un mazzo principale e un mazzo di aggiornamento. Il raccoglitore ha unito i due deck in un nuovo contenitore di materiali e un contenitore di archiviazione, che è stato facoltativamente utilizzato per i duplicati principali in modo che il nuovo contenitore principale avesse solo schede di aggiornamento in caso di duplicati. Questa è stata probabilmente la base dell'idea alla base della fusione originale (dal basso verso l'alto).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.