Die Komplexität des Algorithmus ist so ausgelegt, dass sie unabhängig von Details auf niedrigeren Ebenen ist. Sie basiert jedoch auf einem zwingenden Modell, z. B. dem Array-Zugriff und dem Ändern eines Knotens in einem Baum. Dies ist in reinen Funktionssprachen nicht der Fall. Die Haskell-Liste benötigt für den Zugriff eine lineare Zeit. Zum Ändern eines Knotens in einem Baum muss eine neue Kopie des Baums erstellt werden.
Sollte es dann eine alternative Modellierung der Algorithmuskomplexität für funktionale Sprachen geben?
ST
Monaden) ändern .Antworten:
Wenn Sie davon ausgehen, dass der -calculus ein gutes Modell für funktionale Programmiersprachen ist, könnte man meinen: Der -calculus hat eine scheinbar einfache Vorstellung von Zeitkomplexität: Zählen Sie einfach die Anzahl der -Reduktionsschritte .λ λ β (λx.M)N→M[N/x]
Aber ist das ein gutes Maß für die Komplexität?
Um diese Frage zu beantworten, sollten wir zunächst klären, was wir unter Komplexitätsmaß verstehen. Eine gute Antwort liefert die These von Slot und van Emde Boas : Jedes gute Komplexitätsmaß sollte eine polynomielle Beziehung zum kanonischen Begriff der Zeitkomplexität haben, der mit Turing-Maschinen definiert wird. Mit anderen Worten, es sollte ein ‚angemessen‘ kodiert sein von Kalkül Bezug auf Turingmaschinen, wie für ein Polynom , ist es der Fall , dass für jeden Term der Größe: reduziert sich auf einen Wert in -Reduktionsschritten genau dann, wenn sich auf einen Wert in reduzierttr(.) λ p M |M| M p(|M|) β tr(M) p(|tr(M)|) Schritte einer Turingmaschine.
Es war lange unklar, ob dies im λ-Kalkül erreicht werden kann. Die Hauptprobleme sind die folgenden.
Die Veröffentlichung " Beta Reduction is Invariant, Indeed " von B. Accattoli und U. Dal Lago klärt das Problem, indem sie eine "vernünftige" Codierung zeigt, die die Komplexitätsklasse P der polynomialen Zeitfunktionen beibehält , wobei von Kürzungen des äußersten linken Randes der Call-by-Name ausgegangen wird . Die wichtigste Erkenntnis ist, dass das exponentielle Aufblasen nur aus „uninteressanten“ Gründen erfolgen kann, die durch richtiges Teilen besiegt werden können. Mit anderen Worten, die Klasse P ist die gleiche, unabhängig davon, ob Sie sie mit Turing-Maschinenschritten oder mit (ganz links) -Reduktionen definieren.β
Ich bin mir nicht sicher, wie die Situation für andere Bewertungsstrategien ist. Mir ist nicht bekannt, dass ein ähnliches Programm für die Raumkomplexität durchgeführt wurde.
quelle
Nein nicht wirklich. Wir zählen immer elementare Operationen in einigen Maschinenmodellen:
Sie haben wahrscheinlich an das gesamte / / Geschäft gedacht. Während es stimmt, dass Sie mit Landau Asymptotics einige Implementierungsdetails abstrahieren können, werden Sie die Auswirkungen des Maschinenmodells nicht los. Algorithmen haben sehr unterschiedliche Laufzeiten, sagen wir TMs und RAMs - auch wenn Sie nur Klassen berücksichtigen!Ω Θ O Θ
Daher hat Ihre Frage eine einfache Antwort: Fixieren Sie ein Maschinenmodell und welche "Operationen" zu zählen sind. Dies gibt Ihnen ein Maß. Wenn Sie möchten, dass die Ergebnisse mit nicht funktionalen Algorithmen vergleichbar sind, sollten Sie Ihre Programme am besten in RAM (für die Algorithmusanalyse) oder TM (für die Komplexitätstheorie) kompilieren und das Ergebnis analysieren. Möglicherweise existieren Übertragungssätze, um diesen Prozess zu vereinfachen.
quelle
O(1)
wenn es wirklich istO(log ab)
Anstatt Ihr Komplexitätsmaß in Bezug auf eine zugrunde liegende abstrakte Maschine zu formulieren, können Sie die Kosten in die Sprachdefinitionen selbst einbeziehen - dies wird als Kostendynamik bezeichnet . Man fügt jeder Bewertungsregel in der Sprache auf kompositorische Weise Kosten hinzu - das heißt, die Kosten einer Operation sind eine Funktion der Kosten ihrer Unterausdrücke. Dieser Ansatz ist für funktionale Sprachen am natürlichsten, kann jedoch für jede genau definierte Programmiersprache verwendet werden (natürlich sind die meisten Programmiersprachen leider nicht genau definiert).
quelle