web-dev-qa-db-ger.com

Big O, wie komplex ist das Summieren einer Reihe von n Zahlen?

Ich dachte immer an die Komplexität von:

1 + 2 + 3 + ... + n ist O (n) und das Summieren von zwei n zu n Matrizen wäre O (n ^ 2).

Aber heute habe ich aus einem Lehrbuch gelesen, "durch die Formel für die Summe der ersten n ganzen Zahlen, dies ist n (n + 1)/2" und dann: (1/2) n ^ 2 + (1/2) n und damit O (n ^ 2).

Was fehlt mir hier? 

24
user1032613

Die big O-Notation kann verwendet werden, um die Wachstumsrate der Funktion any zu bestimmen.

In diesem Fall spricht das Buch scheinbar nicht von der zeitlichen Komplexität der Wertberechnung, sondern von dem Wert selbst. Und n(n+1)/2 ist O(n^2).

16
svick

Sie verwirren die Komplexität von Laufzeit und die Größe (Komplexität) von Ergebnis .

Die Laufzeit des Summierens nacheinander die erste n fortlaufende Nummer ist in der TatO(n).1

Aber die Komplexität des Ergebnisses, das ist die Größe von "Summe von 1 bis n " = n(n - 1)/2 istO(n ^ 2).


1 Bei beliebig großen Zahlen ist dies jedoch sehr einfach, da das Hinzufügen großer Zahlen länger dauert als das Hinzufügen kleiner Zahlen. Für eine genaue Laufzeitanalyse müssen Sie tatsächlich die Größe des Ergebnisses berücksichtigen. Dies ist jedoch in der Regel weder für die Programmierung noch für die rein theoretische Informatik relevant. In beiden Domänen wird das Summieren von Zahlen normalerweise alsO(1) -Operation betrachtet, sofern dies nicht ausdrücklich von der Domäne anders verlangt wird (d. H. Wenn eine Operation für eine Bignum-Bibliothek implementiert wird).

8
Konrad Rudolph

n (n + 1)/2 ist der schnelle Weg, um eine Folge von N ganzen Zahlen (beginnend mit 1) zu summieren. Ich denke, Sie verwechseln einen Algorithmus mit der Big-Oh-Notation!

Wenn Sie es als Funktion betrachten, dann ist die Komplexität dieser Funktion O (1):

 public int sum_of_first_n_integers (int n) {
 return (n * (n + 1))/2; 
} 

Die naive Implementierung hätte eine große Komplexität von O (n).

public int sum_of_first_n_integers(int n) {
  int sum = 0;
  for (int i = 1; i <= n; i++) {
    sum += n;
  }
  return sum;
}

Selbst wenn man nur jede Zelle einer einzelnen n-mal-n-Matrix betrachtet, ist O (n ^ 2), da die Matrix n ^ 2-Zellen hat.

7
Julius Musseau

Ich vermute also, dass dies tatsächlich ein Verweis auf Cracking the Coding Interview ist, das diesen Absatz über eine StringBuffer -Implementierung enthält:

Bei jeder Verkettung wird eine neue Kopie der Zeichenfolge erstellt, und die beiden Zeichenfolgen werden zeichenweise kopiert. Bei der ersten Iteration müssen wir x Zeichen kopieren. Die zweite Iteration erfordert das Kopieren von 2x - Zeichen. Die dritte Iteration erfordert 3x Und so weiter. Die Gesamtzeit ist also O(x + 2x + ... + nx). Dies reduziert sich auf O(xn²). (Warum ist es nicht O(xnⁿ)? Weil 1 + 2 + ... nn(n+1)/2 oder O(n²) entspricht.)

Aus irgendeinem Grund fand ich das auch beim ersten Durchlesen etwas verwirrend. Das Wichtige ist, dass nn multipliziert, oder mit anderen Worten, dass Passiert und das dominiert. Deshalb ist O(xn²) letztendlich nur O(n²) - das x ist eine Art roter Hering.

4

Es gibt wirklich keine Komplexität eines Problems, sondern eher eine Komplexität eines Algorithmus.

Wenn Sie alle Zahlen durchlaufen, ist die Komplexität in der Tat O(n).

Das ist jedoch nicht der effizienteste Algorithmus. Eine effizientere Methode ist die Anwendung der Formel n*(n+1)/2, die konstant ist und daher die Komplexität O(1) ist.

2
Luchian Grigore

Sie haben eine Formel, die nicht von der Anzahl der hinzugefügten Zahlen abhängt. Es handelt sich also um einen Constant-Time - Algorithmus oder O (1).

Wenn Sie jede Zahl einzeln hinzufügen, ist es tatsächlich O (n). Die Formel ist eine Abkürzung. Es ist ein anderer, effizienterer Algorithmus. Die Abkürzung funktioniert, wenn die Zahlen, die hinzugefügt werden, alle 1 ..n sind. Wenn Sie eine nicht zusammenhängende Folge von Zahlen haben, funktioniert die Abkürzungsformel nicht und Sie müssen zum Einzelalgorithmus zurückkehren.

Nichts davon trifft jedoch auf die Zahlenmatrix zu. Um zwei Matrizen hinzuzufügen, ist es immer noch O (n ^ 2), da Sie n ^ 2 verschiedene Zahlenpaare hinzufügen, um eine Matrix mit n ^ 2 Ergebnissen zu erhalten.

1
Rob Kennedy

Es gibt einen Unterschied zwischen dem Summieren von N beliebigen Zahlen und dem Summieren von N, die alle in einer Reihe liegen. Für 1 + 2 + 3 + 4 + ... + N können Sie die Tatsache ausnutzen, dass sie in Paare mit einer gemeinsamen Summe unterteilt werden können, z. 1 + N = 2+ (N-1) = 3+ (N-2) = ... = N + 1. Also ist das N + 1, N/2 mal. (Wenn es eine ungerade Zahl gibt, ist einer davon ungepaart, aber mit etwas Aufwand können Sie feststellen, dass in diesem Fall dieselbe Formel gilt.)

Das ist jedoch nicht O (N ^ 2). Es ist nur eine Formel, die verwendet N ^ 2, eigentlich O (1). O (N ^ 2) würde (ungefähr) bedeuten, dass die Anzahl der zu berechnenden Schritte für N groß ist wie N ^ 2. In diesem Fall ist die Anzahl der Schritte unabhängig von N gleich.

0
Tim Goodman

die Antwort der Summe der Reihen von n natürlich kann auf zwei Arten gefunden werden. Der erste Weg ist das Hinzufügen aller Zahlen in einer Schleife. In diesem Fall ist der Algorithmus linear und der Code wird so sein

 int sum = 0;
     for (int i = 1; i <= n; i++) {
     sum += n;
   }
 return sum;

es ist analog zu 1 + 2 + 3 + 4 + ...... + n. in diesem Fall wird die Komplexität des Algorithmus als Anzahl von Malen berechnet, zu denen die Additionsoperation durchgeführt wird, die 0 (n) ist.

der zweite Weg, die Antwort auf die Summe der Reihen von n natürlicher Zahl zu finden, ist die ungelöste Formel n * (n + 1)/2. Diese Formel verwendet die Multiplikation anstelle der wiederholten Addition. Die Multiplikationsoperation hat keine lineare Zeitkomplexität. Für die Multiplikation stehen verschiedene Algorithmen zur Verfügung, deren zeitliche Komplexität im Bereich von O (N ^ 1.45) bis O (N ^ 2) liegt. Daher hängt die Komplexität der Zeit von der Architektur des Prozessors ab. Für den Analysezweck wird jedoch die Komplexität der Multiplikation als O (N ^ 2) betrachtet. Wenn also ein zweiter Weg zum Finden der Summe verwendet wird, ist die Zeitkomplexität O (N ^ 2). 

hier ist die Multiplikationsoperation nicht gleich der Additionsoperation. Wenn jemand Kenntnisse im Bereich der Computerorganisation besitzt, kann er leicht die interne Funktionsweise der Multiplikations- und Additionsoperation verstehen. Die Multiplikationsschaltung ist komplexer als die Addierschaltung und benötigt viel mehr Zeit als die Addierschaltung, um das Ergebnis zu berechnen. Die zeitliche Komplexität der Summe der Serien kann also nicht konstant sein.

0
Ashok