Würde dies als O (1) -Algorithmus für "Hallo Welt!" ??
public class Hello1
{
public static void Main()
{
DateTime TwentyYearsLater = new DateTime(2035,01,01);
while ( DateTime.Now < TwentyYearsLater )
{
System.Console.WriteLine("It's still not time to print the hello ...");
}
System.Console.WriteLine("Hello, World!");
}
}
Ich denke darüber nach, die zu verwenden
DateTime TwentyYearsLater = new DateTime(2035,01,01);
while ( DateTime.Now < TwentyYearsLater )
{
// ...
}
Codeausschnitt als Besetztschleife, die als Witz eingefügt werden kann, wenn jemand nach einem Algorithmus einer bestimmten Komplexität fragt. Wäre das richtig?
O(N)
keine KomplexitätO(1)
N
, von denen der Algorithmus abhängig ist, daher kann man nicht sagen, dass es sich um einen O (N) -Algorithmus handelt.N
macht also nicht einmal Sinn. Sie können jedochDateTime.Now
eine Eingabe in Betracht ziehen , die dies immer noch vom Ergebnis abhängig macht. Wenn Sie einen realistischen Wert für annehmen könnenDateTime.Now
, dann wiederholt das Programm eine konstante Anzahl von Malen.Antworten:
Die Big O-Notation wird in diesem Zusammenhang verwendet, um eine Beziehung zwischen der Größe der Eingabe einer Funktion und der Anzahl der Operationen zu beschreiben, die ausgeführt werden müssen, um das Ergebnis für diese Eingabe zu berechnen.
Ihre Operation hat keine Eingabe, auf die sich die Ausgabe beziehen kann, daher ist die Verwendung der Big O-Notation unsinnig. Die Zeit, die die Operation benötigt, ist unabhängig von den Eingaben der Operation (dh ... keine). Da ist keine Beziehung zwischen dem Eingang und der Anzahl von Operationen durchgeführt, können Sie Big O nicht , dass nicht vorhandene Beziehung zu beschreiben ,
quelle
O(max(1, 2035 - yearTheProgramIsStarted))
?DateTime
für die Startzeit als Eingabe. Wie ich bereits sagte, kann sich die Systemuhr im Laufe der Zeit ändern . Auch hier können Sie die von Ihnen beschriebene Quazi-Eingabe nicht direkt einer festen Ausgabe zuordnen. Es ist keine bekannte Anzahl von Vorgängen für eine bestimmte Startzeit oder sogar für zwei Programme bekannt, die immer einen vernünftigen Wert von erhaltenDateTime.Now
. Sie können die beiden also nicht in Beziehung setzen, wenn sich die Zeit ändert, da Sie sie nicht einmal in Beziehung setzen können, wenn Die Zeit ändert sich nicht .Big-O-Notation bedeutet ungefähr "bei einer Operation mit einem Arbeitsaufwand N, wie viel Rechenzeit, proportional zu N, benötigt der Algorithmus?". Zum Beispiel kann das Sortieren eines Arrays der Größe N N ^ 2, Nlog (N) usw. dauern.
Dies hat keine Menge an Eingabedaten, auf die reagiert werden kann. Also ist es nicht
O(anything)
.Noch schlimmer; Dies ist technisch gesehen kein Algorithmus. Ein Algorithmus ist eine Methode zur Berechnung des Werts einer mathematischen Funktion. Mathematikfunktionen sind eine Zuordnung von einer Eingabe zu einer Ausgabe. Da dies keine Eingabe erfordert und nichts zurückgibt, ist es keine Funktion im mathematischen Sinne. Aus Wikipedia:
Was dies technisch ist, ist ein Steuerungssystem. Aus Wikipedia;
Für Leute, die eine detailliertere Antwort auf den Unterschied zwischen mathematischen Funktionen und Algorithmen und die leistungsfähigeren Fähigkeiten von Computern wünschen, um nebensächliche Dinge wie Konsolenausgabe, Anzeige von Grafiken oder Steuerung von Robotern zu tun, gibt es eine lesen Sie dieses Dokument auf der Starke kirchliche Hypothese
Abstrakt
quelle
Nein, Ihr Code hat eine zeitliche Komplexität von
O(2^|<DeltaTime>|)
,Für eine korrekte Codierung der aktuellen Zeit.
Bitte, lassen Sie mich zuerst für mein Englisch entschuldigen.
Was ist und wie funktioniert Big O in CS?
Die Big O-Notation wird nicht verwendet, um die Eingabe eines Programms mit seiner Laufzeit zu verknüpfen .
Die Big-O-Notation ist eine Möglichkeit, das asymptotische Verhältnis zweier Größen auszudrücken .
Bei der Algorithmusanalyse sind diese beiden Größen nicht die Eingabe (für die man zuerst eine "Mess" -Funktion haben muss) und die Laufzeit.
Sie sind die Länge der Codierung einer Instanz des Problems 1 und eine interessierende Metrik.
Die am häufigsten verwendeten Metriken sind
Implizit ist eine TM als Modell angenommen , so dass der erste Punkt zur übersetzten Anzahl von Anwendungen der Übergang 2 - Funktion , dh „Stufen“, und die zweiter übersetzt die Anzahl der verschiedenen Band Zellen mindestens einmal geschrieben .
Wird auch oft implizit angenommen, dass wir anstelle der ursprünglichen Codierung eine polynomiell verwandte Codierung verwenden können, beispielsweise ist eine Funktion, die ein Array von Anfang bis Ende durchsucht,
O(n)
komplex, obwohl eine Codierung einer Instanz eines solchen Arrays eine Länge von haben sollten*b+(n-1)
wob
ist die (konstante) Anzahl von Symbolen jedes Elements. Dies liegt daran,b
dass eine Konstante des Berechnungsmodells und damit der Ausdruck über und betrachtet wirdn
asymptotisch gleich ist.Dies erklärt auch, warum ein Algorithmus wie die Trial Division ein exponentieller Algorithmus ist, obwohl er im Wesentlichen ein
for(i=2; i<=sqr(N); i++)
ähnlicher Algorithmus 3 ist .Sehen Sie das .
Dies bedeutet auch, dass die Big-O-Notation möglicherweise so viele Parameter verwendet, wie zur Beschreibung des Problems erforderlich sind. Ist es nicht ungewöhnlich, dass für einige Algorithmen ein k- Parameter vorhanden ist?
Es geht also nicht um die "Eingabe" oder "es gibt keine Eingabe".
Studienfall jetzt
Die Big O-Notation stellt Ihren Algorithmus nicht in Frage, sondern setzt lediglich voraus, dass Sie wissen, was Sie tun. Es ist im Wesentlichen ein Werkzeug, das überall anwendbar ist, selbst für Algorithmen, die absichtlich schwierig sein können (wie bei Ihnen).
Um Ihr Problem zu lösen, haben Sie das aktuelle und ein zukünftiges Datum verwendet. Sie müssen also irgendwie Teil des Problems sein. Einfach ausgedrückt: Sie sind Teil der Instanz des Problems.
Insbesondere lautet die Instanz:
<DeltaTime>
Wo das
<>
bedeutet, eine nicht pathologische Kodierung der Wahl.Siehe unten für sehr wichtige Erläuterungen.
Ihre große O-Komplexitätszeit ist also nur
O(2^|<DeltaTime>|)
deshalb so , weil Sie eine Reihe von Iterationen durchführen, die vom Wert der aktuellen Zeit abhängen. Es macht keinen Sinn, andere numerische Konstanten zu setzen, da die asymptotische Notation nützlich ist, da sie Konstanten eliminiert (so ist beispielsweise die Verwendung vonO(10^|<DeltaTime>|*any_time_unit)
sinnlos).Wo der schwierige Teil ist
Wir haben oben eine wichtige Annahme getroffen: dass das Berechnungsmodell 5- mal reifiziert , und mit Zeit meine ich die (reale?) Physikalische Zeit. Es gibt kein solches Konzept im Standard-Rechenmodell, ein TM kennt die Zeit nicht, wir verknüpfen die Zeit mit der Anzahl der Schritte, weil unsere Realität so funktioniert 4 .
In Ihrem Modell können Sie jedoch die Terminologie funktionaler Personen verwenden, indem Sie sagen, dass Main nicht rein ist, das Konzept jedoch dasselbe.
Um dies zu verstehen, sollte man beachten, dass nichts das Framework daran hindert, eine gefälschte Zeit zu verwenden, die zweimal, fünf, zehnmal schneller als die physische Zeit läuft. Auf diese Weise wird Ihr Code in "der Hälfte", "einem Fünftel", "einem Zehntel" der "Zeit" ausgeführt.
Diese Reflexion ist wichtig für die Auswahl der Codierung von
<DeltaTime>
. Dies ist im Wesentlichen eine komprimierte Schreibweise <(CurrentTime, TimeInFuture)>. Da im Priorat keine Zeit vorhanden ist, könnte die Codierung von CurrentTime sehr gut das Wort Now (oder eine andere Wahl) am Vortag sein, das als Yesterday codiert werden könnte , indem die Annahme gebrochen wird, dass die Länge der Codierung zunimmt mit der physischen Zeit geht vorwärts (und der von DeltaTime nimmt ab)Wir müssen die Zeit in unserem Rechenmodell richtig modellieren, um etwas Nützliches zu tun.
Die einzig sichere Wahl, die wir treffen können, besteht darin, Zeitstempel mit zunehmender Länge zu codieren (aber immer noch nicht unär zu verwenden), wenn die physische Zeit voranschreitet. Dies ist die einzig wahre Eigenschaft der Zeit, die wir brauchen, und diejenige, die die Codierung abfangen muss. Nur mit dieser Art der Codierung kann Ihr Algorithmus eine zeitliche Komplexität erhalten.
Ihre Verwirrung, falls vorhanden, ergibt sich aus der Tatsache, dass das Wort Zeit in den Sätzen "Was ist seine zeitliche Komplexität?" und 'Wie viel Zeit wird es dauern?' bedeutet zu sehr sehr unterschiedlichen Dingen
Leider verwendet die Terminologie dieselben Wörter, aber Sie können versuchen, "Schrittkomplexität" in Ihrem Kopf zu verwenden und sich Ihre Frage erneut zu stellen. Ich hoffe, das hilft Ihnen zu verstehen, dass die Antwort wirklich ^ _ ^ lautet
1 Dies erklärt auch die Notwendigkeit eines asymptotischen Ansatzes, da jede Instanz eine andere, jedoch nicht willkürliche Länge hat.
2 Ich hoffe, ich verwende hier den richtigen englischen Begriff.
3 Auch deshalb finden wir häufig
log(log(n))
Begriffe in der Mathematik.4 Im besten Fall muss ein Schritt ein endliches, aber nicht nulles oder nicht verbundenes Zeitintervall einnehmen.
5 Dies bedeutet, dass der Rechenmodus als Kenntnis der physikalischen Zeit darin, dh mit seinen Begriffen ausgedrückt werden kann. Eine Analogie ist die Funktionsweise von Generika im .NET Framework.
quelle
O(2^n)
? Für Anfänger ist das nicht klar.DeltaTime
anstelle des Werts zu messen . Zum Beispiel, aber diese Argumentation, kein optimaler Sortieralgorithmus hat Zeitkomplexität $ O (n \ cdot log n) $. Warum? Da Sie entweder nur endlich viele unterscheidbare Objekte sortieren müssen, können Sie in diesem Fall immer die Bucket-Sortierung verwenden, um $ O (n) $ zu sortieren. Oder Ihre Objektgröße ist unbegrenzt. In diesem Fall gilt $ O (n \ cdot log n) $ nicht, da ein einzelner Vergleich keine konstante Zeit mehr hat ...Obwohl es hier eine Reihe großartiger Antworten gibt, möchte ich sie alle ein wenig umformulieren.
Es gibt eine Big-O-Notation zur Beschreibung von Funktionen . Bei der Analyse von Algorithmen müssen wir zunächst einige Merkmale dieses Algorithmus in Bezug auf eine Funktion definieren . Die übliche Wahl besteht darin, die Anzahl der Schritte als Funktion der Eingabegröße zu berücksichtigen . Wie in anderen Antworten erwähnt, erscheint es seltsam, in Ihrem Fall eine solche Funktion zu entwickeln, da es keine klar definierte "Eingabe" gibt. Wir können es trotzdem versuchen:
TwentyYearsLater
als "Eingabegröße" -ähnlichen Parameter von Interesse betrachten. In diesem Fall ist die Laufzeit f (n) = (nx), wobei x die "Jetzt-Zeit" zum Zeitpunkt des Aufrufs ist. So gesehen handelt es sich um einen O (n) -Zeitalgorithmus. Erwarten Sie dieses Gegenargument, wenn Sie anderen Ihren technischen O (1) -Algorithmus zeigen .TwentyYearsLater
die Eingabe ist, dann ist seine Größe n tatsächlich die Anzahl der Bits, die benötigt werden, um sie darzustellen, dh n = log (k) . Die Abhängigkeit zwischen der Größe der Eingabe n und der Laufzeit beträgt daher f (n) = 2 ^ n - x . Ihr Algorithmus scheint gerade exponentiell langsam geworden zu sein! Pfui.DateTime.Now
Aufrufe in der Schleife gibt. Wir können uns tatsächlich vorstellen, dass diese gesamte Sequenz zum Zeitpunkt der Ausführung des Programms als Eingabe bereitgestellt wird. Es kann dann davon ausgegangen werden, dass die Laufzeit von der Eigenschaft dieser Sequenz abhängt - nämlich von ihrer Länge bis zum erstenTwentyYearsLater
Element. In diesem Fall ist die Laufzeit wieder f (n) = n und der Algorithmus ist O (n) .Andererseits haben Sie in Ihrer Frage nicht einmal gesagt, dass Sie an Laufzeit interessiert sind. Was wäre, wenn Sie die Speichernutzung meinen würden? Abhängig davon, wie Sie die Situation modellieren, können Sie sagen, dass der Algorithmus O (1) -Speicher oder möglicherweise O (n) -Speicher ist (wenn die Implementierung von
DateTime.Now
erfordert, dass die gesamte Aufrufsequenz irgendwo verfolgt wird).Und wenn Ihr Ziel darin bestand, etwas Absurdes zu finden, warum gehen Sie nicht all-in und sagen, dass Sie daran interessiert sind, wie die Größe des Algorithmuscodes in Pixel auf dem Bildschirm von der gewählten Zoomstufe abhängt. Dies könnte so etwas wie f (Zoom) = 1 / Zoom sein und Sie können stolz Ihren Algorithmus als O (1 / n) Pixel groß deklarieren!
quelle
DateTime.Now
Aufrufe gibt", ist hier die eigentliche Eingabe. Aber ich denke, die Schlussfolgerung sollte nicht sein, dass es O (n) ist, sondern O (k), wobei k die Länge ist bis zum erstenTwentyYearsLater
Element.Ich muss Servy etwas widersprechen. Es gibt eine Eingabe für dieses Programm, auch wenn es nicht offensichtlich ist, und das ist die Zeit des Systems. Dies könnte eine Technik sein, die Sie nicht beabsichtigt hatten, aber Ihre
TwentyYearsFromNow
Variable ist nicht zwanzig Jahre von der Zeit des Systems entfernt , sondern statisch dem 1. Januar 2035 zugeordnet.Wenn Sie diesen Code auf einem Computer mit einer Systemzeit vom 1. Januar 1970 ausführen, dauert die Fertigstellung 65 Jahre, unabhängig davon, wie schnell der Computer ist (bei fehlerhafter Uhr kann es zu Abweichungen kommen ). Wenn Sie diesen Code auf einem Computer mit einer Systemzeit vom 2. Januar 2035 ausführen, wird er fast sofort abgeschlossen.
Ich würde sagen, Ihre Eingabe
n
istJanuary 1st, 2035 - DateTime.Now
und es ist O (n).Dann gibt es noch das Problem der Anzahl der Operationen. Einige Leute haben bemerkt, dass schnellere Computer schneller in die Schleife kommen und mehr Operationen verursachen, aber das ist irrelevant. Bei der Arbeit mit Big-O-Notation berücksichtigen wir weder die Geschwindigkeit des Prozessors noch die genaue Anzahl der Vorgänge. Wenn Sie diesen Algorithmus verwenden und ihn auf einem Computer ausführen und dann erneut ausführen, jedoch 10x länger auf demselben Computer, würden Sie erwarten, dass die Anzahl der Vorgänge um den gleichen Faktor von 10x zunimmt.
Was das betrifft:
Nein nicht wirklich. Andere Antworten haben dies behandelt, deshalb wollte ich es nur erwähnen. Sie können jahrelange Ausführung im Allgemeinen nicht mit einer Big-O-Notation korrelieren. Z.B. Es gibt keine Möglichkeit, 20 Jahre Hinrichtung = O (n ^ 87) oder irgendetwas anderes zu sagen. Selbst in dem von Ihnen angegebenen Algorithmus könnte ich das
TwentyYearsFromNow
auf das Jahr 20110, 75699436 oder 123456789 ändern, und das große O ist immer noch O (n).quelle
When working with big-O notation, we don't consider the speed of the processor or the exact number of operations.
Dies ist eine falsche Aussage. So ziemlich jeder vernünftiger Betrieb , dass Sie versuchen würden , den Big O Wert zu berechnen , wird nicht die Anzahl der Operationen ändern durchgeführt , basierend auf der Hardware, aber dies tut . Big O ist nur eine Möglichkeit, die Anzahl der Operationen mit der Größe der Eingabe in Beziehung zu setzen. Für die meisten Vorgänge unabhängig von der Systemhardware. In diesem Fall ist es nicht .If you took this algorithm and ran it on a computer, and then ran it again but for 10x longer on the same computer, you would expect the number of operations to grow by the same factor of 10x.
Das ist auch eine falsche Aussage. Die Umgebung ändert die Anzahl der Operationen in der Schleife nicht unbedingt linear. Es könnten beispielsweise andere Programme auf dem Computer vorhanden sein, die zu unterschiedlichen Zeitpunkten mehr oder weniger CPU-Zeit verbrauchen und die dieser Anwendung im Laufe der Zeit ständig zugewiesene Zeit ändern.Die Big-O-Analyse befasst sich mit dem Verarbeitungsaufwand, da die verarbeitete Datenmenge unbegrenzt zunimmt.
Hier handelt es sich wirklich nur um ein einzelnes Objekt fester Größe. Daher hängt die Anwendung der Big-O-Analyse stark (hauptsächlich?) Davon ab, wie Sie Ihre Begriffe definieren.
Zum Beispiel könnten Sie bedeuten, die Ausgabe im Allgemeinen zu drucken und so lange zu warten, bis eine angemessene Datenmenge in genau demselben Zeitraum gedruckt wird / wird. Sie müssen auch etwas mehr ungewöhnliche (wenn nicht völlig falsche) Definitionen hinzufügen, um sehr weit zu kommen - insbesondere bei Big-O-Analysen ist dies normalerweise der Fall anhand der Anzahl der grundlegenden Operationen definiert, die zur Durchführung von a erforderlich sind bestimmte Aufgabe (beachten Sie jedoch, dass Komplexität auch in Bezug auf die Speichernutzung und nicht nur die CPU-Auslastung / ausgeführte Operationen berücksichtigt werden kann).
Die Anzahl der grundlegenden Operationen entspricht jedoch in der Regel ziemlich genau der Zeit, die benötigt wird. Daher ist es keine große Herausforderung, die beiden als synonym zu behandeln. Leider bleiben wir jedoch bei diesem anderen Teil: Die Menge der verarbeiteten Daten nimmt unbegrenzt zu. In diesem Fall funktioniert keine feste Verzögerung, die Sie auferlegen können, wirklich. Um O (1) mit O (N) gleichzusetzen, müssten Sie eine unendliche Verzögerung festlegen, damit das Drucken einer festen Datenmenge ewig dauerte, genau wie eine unendliche Datenmenge.
quelle
Big-O relativ zu was?
Sie scheinen zu verstehen, dass dies
twentyYearsLater
eine "Eingabe" ist. Wenn Sie tatsächlich Ihre Funktion als geschrieben habenEs wäre O (N), wo N = Jahre (oder einfach sagen)
O(years)
).Ich würde sagen, Ihr Algorithmus ist O (N) relativ zu der Zahl, mit der Sie in die Codezeile schreiben, beginnend mit
twentyYearsLater =
. Normalerweise betrachten die Leute Zahlen im eigentlichen Quellcode jedoch nicht als Eingabe. Sie betrachten möglicherweise die Befehlszeileneingabe als Eingabe oder die Funktionssignatureingabe als Eingabe, höchstwahrscheinlich jedoch nicht den Quellcode selbst. Das ist es, was Sie mit Ihrem Freund bestreiten - ist dies der "Input"? Sie richten Ihren Code so ein, dass er intuitiv wie eine Eingabe erscheint, und Sie können definitiv die große O-Laufzeit in Bezug auf die Nummer N in Zeile 6 Ihres Programms erfragen, aber wenn Sie eine solche nicht standardmäßige Auswahl verwenden Als Eingabe müssen Sie wirklich explizit darüber sein.Wenn Sie jedoch die Eingabe als etwas Üblicheres betrachten, wie die Befehlszeile oder die Eingabe für die Funktion, gibt es überhaupt keine Ausgabe und die Funktion ist O (1). Es dauert zwanzig Jahre, aber da sich big-O nicht bis zu einem konstanten Vielfachen ändert, ist O (1) = O (zwanzig Jahre).
Ähnliche Frage - was ist die Laufzeit von:
Angenommen, es tut, was es sagt, und die Eingabe ist gültig, und der Algorithmus nutzt eine Quicksort- oder Blasensortierung oder irgendetwas Vernünftiges, dann ist es O (1).
quelle
Dieser "Algorithmus" wird korrekt als O (1) oder konstante Zeit beschrieben. Es wurde argumentiert, dass es keinen Input für dieses Programm gibt, daher gibt es kein N, das in Bezug auf Big Oh analysiert werden muss. Ich bin nicht der Meinung, dass es keine Eingabe gibt. Wenn dies in eine ausführbare Datei kompiliert und aufgerufen wird, kann der Benutzer jede Eingabe beliebiger Länge angeben. Diese Eingangslänge ist die N.
Das Programm ignoriert nur die Eingabe (unabhängig von der Länge), sodass die benötigte Zeit (oder die Anzahl der ausgeführten Maschinenbefehle) unabhängig von der Länge der Eingabe (bei fester Umgebung = Startzeit + Hardware) gleich ist, daher O (1) ).
quelle
Let's suppose that there is a finite lower bound on the amount of time a loop iteration takes
Das ist eine falsche Annahme. Das Programm kann für immer laufen. Alles, was ich tun muss, ist, meine Systemuhr auf 50 Jahre einzustellen, sie zu starten und sie wird niemals beendet. Oder ich könnte die Uhr schneller zurückbewegen als vorwärts oder an einem unbestimmten Punkt in der Vergangenheit starten . Sie können einfach nicht davon ausgehen, dass es eine Untergrenze für die Laufzeit des Programms gibt. es kann für immer laufen. Aber selbst wenn wir Ihre (falsche) Annahme als wahr annehmen, können Sie die Anzahl der ausgeführten Operationen nicht mit der Eingabe in Beziehung setzen.Eine Sache, die mich überrascht, wurde noch nicht erwähnt: Die Big-O-Notation ist eine Obergrenze!
Das Problem, das jeder bemerkt hat, ist, dass es kein N gibt, das die Eingaben in den Algorithmus beschreibt, so dass es nichts gibt, mit dem man eine Big-O-Analyse durchführen kann. Dies lässt sich jedoch leicht durch einige grundlegende Tricks abmildern, z. B. das Akzeptieren
int n
und Drucken von "Hello World"n
-Zeiten. Das würde diese Beschwerde umgehen und auf die eigentliche Frage zurückkommen, wie dieseDateTime
Monstrosität funktioniert.Es gibt keine tatsächliche Garantie dafür, dass die while-Schleife jemals beendet wird. Wir denken gerne, dass es irgendwann sein muss, aber denken Sie daran , dass
DateTime.now
das System Datum und Uhrzeit zurückgibt . Es gibt eigentlich keine Garantie dafür, dass dies monoton zunimmt. Es ist möglich, dass ein pathologisch ausgebildeter Affe das Datum und die Uhrzeit des Systems ständig auf den 21. Oktober 2015 um 12:00:00 UTC ändert, bis jemand dem Affen einige automatisch passende Schuhe und ein Hoverboard gibt. Diese Schleife kann tatsächlich unendlich lange laufen!Wenn Sie sich tatsächlich mit der mathematischen Definition von Big-O-Notationen befassen, handelt es sich um Obergrenzen. Sie zeigen das Worst-Case-Szenario, egal wie unwahrscheinlich. Das Worst-Case * -Szenario hier ist eine unendliche Laufzeit, daher müssen wir deklarieren, dass es keine Big-O-Notation gibt, um die Laufzeitkomplexität dieses Algorithmus zu beschreiben. Es existiert nicht, genauso wie 1/0 nicht existiert.
* Bearbeiten: Aus meiner Diskussion mit KT geht nicht immer hervor, dass das Szenario, das wir mit Big-O-Notation modellieren, der schlimmste Fall ist. In den meisten Fällen wollte eine Person, wenn sie nicht angibt, welchen Fall wir verwenden, den schlimmsten Fall untersuchen. Sie können jedoch eine Big-O-Komplexitätsanalyse zur besten Laufzeit durchführen.
quelle
f
und die Funktiong
als dieselbe zu deklarierenf
, aber mit einer eingeschränkten Domain, die nur denf
besten Fall enthält, und dann Big-Oh-On ausführeng
, aber es beginnt zu degenerieren, wenn Sie dies tun Das.Die Komplexität wird verwendet, um die rechnerische "Leistung" in Bezug auf Zeit / Raum zu messen. Die Big O-Notation wird verwendet, um zu vergleichen, welche Probleme "berechenbar" oder "nicht berechenbar" sind, und um zu vergleichen, welche Lösungen - Algorithmen - besser sind als andere. Daher können Sie jeden Algorithmus in zwei Kategorien einteilen: diejenigen, die in Polynomzeit gelöst werden können, und diejenigen, die dies nicht können.
Probleme wie das Sieb von Erathostene sind O (n ^ exp) und daher für kleine Werte von n lösbar. Sie sind berechenbar, nur nicht in der Polynomzeit (NP). Wenn Sie also gefragt werden, ob eine bestimmte Zahl eine Primzahl ist oder nicht, hängt die Antwort von der Größe dieser Zahl ab. Darüber hinaus hängt die Komplexität nicht von der Hardware ab, sodass schnellere Computer nichts ändern ...
Hello World ist kein Algorithmus und daher sinnlos zu versuchen, seine Komplexität zu bestimmen - was keiner ist. Ein einfacher Algorithmus kann ungefähr so aussehen: Bestimmen Sie anhand einer Zufallszahl, ob er gerade oder ungerade ist. Ist es nun wichtig, dass die angegebene Nummer 500 Stellen hat? Nein, weil Sie nur prüfen müssen, ob die letzte Ziffer gerade oder ungerade ist. Ein komplexerer Algorithmus wäre zu bestimmen, ob eine bestimmte Zahl gleichmäßig durch 3 geteilt wird. Obwohl einige Zahlen "einfach" zu berechnen sind, sind andere "schwer" und dies liegt an ihrer Größe: Vergleichen Sie die Zeit, die zur Bestimmung der Remaninder zwischen benötigt wird eine Zahl mit einer Ziffer und eine andere mit 500 Ziffern.
Ein komplexerer Fall wäre das Dekodieren eines Textes. Sie haben eine scheinbar zufällige Anordnung von Symbolen, von denen Sie auch wissen, dass sie eine Nachricht für diejenigen übermitteln, die den Entschlüsselungsschlüssel haben. Angenommen, der Absender hat den Schlüssel links verwendet und Ihre Hello World würde lauten: Gwkki Qieks. Die "Big-Hammer, No-Brain" -Lösung würde alle Kombinationen für diese Buchstaben erzeugen: von Aaaa bis Zzzz und dann ein Wortwörterbuch durchsuchen, um zu identifizieren, welche Wörter gültig sind, und die beiden gemeinsamen Buchstaben in der Chiffre (i, k) in teilen die gleiche Position. Diese Transformationsfunktion misst Big O!
quelle
Den meisten Menschen scheinen zwei sehr wichtige Dinge zu fehlen.
Das Programm hat einen Eingang. Dies ist das fest codierte Datum / die fest codierte Uhrzeit, mit der die Systemzeit verglichen wird. Die Eingaben werden von der Person gesteuert, die den Algorithmus ausführt, die Systemzeit jedoch nicht. Die Person, die dieses Programm ausführt, kann nur das Datum und die Uhrzeit steuern, die sie im Vergleich fest codiert hat.
Das Programm hängt von der Grundlage des eingegebenen Wert , aber nicht die Größe des Eingangssatzes , das ist das, was Big-O - Notation mit betroffen ist .
Daher ist es unbestimmt, und die beste 'Big-O'-Notation für dieses Programm wäre wahrscheinlich O (null) oder möglicherweise O (NaN).
quelle
Jeder hat richtig darauf hingewiesen, dass Sie nicht N definieren , aber die Antwort ist nein unter der vernünftigsten Interpretation. Wenn N die Länge der Zeichenfolge ist, die wir drucken, und "Hallo, Welt!" ist nur ein Beispiel, wie wir aus der Beschreibung dieses Algorithmus als "für
hello, world!
" schließen könnten , dann ist der Algorithmus O ( N ), weil Sie möglicherweise eine Ausgabezeichenfolge haben, deren Druck dreißig, vierzig oder fünfzig Jahre dauert, und Sie füge dem nur eine konstante Zeit hinzu. O ( kN + c ) ≤ O ( N ).Nachtrag:
Zu meiner Überraschung bestreitet dies jemand. Erinnern Sie sich an die Definitionen von big O und big Θ. Angenommen, wir haben einen Algorithmus, der auf eine konstante Zeit c wartet und dann eine Nachricht der Länge N in linearer Zeit druckt . (Dies ist eine Verallgemeinerung des ursprünglichen Codebeispiels.) Nehmen wir willkürlich an, wir warten zwanzig Jahre, um mit dem Drucken zu beginnen, und das Drucken von Billionen Zeichen dauert weitere zwanzig Jahre. Es sei zum Beispiel c = 20 und k = 10¹², aber alle positiven reellen Zahlen reichen aus. Das ist eine Rate von d = c / k (in diesem Fall 2 × 10¹¹) Jahren pro Zeichen, also unsere Ausführungszeit f ( N ) asymptotisch cdN + Jahre. Immer wenn N > k , ist dN = c / k N > c . Daher ist dN < dN + c = f ( N ) <2 dN für alle N > k und f ( N ) ∈ ∈ ( N ). QED
quelle
Ich denke, die Leute werden abgeworfen, weil der Code nicht wie ein traditioneller Algorithmus aussieht . Hier ist eine Übersetzung des Codes, die wohlgeformter ist, aber dem Geist der OP-Frage treu bleibt.
Die Eingaben sind explizit, während sie zuvor implizit zum Zeitpunkt des Starts des Codes und zur Geschwindigkeit der Hardware, auf der der Code ausgeführt wird, angegeben wurden. Der Code ist deterministisch und hat eine genau definierte Ausgabe für bestimmte Eingaben.
Aufgrund der Einschränkungen, die den von uns bereitgestellten Eingaben auferlegt werden, gibt es eine Obergrenze für die Anzahl der Operationen, die ausgeführt werden, sodass dieser Algorithmus tatsächlich O (1) ist.
quelle
Zu diesem Zeitpunkt ja
Dieser Algorithmus hat eine implizite Eingabe, nämlich die Zeit, zu der das Programm gestartet wird. Die Ausführungszeit variiert linear 1, je nachdem, wann sie gestartet wird. Während des Jahres 2035 und danach wird die while-Schleife sofort beendet und das Programm endet nach konstanten Operationen 2 . Man könnte also sagen, dass die Laufzeit
O(max(2035 - start year, 1))
3 ist . Da unser Startjahr jedoch einen Mindestwert hat, wird die Ausführung des Algorithmus nie länger als 20 Jahre dauern (dh einen konstanten Wert).Sie können Ihren Algorithmus besser an Ihre Absicht anpassen, indem Sie 4 definieren
DateTime TwentyYearsLater = DateTime.Now + new TimeSpan(365*20,0,0,0);
1 Dies gilt für das technischere Gefühl der Ausführungszeit, gemessen als Anzahl der Operationen, da es eine maximale Anzahl von Operationen pro Zeiteinheit gibt.
2 Angenommen, das Abrufen
DateTime.Now
ist eine konstante Operation, die sinnvoll ist.3 Ich missbrauche hier die große O-Notation etwas, weil dies eine abnehmende Funktion in Bezug auf ist
start year
, aber wir könnten dies leicht korrigieren, indem wir sie in Bezug auf ausdrückenyears prior to 2035
.4 Dann hängt der Algorithmus nicht mehr von der impliziten Eingabe der Startzeit ab, aber das hat keine Konsequenz.
quelle
Ich würde argumentieren, dass dies O (n) ist. Verwenden von http://www.cforcoding.com/2009/07/plain-english-explanation-of-big-o.html als Referenz.
und
Für Ihr Beispiel
gegeben die Eingabe von n = 20 (mit Einheiten Jahre).
Der Algorithmus ist eine mathematische Funktion f (). Dabei wartet f () n Jahre lang mit dazwischen liegenden 'Debug'-Zeichenfolgen. Der Skalierungsfaktor ist 1. f () kann durch Ändern dieses Skalierungsfaktors verringert / oder erhöht werden.
In diesem Fall beträgt der Ausgang ebenfalls 20 (durch Ändern des Eingangs wird der Ausgang linear geändert).
im wesentlichen ist die Funktion
quelle