Toutes les autres réponses sont correctes, je veux juste modifier ce qui suit. Je voulais voir si la réduction des exécutions de la boucle k interne était suffisante pour réduire la complexité réelle ci-dessous. O(n⁴).
J'ai donc écrit ce qui suit:
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);
}
Après avoir exécuté cela, il devient évident que la complexité est en fait n⁴
. Les dernières lignes de sortie ressemblent à ceci:
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
Ce que cela montre, c'est que la différence relative réelle entre le réel n⁴
et la complexité de ce segment de code est un facteur asymptotique vers une valeur autour 0.124...
(en fait 0,125). Bien qu'il ne nous donne pas la valeur exacte, nous pouvons en déduire ce qui suit:
La complexité du temps est n⁴/8 ~ f(n)
où se f
trouve votre fonction / méthode.
- La page wikipedia sur la notation Big O indique dans les tableaux de la «famille des notations Bachmann – Landau» que la
~
définition de la limite des deux côtés de l'opérande est égale. Ou:
f est égal à g asymptotiquement
(J'ai choisi 363 comme borne supérieure exclue, car n = 362
c'est la dernière valeur pour laquelle nous obtenons un résultat sensible. Après cela, nous dépassons l'espace long et la valeur relative devient négative.)
L'utilisateur kaya3 a compris ce qui suit:
La constante asymptotique est exactement 1/8 = 0,125, soit dit en passant; voici la formule exacte via Wolfram Alpha .
for (j = i; j < i *i; j += i)
alors vous n'avez pas besoin du test de module (car ilj
est garanti d'être divisible pari
).