Ich bin noch nicht einmal ein CS-Student, also ist das vielleicht eine blöde Frage, aber bitte trage sie mit mir ...
Im Zeitalter vor dem Computer können wir eine Array-Datenstruktur nur mit so etwas wie einem Array von Schubladen implementieren. Da man die Schublade mit dem entsprechenden Index lokalisieren muss, bevor man den Wert daraus extrahiert, ist die zeitliche Komplexität der Array-Suche , unter der Annahme einer binären Suche.
Die Erfindung der Computer machte jedoch einen großen Unterschied. Moderne Computer können so schnell aus ihrem RAM lesen, dass wir die zeitliche Komplexität der Array-Suche als (auch technisch nicht, da es länger dauert, das Register über eine größere Entfernung zu bewegen usw.).
Ein weiteres Beispiel sind Python-Wörterbücher. Während man eine Wörterbuchzugriffskomplexität von mit einer falsch geschriebenen überladenen Magiemethode (oder einem lächerlichen Pech, dh Schlüsseln mit vielen Hash-Kollisionen) erhält , wird normalerweise angenommen, dass es sich um O ( 1 ) handelt . In diesem Fall hängt die zeitliche Komplexität sowohl von der Implementierung der Hash-Tabellen in Python-Wörterbüchern als auch von der Implementierung der Hash-Funktionen durch die Schlüssel ab.__hash__
Bedeutet dies, dass Hardware / Implementierung die zeitliche Komplexität von Algorithmen beeinflussen kann? (Während es in beiden Beispielen um Datenstrukturen statt Algorithmen geht, bauen die letzteren auf den ersteren auf, und ich habe noch nie von der zeitlichen Komplexität von Datenstrukturen gehört, weshalb ich hier den Begriff "Algorithmen" verwende.)
Algorithmen sind für mich abstrakt und konzeptionell. Ihre Eigenschaften wie die Komplexität von Zeit und Raum sollten nicht davon abhängen, ob sie auf eine bestimmte Art und Weise implementiert werden, aber sind sie dies?
Antworten:
Sicher. Bestimmt. Hier erfahren Sie, wie Sie Ihre Beschwerden in Einklang bringen können.
Wenn wir die Laufzeit von Algorithmen analysieren, tun wir dies in Bezug auf ein bestimmtes Rechenmodell . Das Berechnungsmodell gibt Dinge wie die Zeit an, die für die Ausführung jeder Grundoperation benötigt wird (ist eine Array-Lookup- oderO ( logn ) -Zeit?). Die Laufzeit des Algorithmus hängt möglicherweise vom Berechnungsmodell ab.O ( 1 )
Sobald Sie ein Rechenmodell ausgewählt haben, ist die Analyse des Algorithmus eine rein abstrakte, konzeptionelle, mathematische Übung, die nicht mehr von der Hardware abhängt.
In der Praxis möchten wir jedoch in der Regel ein Berechnungsmodell auswählen, das die Realität unserer Hardware widerspiegelt - zumindest zu einem vernünftigen Grad. Wenn sich also die Hardware ändert, können wir uns dazu entschließen, unsere Algorithmen unter einem anderen Berechnungsmodell zu analysieren, das für die neue Hardware besser geeignet ist. So kann die Hardware die Laufzeit beeinflussen.
Der Grund, warum dies nicht offensichtlich ist, liegt darin, dass wir in Einführungskursen häufig nicht über das Rechenmodell sprechen. Wir machen nur implizit einige Annahmen, ohne sie jemals explizit zu machen. Das ist aus pädagogischen Gründen vernünftig, hat aber Kosten - es verbirgt diesen Aspekt der Analyse. Jetzt wissen Sie.
quelle
Ich denke, es gibt ein grundlegendes Missverständnis in der Frage. Sie vergleichen eine Person, die ein Objekt in einer sortierten Liste findet (z. B. eine bestimmte Seite in einem Buch, deren Nummer angegeben ist), mit einem Computer, der ein Objekt aus einem Array nachschlägt.
Ja, die Hardware (dh das Berechnungsmodell) beeinflusst die Laufzeit von Algorithmen, wie DW erklärt , aber auf diesem Beispiel scheint Ihr Array-Zugriff nicht zu basieren.
quelle
O(lg size-of-memory)
, dh sie sind vernachlässigbar - aber genau das hat OP gefragt!Nein, die Hardware hat keinen Einfluss auf die Komplexität der Algorithmen.
Aber wirkt sich jedoch auf die Wahl des Algorithmus aus und kann den Nutzen der Komplexitätsanalyse bis zu einem Punkt beeinträchtigen, an dem die Analyse praktisch bedeutungslos wird (oder lediglich von akademischem Interesse ist).
Das Finden der richtigen Schublade (beim Zugriff auf ein Array-Element) verwendet den Algorithmus "Open Nth Element Direct By Index", nicht den Algorithmus "Linear suchen" oder "Binär suchen". Die Algorithmen werden nicht geändert, sondern die Wahl.
Zum anderen ist die Komplexitätsanalyse selbst bzw. deren Aussagekraft betroffen stark von der Hardware.
Viele Algorithmen, die durch ihre Komplexitätsanalyse herausragend sind, sind schlecht oder in der Praxis sogar unbrauchbar, da der unbedeutende konstante Faktor nicht unbedeutend ist, sondern dominiert .
Oder weil Annahmen, die einst wahr waren (oder größtenteils wahr sind), nicht mehr gelten. So ist zum Beispiel jeder Vorgang meistens derselbe (nur kleine konstante Unterschiede, die keine Rolle spielen), oder es spielt keine Rolle, auf welche Speicherorte Sie in welcher Reihenfolge zugreifen. Aus der Komplexitätsanalyse können Sie schließen, dass ein Algorithmus weit überlegen ist, da er nur so viele Operationen benötigt. In der Praxis kann es vorkommen, dass jede Operation einen garantierten Cache-Fehler (oder noch schlimmer einen Seitenfehler) verursacht, der ein k einführt , das so groß ist, dass es nicht mehr unbedeutend ist, sondern alles dominiert.
Wenn der Algorithmus A 500 Operationen für die Verarbeitung eines Datensatzes einer bestimmten Größe benötigt und der Algorithmus B nur 5, B jedoch 5 Fehler verursacht, die jeweils 20 Millionen Zyklen auslösen, ist A besser, ungeachtet dessen, was die Analyse oder der gesunde Menschenverstand aussagen.
Dies hat vor ein paar Jahren zu lustigen Überraschungen geführt, wie zB beim Cuckoo Hashing. Welches war weit überlegen, weil [lange Liste der Vorteile]. Nachdem sich der Hype abgekühlt hatte, stellte sich heraus, dass er erheblich schlechter war, da er bei jedem Zugriff zwei Cache-Fehlschläge (Fehler bei größeren Datenmengen) garantierte .
Ähnliches gilt für die Identifizierung und Verarbeitung von Teilmengen von Daten. Heutzutage lautet die richtige Lösung häufig: "Mach einfach alles" , dh anstatt herauszufinden, was du zu verarbeiten und zu tun hast, verarbeite den gesamten Datensatz linear, auch wenn du vielleicht nur die Hälfte davon benötigst. Denn ob Sie es glauben oder nicht, das geht schneller, da es keine Verzweigungsfehlervorhersagen, keine Cache-Fehlschläge und keine Seitenfehler gibt.
Müssen Sie die ersten 8 KB und die letzten 3 KB einer 3-MB-Datei lesen? Nun, lesen Sie die komplette Datei und werfen Sie weg, was Sie nicht wollen, denn das Suchen dazwischen ist zehnmal langsamer als das Lesen der kompletten Datei.
Verwenden Sie eine Karte, weil sie logarithmisch komplex ist? Oder eine Hash-Tabelle, die eine konstante Zugriffszeit hat? Constant klingt großartig. Nun, für alles, was weniger als tausend Dinge enthält (abhängig von Hardware, Datengröße und Zugriffsmuster), kann eine lineare Suche genauso gut oder besser sein. Überraschung.
Es sind also nicht die Algorithmen an sich, die betroffen sind, sondern ihre Nützlichkeit und Auswahl.
quelle