Se si dispone di 5 numeri distinti, quanti confronti al massimo è necessario ordinare utilizzando l'ordinamento di unione?Numero di confronti utilizzando l'ordinamento di unione
risposta
trovo la domanda interessante, così ho deciso di esplorare a fondo (con un po 'di sperimentazione in Python).
Ho scaricato mergesort.py
da here e l'ho modificato per aggiungere un argomento cmp
per una funzione comparatore.Poi:
import collections
import itertools
import mergesort
import sys
class CountingComparator(object):
def __init__(self):
self.count = 0
def __call__(self, a, b):
self.count += 1
return cmp(a, b)
ms_histo = collections.defaultdict(int)
for perm in itertools.permutations(range(int(sys.argv[1]))):
cc = CountingComparator()
lperm = list(perm)
mergesort.mergesort(lperm, cmp=cc)
ms_histo[cc.count] += 1
for c in sorted(ms_histo):
print "%d %2d" % (c, ms_histo[c])
Il risultante semplice istogramma (iniziando con una lunghezza di 4, come ho fatto per lo sviluppo e il debugging questo) è:
4 8
5 16
Per il problema come inviato, con una lunghezza di 5 invece di 4, ottengo:
5 4
6 20
7 48
8 48
e con una lunghezza di 6 (e di un formato più ampio ;-):
7 8
8 56
9 176
10 288
11 192
Infine, con una lunghezza di 7 (formato e ancora più ampia ;-):
9 16
10 128
11 480
12 1216
13 1920
14 1280
Sicuramente qualche formula combinatoria perfettamente regolare annida qui, ma mi sto trovando difficile valutare cosa potrebbe essere, sia analiticamente o esaminando i numeri. Qualcuno ha dei suggerimenti?
bel lavoro. Apprezzo molto la tua curiosità e interesse per l'argomento. Osservando i risultati, puoi vedere che il numero di confronti è superiore a n e inferiore a 2n. Wiki suggerisce: Nel peggiore dei casi, l'unione di ordinamento fa una quantità di confronti uguale o leggermente inferiore a (n ⌈lg n⌉ - 2⌈lg n⌉ + 1), che è tra (n lg n - n + 1) e (n lg n + n + O (lg n)). [1] – DarthVader
Secondo Wikipedia: Nel peggiore dei casi, merge sort fa una quantità di confronti uguale o leggermente inferiore (n ⌈lg n⌉ - 2^⌈lg n⌉ + 1)
Ho letto che volevo solo vedere il numero. quindi posso dire: 5 * 3 - 2 * 3 +1 = 10 . Ero anche curioso di questa istanza dei numeri. – DarthVader
Poiché ⌈lg 5⌉ è 2, la risposta è 5 * 2-2^2 + 1 = 7. Ciò ha senso se si segue l'algoritmo come descritto nell'articolo. Se la sequenza iniziale è 2,4,1,3,5, i confronti saranno, in ordine di apparizione: (2,4) (2,1) (3,5) (1,3) (2,3) (4,3) (4,5) – SteinNorheim
Che ne dici di 2,4,5,3,1? – Zed
Quando unione -sortando due liste di lunghezza L1 e L2, suppongo che il peggiore dei casi di confronto sia L1 + L2-1.
- Inizialmente si hanno cinque elenchi di 1 lunghezza.
- È possibile unire due coppie di liste con 2 paragoni, con conseguente liste di lunghezza 2,2 e 1.
- Quindi è possibile unire una lunga lista 2 e 1 con al più un altro 1 + 2-1 = 2 confronti, ottenendo una lista lunga 2 e 3.
- Infine unisci queste liste al massimo 2 + 3-1 = 4 confronti.
Quindi credo che la risposta è 8.
Questa sequenza di numeri risultati in quanto sopra: [2], [4], [1], [3], [5] -> [ 2,4], [1,3], [5] -> [2,4], [1,3,5] -> [1,2,3,4,5]
Modifica:
Ecco un'implementazione ingenua di Erlang. Sulla base di questo, il numero di confronti è 5,6,7 o 8 per le permutazioni di 1,5.
-module(mergesort).
-compile(export_all).
test() ->
lists:sort([{sort(L),L} || L <- permutations()]).
sort([]) -> {0, []};
sort([_] = L) -> {0, L};
sort(L) ->
{L1, L2} = lists:split(length(L) div 2, L),
{C1, SL1} = sort(L1), {C2, SL2} = sort(L2),
{C3, RL} = merge(SL1, SL2, [], 0),
{C1+C2+C3, RL}.
merge([], L2, Merged, Comps) -> {Comps, Merged ++ L2};
merge(L1, [], Merged, Comps) -> {Comps, Merged ++ L1};
merge([H1|T1], [H2|_] = L2, Merged, Comps) when H1 < H2 -> merge(T1, L2, Merged ++[H1], Comps + 1);
merge(L1, [H2|T2], Merged, Comps) -> merge(L1, T2, Merged ++[H2], Comps + 1).
permutations() ->
L = lists:seq(1,5),
[[A,B,C,D,E] || A <- L, B <- L, C <- L, D <- L, E <- L, A =/= B, A =/= C, A =/= D, A =/= E, B =/= C, B =/= D, B =/= E, C =/= D, C =/= E, D =/= E].
Cosa vi impedisce di codifica di un merge sort, mantenendo un contatore per il numero di confronti in esso, e provarlo su tutte le permutazioni di [0,1,2,3,4]?
Mi piace la tua risposta, non ho molto tempo per codificarla. Ho guardato queste applet di smistamento e alcune di esse sono semplicemente sbagliate, alcune sono solo foto. – DarthVader
L'ordinamento unione non richiede molto tempo per il codice che probabilmente stai pensando. È piuttosto breve in Python (e penso che sia ancora più breve in molti linguaggi funzionali), e una soluzione C/C++/Java di base non dovrebbe essere troppo lunga. – MAK
per soli cinque numeri distinti per ordinare, il numero massimo di confronti si può avere è 8 e il numero minimo di confronti è 7. Ecco perché: -
Supponiamo che la matrice è a, b, c, d, e
divide ricorsivamente: a, b, c, d, e
divide ricorsivamente: a, b & ced & e
divide ricorsivo: una & b & ced & e
Ora, fusione che richiederà comparison-
un & b: Confronto uno a formare una, b
a, b & c: due confronti per formare a, b , c
d & e: un confronto per formare d, e
a, b, c, d, e: quattro comparatore nel peggiore dei casi o tre confronti id d è l'elemento più grande di matrice per formare a, b, c, d, e
Quindi, il numero totale di confronti sarà otto nel caso peggiore e sette nel migliore dei casi.
- 1. Ordinamento di un array con un numero minimo di confronti
- 2. F # Numero di tipo Unione discriminato
- 3. Unione SQLAlchemy con diverso numero di colonne
- 4. unione mysql numero diverso di colonne
- 5. Unione di celle in Excel utilizzando C#
- 6. Unione di due tabelle con diverso numero di colonne
- 7. * nix: esegue unione unione/intersezione/differenza di elenchi
- 8. Confronti diretti di tipi di valore C#
- 9. unione di due file
- 10. unione tutte con query con un diverso numero di colonne
- 11. Unione di righe di codice selettive utilizzando Git?
- 12. Unione di due variabili IQueryable di diversi tipi utilizzando LINQ
- 13. Unione di stringhe con limite
- 14. Documenti di unione
- 15. Unione unione php unione senza rimuovere la chiave di matrice
- 16. Confronti con i tipi numerici di Scala?
- 17. Costo delle prestazioni dei confronti di tipo
- 18. Unione/unione di matrici in C#
- 19. Unione di documenti xml
- 20. tipi iterabili comprensione confronti
- 21. Algoritmo di ordinamento di elenchi per confronti effettuati dall'uomo
- 22. Unione di ramo a tronco in SVN utilizzando Eclipse
- 23. Unione di file su AWS S3 (utilizzando Apache Camel)
- 24. Unione di due linee consecutive utilizzando awk o sed
- 25. Unione di elementi array NumPy utilizzando join() in pitone
- 26. Lua ha confronti O?
- 27. confronti stringa bash
- 28. Aree rettangolari di unione (unione booleana) con precisione intera
- 29. Funzione Ceil utilizzando un numero limitato di operatori aritmetici
- 30. come usare Java 8 funzione di unione per il numero n di HashMaps
Beh, io sono uno studente ma questa non è una domanda a casa. Solo curioso. O (nlogn) è il caso peggiore di merge sort. che arriva a 5 * 2.3 = 11 confronti, ma quando lo faccio sulla carta, ottengo risultati migliori, quindi ero curioso. Quanti confronti abbiamo bisogno di ordinare questo nel peggiore dei casi? – DarthVader
Il caso "peggiore" sarebbe quello di confrontare ogni numero con un altro numero pari a 10. – Zed
Uguale a bubble sort, tipo di inserimento o selezione. puoi dare la sequenza di 5 numeri per il caso peggiore? – DarthVader