2010-03-05 10 views
18

Quelle est la complexité Big-O pour les algorithmes répandus des opérations arithmétiques de base comme la multiplication, la racine carrée, le logarithme, le scalaire et le produit matriciel? Y at-il des algorithmes exotiques qui sont plus efficaces, en termes de complexité Big-O, mais qui ne sont pas très répandus dans les solutions pratiques (par exemple, non implémentés dans les bibliothèques de logiciels populaires)?Big O complexité des opérations arithmétiques de base

+2

+1 Question intéressante. Pour plus de clarté, on suppose qu'il signifie complexité avec un nombre croissant de bits. – Tronic

+0

@Tronic: pensez-vous que les bits? Le produit matriciel serait probablement en termes de taille de la matrice ... – Skilldrick

+0

Wiki communautaire? –

Répondre

19

Voir http://en.wikipedia.org/wiki/Computational_complexity_of_mathematical_operations


produit de matrices des matrices carrées:

Il y a aussi un O (N 2,38) Coppersmith–Winograd algorithm mais je ne pense pas qu'il est répandue en raison de l'énorme constante caché.

multiplication Big-int:

Il existe également un n log n & middot; 2 O (log * n) algorithme publié en 2008 mais qui était trop nouveau pour être répandu.


Habituellement, la méthode naïve est assez bonne pour une entrée de taille normale.

+0

Il est intéressant de constater que O (N 2.38) est plus rapide que O (N³). – psihodelia

+1

Malheureusement, la réponse à cela est "ça dépend". Comme le mentionne l'article wikipedia, l'algorithme n'est pas très utilisé car il ne fait que réduire le temps d'exécution pour des intrants d'une taille impensable. –

+1

En pratique, l'algorithme O (N^2.38) n'est pas plus rapide du tout, car il y a plus de vitesse que de complexité algorithmique. – Pillsy

5

Les opérations n'ont pas de complexité, contrairement aux algorithmes. Par exemple, il existe différents algorithmes de racine carrée, et ils auront une complexité différente.

+2

La multiplication est un algorithme entre deux tableaux de bits. Avec la complexité O (n²), si je ne me trompe pas. – Tronic

+2

@Skilldrick: OP parle des algorithmes les plus couramment utilisés, donc dans un sens cette réponse n'est pas pertinente. –

+0

@Moron: Je pense que la question a été légèrement modifiée depuis que j'ai répondu. – Skilldrick

5

Vous considérerez la plupart des opérations simples comme O (1) car votre taille d'entrée est généralement fixe (c'est-à-dire 32 ou 64 bits). Dans des conditions normales, votre plate-forme effectuera exactement la même opération pour la multiplication, la racine carrée, le logarithme, etc., quelle que soit la "taille" de votre entrée (par exemple int a = 0 et int b = Int32.MaxValue sont les deux entiers 32 bits).

Cela devient intéressant quand vous commencez à regarder des matrices ou à représenter des nombres de précision arbitraire, mais quelqu'un a déjà lié le résumé de wikipedia, donc je ne vais pas entrer dans ça. N'utilisez pas Schönhage–Strassen pour multiplier les petits nombres "normaux". Ça va me faire pleurer. Juste parce qu'un algorithme est O (n ) ne signifie pas qu'il est mauvais - surtout quand n est presque toujours 2 ou 2 .

+0

C'est un très bon point sur les opérations sur les entiers 32 bits. – Skilldrick

+0

En pratique, vous avez raison sur les opérations simples. Cependant, en tant que théoricien, je veux dire que vous pouvez toujours parler de la complexité en termes de nombre de bits dans le nombre. Le même algorithme fonctionne bien pour 32b, mais devient lent pour 64b, ou quand nous arrivons finalement à 1024b ou quelque chose ... Encore une fois, réalistement vous avez raison, mais c'est toujours une question intéressante. –

+0

* hochements de tête *, c'est une question absolument intéressante dès que vous sortez du monde sans danger des entrées à longueur fixe. –

1

La racine carrée et le logarithme peuvent être implémentés de diverses manières, affectant grandement la complexité (jugée par la précision requise). Si elles sont implémentées avec des tables de recherche (et une sorte d'interpolation), l'exigence de mémoire explose vraiment car plus de précision est requise mais la complexité est de rechercher la valeur dans le tableau et éventuellement d'appliquer l'interpolation.

Plus généralement, ils semblent être implémentés par leurs définitions de séries. Recurve ou itère une déclaration pour un certain nombre de tours jusqu'à ce que vous atteigniez la précision requise. Ici le nombre de tours peut devenir très élevé car plus de précision est nécessaire, et les calculs eux-mêmes sont affectés par la précision accrue.

+0

+1 Intéressant. Est-ce que cela signifie que N devient la précision? – Skilldrick

+0

@skilldrick vous pouvez certainement le faire de cette façon. Il y a des algorithmes qui sont mesurés dans la taille de leur OUTPUT au lieu de leur entrée. Ils ont un nom, mais c'est vendredi, donc je ne peux pas prendre la peine de m'en souvenir B-) –

0

Il y a un algorithme de type Fourier qui fait la multiplication entier ainsi (Schonhage-Strassen)

Je pensais qu'il y avait une version de l'algorithme de Strassen qui fait un peu mieux que la normale pour la multiplication entier, mais maintenant que je pense, celui-là finit par être le même que simple ...

L'addition et la soustraction sont à peu près, juste l'addition et la soustraction. Division et la racine carrée sont probablement intéressants si ...

AUSSI: Notez que jusqu'à présent, tout le monde a parlé de l'arithmétique INTEGER. Une fois que vous arrivez à flotteurs/doubles tous les paris sont désactivés. Ensuite, vous entrez dans le monde de numerical analysis, et c'est tout un champ de son propre ...

1

Jetez un oeil à BigInteger, sur des entiers de longueur arbitraire. Tout a maintenant un coût, en termes de taille de l'entrée, qui est le nombre de bits (généralement O(log K) bits pour un nombre K). Je vais utiliser N pour le nombre de bits ci-dessous. Par exemple, l'addition et la soustraction sont maintenant O(N). La multiplication est O(N^2) (naïf) ou O(n (log n)^(2+epsilon) ) avec FFT.

D'autres algorithmes incluent la fonction "power", qui prend la multiplication O(N). (excepté maintenant chaque multiplication a un coût!)

Et il y a des complexités supplémentaires pour BigDecimals, qui est l'équivalent décimal de longueur arbitraire, et au-delà de certaines opérations plus basiques, certaines des choses sont plus intéressantes aussi (surtout si vous voulez comprendre combien de précision vous voulez). Vous pouvez jeter un oeil à l'implémentation de Java.

+0

Une implémentation naïve de la fonction de puissance nécessite des multiplications O (n), mais les implémentations intelligentes sont O (log n): http://en.wikipedia.org/wiki/Exponentiation_by_squaring – Juliet

+0

Comme je l'ai mentionné, 'N' est le nombre de bits. L'alimentation est en effet 'O (log K)' pour un certain nombre de 'K' cependant. – Larry

0

La division et les racines carrées pour un grand nombre de bits ne sont pas beaucoup plus complexes que la multiplication. Pour les deux opérations, l'ancienne itération de Newton peut être arrangée de telle sorte que l'itération de Newton n'ait que des multiplications. Puisque le nombre de chiffres corrects est doublé à chaque étape, nous pouvons simplement doubler la précision du calcul à chaque étape.