Alle anderen Antworten sind richtig, ich möchte nur Folgendes ändern. Ich wollte sehen, ob die Reduzierung der Ausführungen der inneren k-Schleife ausreicht, um die tatsächliche Komplexität unten zu reduzieren. O(n⁴).
Also schrieb ich Folgendes:
for (int n = 1; n < 363; ++n) {
int sum = 0;
for(int i = 1; i < n; ++i) {
for(int j = 1; j < i * i; ++j) {
if(j % i == 0) {
for(int k = 0; k < j; ++k) {
sum++;
}
}
}
}
long cubic = (long) Math.pow(n, 3);
long hypCubic = (long) Math.pow(n, 4);
double relative = (double) (sum / (double) hypCubic);
System.out.println("n = " + n + ": iterations = " + sum +
", n³ = " + cubic + ", n⁴ = " + hypCubic + ", rel = " + relative);
}
Nachdem dies ausgeführt wurde, wird klar, dass die Komplexität tatsächlich ist n⁴
. Die letzten Ausgabezeilen sehen folgendermaßen aus:
n = 356: iterations = 1989000035, n³ = 45118016, n⁴ = 16062013696, rel = 0.12383254507467704
n = 357: iterations = 2011495675, n³ = 45499293, n⁴ = 16243247601, rel = 0.12383580700180696
n = 358: iterations = 2034181597, n³ = 45882712, n⁴ = 16426010896, rel = 0.12383905075183874
n = 359: iterations = 2057058871, n³ = 46268279, n⁴ = 16610312161, rel = 0.12384227647628734
n = 360: iterations = 2080128570, n³ = 46656000, n⁴ = 16796160000, rel = 0.12384548432498857
n = 361: iterations = 2103391770, n³ = 47045881, n⁴ = 16983563041, rel = 0.12384867444612208
n = 362: iterations = 2126849550, n³ = 47437928, n⁴ = 17172529936, rel = 0.1238518469862343
Dies zeigt, dass der tatsächliche relative Unterschied zwischen dem tatsächlichen n⁴
und der Komplexität dieses Codesegments ein Faktor ist, der asymptotisch gegenüber einem Wert um 0.124...
(tatsächlich 0,125) ist. Obwohl es uns nicht den genauen Wert gibt, können wir Folgendes ableiten:
Zeitkomplexität ist, n⁴/8 ~ f(n)
wo f
Ihre Funktion / Methode ist.
- Die Wikipedia-Seite zur Big O-Notation gibt in den Tabellen der 'Familie der Bachmann-Landau-Notationen' an, dass die
~
Definition der Grenze der beiden Operandenseiten gleich ist. Oder:
f ist asymptotisch gleich g
(Ich habe 363 als ausgeschlossene Obergrenze gewählt, da dies n = 362
der letzte Wert ist, für den wir ein vernünftiges Ergebnis erhalten. Danach überschreiten wir den langen Raum und der relative Wert wird negativ.)
Der Benutzer kaya3 hat Folgendes herausgefunden:
Die asymptotische Konstante beträgt übrigens genau 1/8 = 0,125; Hier ist die genaue Formel über Wolfram Alpha .
for (j = i; j < i *i; j += i)
Dann benötigen Sie den Modultest nicht (da erj
garantiert durch teilbar isti
).