Was bedeutet ein schnellerer Algorithmus in der theoretischen Informatik?

18

Wenn für ein Problem A ein Algorithmus zur Zeit wird und jemand einen Algorithmus zur Zeit , wobei , wird dies als Verbesserung gegenüber dem vorherigen Algorithmus angesehen?O ( f ( n ) / g ( n ) ) g ( n ) = o ( f ( n ) )O(f(n))O(f(n)/g(n))g(n)=o(f(n))

Ist es im Kontext der theoretischen Informatik sinnvoll, einen solchen Algorithmus zu entwickeln?

Liebes
quelle
4
Mit "schnellerer Algorithmus" meinen wir "asymptotisch schnellerer Algorithmus".
Yuval Filmus
@YuvalFilmus was meinst du mit "asymptotisch"
undefined
1
Laufen in der Zeit . o(f(n))
Yuval Filmus

Antworten:

26

Nein, ein Algorithmus, der zur Zeit O (f (n) / g (n)) läuft O(f(n)/g(n)), wobei g(n)=o(f(n)) , wird nicht notwendigerweise als Verbesserung angesehen. Angenommen, f(n)=n und g(n)=1/n . Dann ist O(f(n)/g(n))=O(n2) eine schlechtere gebundene Zeit als O(f(n))=O(n) .

Um einen Algorithmus zu verbessern, der in der Zeit f(n) abläuft, müssen Sie einen Algorithmus entwickeln, der in der Zeit o(f(n)) abläuft, dh in der Zeit g(n) für einige Funktionen g(n)=o(f(n)) .

Wenn Sie nur wissen, dass ein Algorithmus in der Zeit abläuft , ist nicht klar, ob ein in der Zeit ablaufender Algorithmus eine Verbesserung darstellt, unabhängig davon, ob sind. Dies liegt daran, dass Big O nur eine Obergrenze für die Laufzeit ist. Stattdessen ist es üblich, die Zeitkomplexität im ungünstigsten Fall zu betrachten und sie als ein großes und nicht nur als ein großes zu schätzen .O ( g ( n ) ) f ( n ) , g ( n ) OO(f(n))O(g(n))f(n),g(n)ΘO

Yuval Filmus
quelle
21
Es könnte besser sein, in Ihrem ersten Absatz zu nehmen . Das Verwenden einer abnehmenden Funktion fühlt sich ein wenig betrügerisch an. g(n)=1
David Richerby
1
@DavidRicherby: Vielleicht ein bisschen, aber OP hat nie gesagt, dass ein Algorithmus in sodass keine Monotonie angenommen werden kann. O(g(n))
Kevin
7
@ Kevin Sicher, aber der Kontext ist die Informatik, und in der Informatik wird die Big-O-Notation normalerweise für nicht abnehmende Funktionen verwendet. Wahrscheinlich dachte der Fragesteller in diesen Begriffen.
David Richerby
11

Denken Sie daran, dass mit der Notation analysiert werden soll, wie die Aufgabe für verschiedene Eingabegrößen wächst, und dass insbesondere multiplikative Faktoren, Terme niedrigerer Ordnung und Konstanten weggelassen werden.O(...)

Angenommen, Sie haben einen -Algorithmus mit einer tatsächlichen Laufzeit von (vorausgesetzt, Sie können die Anweisungen tatsächlich zählen und kennen die genauen Zeitpunkte usw., was in modernen Systemen zugegebenermaßen eine große Annahme ist). Angenommen, Sie haben einen neuen Algorithmus entwickelt, der zufällig lautet, dessen tatsächliche Laufzeit jedoch beträgt . Angenommen, Sie wissen, dass die Software, die diesen Algorithmus verwendet, niemals eine Problemgröße von .1 n 2 + 2 n + 1 O ( n ) 1000 n + 5000 n > 10O(n2)1n2+2n+1O(n)1000n+5000n>10

Also, welchen würdest du wählen - den -Algorithmus, der 15000 Zeiteinheiten benötigt, oder den -Algorithmus , der nur 121 Einheiten benötigt? Nun, wenn Ihre Software zur Behandlung von Problemgrößen von , welche würden Sie wählen? Was würden Sie tun, wenn Ihre Problemgröße stark variiert?O ( n 2 ) n > 100000O(n)O(n2)n>100000

Twalberg
quelle
2
"sehen Sie nie eine Problemgröße von n> 10" - dann würden wir die O-Notation überhaupt nicht verwenden, würden wir ...
AnoE
5
@AnoE Einfache Zahlen zum Zwecke der Argumentation. Die gleiche Logik gilt, ob Sie für eine Problemgröße von 10 vs 1e5 oder für 1e6 vs 1e9 analysieren.
Twalberg
1
@AnoE Die meisten Computerprogramme versuchen nicht, eine unendlich wachsende Problemgröße zu bewältigen. Es wird also einen Kompromiss geben. Deshalb ist big-O für theoretische Informatik und die Konzepte können angewendet werden , um aktuelle Programme zu verbessern.
mbomb007
Genau, @ mbomb007. Der Fragentitel lautet "Was bedeutet ein schnellerer Algorithmus in der theoretischen Informatik?" und er hat dies im Körper: "Macht es Sinn, im Kontext der theoretischen Informatik ...".
AnoE
@AnoE Erfahrungsgemäß wird die O-Notation immer dann verwendet, wenn n <10 ist! Nicht, dass es eine gute Idee wäre ... aber es ist absolut etwas, was getan wird!
Cort Ammon - Reinstate Monica
5

Im Allgemeinen bedeutet dies, dass für jede Größe von Eingaben, die groß genug ist, die Worst-Case-Laufzeit des alten Algorithmus langsamer ist als die der neuen. Dies entspricht dem Formalismus , wobei g die Zeitkomplexität des neuen Algorithmus und f die Zeitkomplexität des alten Algorithmus ist .g(n)o(f(n))gf

Manchmal kümmern sich Informatiker jedoch um die durchschnittliche Leistung. Das klassische Beispiel ist Quicksort: Die Laufzeit im schlechtesten Fall ist während wir andere kennen, die in -Zeit ausgeführt werden. In der Praxis ist sie jedoch aufgrund ihrer guten durchschnittlichen Laufzeit weit verbreitet . Es kann außerdem optimiert werden, um in den Fällen, die in der freien Natur am häufigsten auftreten, wie z. B. Arrays, die meist in der richtigen Reihenfolge vorliegen, sehr schnell zu arbeiten.Θ(n2)Θ(nlogn)

Und manchmal verwenden sogar theoretische Informatiker „schneller“ als normale Menschen. Beispielsweise verfügen die meisten Implementierungen von String-Klassen über eine Short String-Optimierung (auch als Small String-Optimierung bezeichnet), obwohl dies nur für kurze Zeichenfolgen eine Beschleunigung und für längere Zeichenfolgen einen reinen Overhead bedeutet. Wenn die Eingabegröße immer größer wird, wird die Laufzeit einer String-Operation mit SSO um einen kleinen konstanten Term länger. Gemäß der Definition im ersten Absatz wird SSO durch Entfernen aus einer String-Klasse schneller In der Praxis sind die meisten Zeichenfolgen jedoch klein, sodass SSO die meisten Programme, die sie verwenden, schneller macht, und die meisten Informatikprofessoren wissen es besser, als zu fordern, dass die Leute nur über Ordnungen mit asymptotischer Zeitkomplexität sprechen .

Davislor
quelle
1

Es gibt keine einheitliche Definition für einen "schnelleren Algorithmus". Es gibt keine Kontrollinstanz, die entscheidet, ob ein Algorithmus schneller ist als ein anderer.

Um darauf hinzuweisen, warum dies so ist, möchte ich zwei verschiedene Szenarien anbieten, die dieses düstere Konzept demonstrieren.

Das erste Beispiel ist ein Algorithmus, der eine verknüpfte Liste ungeordneter Daten durchsucht. Wenn ich die gleiche Operation mit einem Array ausführen kann, hat sich an dem großen Oh-Leistungsmaß nichts geändert. Beide Suchen sind O (n). Wenn ich mir nur die großen Oh-Werte anschaue, kann ich sagen, dass ich überhaupt keine Verbesserung erzielt habe. Es ist jedoch bekannt, dass Array-Lookups in den meisten Fällen schneller sind als das Durchlaufen einer verknüpften Liste. Man kann also entscheiden, dass dies einen Algorithmus "schneller" gemacht hat, obwohl sich das große Oh nicht geändert hat.

Wenn ich das traditionelle Beispiel der Programmierung eines Roboters zur Herstellung eines PBJ-Sandwichs verwenden darf, kann ich zeigen, was ich anders meine. Betrachten Sie nur den Punkt, an dem man das Glas Erdnussbutter öffnet.

Pick up the jar
Grab the lid
Unscrew the lid

Gegen

Pick up the jar
Put the jar back down
Pick up the jar
Put the jar back down
Pick up the jar
Put the jar back down
Pick up the jar
Put the jar back down
Pick up the jar
Put the jar back down
Pick up the jar
Grab the lid
Unscrew the lid

Selbst in der akademischsten theoretischen Umgebung, die ich mir vorstellen kann, werden Sie feststellen, dass die Leute akzeptieren, dass der erste Algorithmus schneller ist als der zweite, obwohl die großen Ergebnisse der Oh-Notation gleich sind.

Im Gegensatz dazu können wir einen Algorithmus zum Unterbrechen der RSA-Verschlüsselung in Betracht ziehen. Im Moment wird angenommen, dass dieser Prozess wahrscheinlich O (2 ^ n) ist, wobei n die Anzahl der Bits ist. Stellen Sie sich einen neuen Algorithmus vor, der n ^ 100 schneller läuft. Das bedeutet, mein neuer Prozess läuft in O (2 ^ n / n ^ 100). In der Welt der Kryptographie wird eine polynomielle Beschleunigung zu einem exponentiellen Algorithmus jedoch traditionell überhaupt nicht als theoretische Beschleunigung angesehen. Bei Sicherheitsüberprüfungen wird davon ausgegangen, dass ein Angreifer möglicherweise eine dieser Beschleunigungen feststellt und diese keine Auswirkungen hat.

In einem Fall können wir also ein O (n) in ein O (n) ändern und es schneller aufrufen. Unter anderen Umständen können wir ein O (2 ^ n) in O (2 ^ n / n ^ 100) ändern und behaupten, es gäbe überhaupt keine sinnvolle Beschleunigung. Aus diesem Grund sage ich, dass es keine einheitliche Definition für einen "schnelleren Algorithmus" gibt. Es ist immer kontextabhängig.

Cort Ammon - Setzen Sie Monica wieder ein
quelle
1

A(n)O(f(n))

 0cf< lim supnA(n)f(n)=cf

g(n)lim supng(n)=h(n)=f(n)g(n)

A(n)O(h(n))A(n)O(h(n))

 0ch< lim supnA(n)h(n)=ch

Nach den Regeln der Grenzen können wir auch schreiben:

ch=lim supnA(n)h(n)=lim supnA(n)g(n)f(n)=cflim supng(n)

ch<cf=0

cf0A(n)O(h(n))

A(n)A(n)A(n)Θ(f(n))g(n)

A(n)O(f(n))A(n)A(n)O(h(n))

Jared Goguen
quelle
1
Ihr Limit sollte überlegen sein.
Yuval Filmus
1
@YuvalFilmus Updated
Jared Goguen