Vraag Hoe schrijf ik een soort slechter dan O (n!)


Ik schreef een O (n!) Sort voor mijn amusement dat niet triviaal geoptimaliseerd kan worden om sneller te draaien zonder het volledig te vervangen. [En nee, ik heb de items niet willekeurig gesorteerd totdat ze waren gesorteerd].

Hoe kan ik een nog slechtere Big-O-soort schrijven, zonder alleen ongewenste rommel toe te voegen die kan worden verwijderd om de tijdcomplexiteit te verminderen?

http://en.wikipedia.org/wiki/Big_O_notation heeft verschillende tijdcomplexiteiten gesorteerd in oplopende volgorde.

Bewerken: ik heb de code gevonden, hier is mijn O (n!) Deterministische sortering met grappige hack om een ​​lijst van alle combinaties van een lijst te genereren. Ik heb een iets langere versie van get_all_combinations die een aantal combinaties oplevert, maar helaas kon ik er geen enkele verklaring van maken. [Hopelijk heb ik geen bugs geïntroduceerd door het corrigeren van typefouten en het verwijderen van underscores in de onderstaande code]

def mysort(somelist):
    for permutation in get_all_permutations(somelist):
        if is_sorted(permutation):
            return permutation

def is_sorted(somelist):
    # note: this could be merged into return... something like return len(foo) <= 1 or reduce(barf)
    if (len(somelist) <= 1): return True
    return 1 > reduce(lambda x,y: max(x,y),map(cmp, somelist[:-1], somelist[1:]))

def get_all_permutations(lst):
    return [[itm] + cbo for idx, itm in enumerate(lst) for cbo in get_all_permutations(lst[:idx] + lst[idx+1:])] or [lst]

10
2017-08-25 02:05


oorsprong


antwoorden:


Er is een (bewezen!) Slechtst sorteeralgoritme genoemd langzaam sorteren die het "vermenigvuldigen en overgeven" -paradigma gebruikt en in exponentiële tijd draait.

Hoewel uw algoritme langzamer is, wordt het niet gestaag verdergezet, maar worden willekeurige sprongen uitgevoerd. Bovendien is het beste geval van het trage sorteerprogramma nog steeds exponentieel terwijl het uwe constant is.


8
2017-08-25 10:58



Chris en ik noemde Bozosort en bogosort in een andere vraag.


3
2017-08-25 02:11



Er is altijd NeverSort, wat O (∞) is:

def never_sort(array)
  while(true)
  end
  return quicksort(array)
end

PS: Ik wil echt je deterministische O (n!) Soort zien; Ik kan niet denken aan O (n!), Maar heb een eindige bovengrens in klassieke berekening (oftewel deterministisch).

PPS: als je je zorgen maakt over het feit dat de compiler die leeg in blok uitroept, kun je het dwingen om het niet te doen door een variabele zowel binnen als buiten het blok te gebruiken:

def never_sort(array)
  i=0
  while(true) { i += 1 }
  puts "done with loop after #{i} iterations!"
  return quicksort(array)
end

2
2017-08-25 03:00



Je zou altijd een willekeurige sortering kunnen doen. Het werkt door alle elementen willekeurig te rangschikken en vervolgens te controleren of het is gesorteerd. Zo niet, dan worden ze willekeurig gerangschikt. Ik weet niet hoe het zou passen in big-O notatie, maar het zal zeker langzaam zijn!


1
2017-08-26 13:57



Hier is de langzaamste, eindige soort die je kunt krijgen:

Koppel elke bewerking van Quicksort aan de bezige Beaver-functie.

Tegen de tijd dat u> 4 bewerkingen krijgt, heeft u een up-arrow-notatie nodig :)


1
2017-10-07 13:15



Een manier die ik kan bedenken is om de positie van elk element te berekenen via een functie die geleidelijk varieert, de grote elementen naar het einde en de kleine naar het begin. Als je een op trig-gebaseerde functie gebruikte, kon je de elementen laten oscilleren door de lijst in plaats van direct naar hun uiteindelijke positie te gaan. Nadat u elk element in de set hebt verwerkt, voert u een volledige traversal uit om te bepalen of de array is gesorteerd of niet.

Ik ben niet zeker dat dit je O (n!) Zal geven, maar het zou nog steeds behoorlijk traag moeten zijn.


0
2017-08-25 02:18



Ik denk dat als je veel kopieert, je een "redelijke" zoekopdracht met brute kracht (N!) Kunt krijgen om N ^ 2 keer per geval te nemen, waardoor N! * N ^ 2


0
2017-08-25 03:23



Hoe zit het met lus over alle arrays t van n gehele getallen (n-tuples van gehele getallen zijn telbaar, dus dit is te doen hoewel het een oneindige lus is natuurlijk), en voor elk van deze:

  • als de elementen precies die van de invoerarray zijn (zie algo hieronder!) en de array is gesorteerd (bijvoorbeeld lineaire alg, maar ik weet zeker dat we erger kunnen doen), keer dan terug t;
  • anders blijven lussen.

Om te controleren of twee arrays a en b van lengte n dezelfde elementen bevatten, wat dacht je van het volgende recursieve algoritme: loop over alle paren (i, j) van indexen tussen 0 en n-1, en voor elk van deze paren

  • test of een [i] == b [j]:
  • als dat het geval is, retourneert u TRUE als en alleen als een recursieve aanroep van de lijsten die is verkregen door een [i] uit a en b [j] uit b te verwijderen, WAAR geeft;
  • ga door met het doorlopen van koppels, en als alle koppels klaar zijn, geef ONWAAR terug.

De tijd zal sterk afhangen van de verdeling van gehele getallen in de invoerreeks.

Maar serieus, is er een punt voor zo'n vraag?

Bewerk:

@Jon, je willekeurige sortering zou gemiddeld in O (n!) Staan (aangezien er n! Permutaties zijn, heb je kans 1 / n! Om de juiste te vinden). Dit geldt voor arrays met verschillende gehele getallen, kan enigszins verschillen als sommige elementen meerdere occurrences hebben in de input-array, en zou dan afhangen van de verdeling van de elementen van de input-arrays (in de gehele getallen).


0
2017-08-26 13:33