Soit un entier positif fixe de taille bits.
On est autorisé à prétraiter cet entier comme il convient.
Etant donné un autre entier positif de taille bits, quelle est la complexité de la multiplication ?
Soit un entier positif fixe de taille bits.
On est autorisé à prétraiter cet entier comme il convient.
Etant donné un autre entier positif de taille bits, quelle est la complexité de la multiplication ?
Réponses:
Bien que ce ne soit pas toujours l'algorithme le plus efficace, cette question a une relation très étroite avec les chaînes d'addition; tout algorithme de calcul rapidement par des chaînes d'addition se traduit par un algorithme pour le calcul par addition répétée (chaque addition, bien sûr, être un fonctionnement). Au contraire, un algorithme rapide pour calculer pour tout conduit à un algorithme rapide pour calculer , mais il n’est bien entendu pas nécessaire que cet algorithme se présente sous la forme d’une chaîne d’addition; Pourtant, cela semble être un excellent endroit pour commencer. Consultez http://en.wikipedia.org/wiki/Addition_chain ou consultez vol. 2 deL'art de la programmation informatique pour plus de détails.
Pour développer l'idée de Steven Stadnicki, nous pouvons rapidement construire un algorithme naïf qui fait mieux que la multiplication matricielle à l'aide de la transformée de Fourier discrète.
Nous comptons le nombre de ceux qui en . Si moins de la moitié des bits sont des bits, nous construisons une liste chaînée de leurs positions. Pour multiplier, il suffit de déplacer gauche de chaque position dans la liste (en multipliant par le bit représenté) et d'ajouter les résultats.
Si plus de la moitié des bits sont des bits, nous procédons comme ci-dessus, mais nous utilisons plutôt les zéros pour renseigner la liste des positions. L'idée est que nous soustrayions cette somme de la somme qui serait obtenue en multipliant par toutes les unités. Pour obtenir la somme de tous ceux, nous passons par le nombre de bits et soustrayons de cette situation . Ensuite, nous pouvons soustraire notre somme obtenue de la liste chaînée.
Nous pouvons appeler cela l'algorithme naïf de liste chaînée. Son temps de fonctionnement est dans le pire des cas, mais dans le cas moyen, ce qui est plus rapide que DFT pour les petites.
Pour utiliser l’idée de listes de manière optimale, nous utilisons diviser pour mieux régner. Nous divisons en deux et trouvons la taille des listes associées à l’aide de l’algorithme naïf. S'ils sont supérieurs à 5, nous appelons à nouveau l'algorithme naïf sur des moitiés supérieures à 5 jusqu'à ce que nous parvenions à réduire toutes les moitiés à moins de cinq. (C'est parce que nous pouvons réduire cela à 4 soustractions)
Mieux encore, nous améliorons notre algorithme de division et de conquête. Nous parcourons toutes les combinaisons possibles de ramifications, en choisissant le meilleur. Ce prétraitement prend environ le même temps que la multiplication réelle.
Si le pré-traitement nous permet une liberté infinie, nous résolvons de manière optimale l'algorithme optimisé de division et de conquête pour toutes les branches. Cela prend du temps dans le pire des cas, mais il devrait être ~ optimal par les méthodes de la chaîne d'addition.
Je travaille sur le calcul de valeurs plus exactes pour les algorithmes ci-dessus.
Le document appelé Multiplication par une constante est sous-linéaire ( PDF ) donne un algorithme pour opérations de décalage / addition oùnest la taille de la constante.
Cela fonctionne essentiellement en recherchant les bits de la constante, en décalant et en ajoutant le nombre à multiplier uniquement pour les 1 bits de la constante (comme une longue multiplication pour binaire, où 0 dans le nombre inférieur à multiplier signifie le haut n'est pas décalé et ajouté, alors qu'un bit 1 signifie que le haut est décalé et ajouté). Cependant, c'est toujours O ( n ) , car il peut y avoir O ( n ) 1 bits dans la constante.
Le document parle alors de changer la représentation numérique de la constante dans le système numérique à double base, où , apparemment, les non -bits sont clairsemés, si la conversion est effectuée correctement (il est un système numérique très redondant). Ils calculent à quel point c'est rare; le nombre de bits non nuls étant limité à moins de O ( n ) , un nombre sous-linéaire d'additions est requis. Cependant, il reste encore O ( n mopérations effectives, dues aucoûtO(m)de chaque addition (oùnest la taille de la constante etmest la taille de l'autre nombre).
Donc, pour répondre à votre question, oui, la multiplication matrice-vecteur a un résultat similaire, en ce sens que vous obtenez une accélération si elle est constante; mais bien sûr cette accélération n’est que sur la multiplication longue naïve, et il existe des algorithmes de multiplication bien meilleurs que O ( n 2).vous pouvez obtenir avec cet algorithme.
Comme suggéré par Matt Groff, vous pouvez être intéressé par des inspirations dans la communauté de pratique (ou si dans votre situation correspond à la largeur en bits d'un processeur actuel). En effet, le problème de la multiplication d’entiers par une constante a été examiné par de nombreux rédacteurs de compilateur et concepteurs de circuits, bien qu’ils s’intéressent généralement au "multiplicateur sans multiplicateur" (multiplier par shift, addition et soustraction). Une des premières références que je connaisse est (je l’ai appris de la section 8.4 de Hacker's Delight):
Bernstein, R. (1986), Multiplication par des constantes entières. Logiciels: pratique et expérience, 16: 641–652. doi: 10.1002 / spe.4380160704
Des travaux plus modernes de Vincent Lefèvre peuvent être trouvés ici (assurez-vous de voir des travaux ultérieurs à ceux-ci), et il note également un projet de la CMU sur la synthèse de circuits efficace (voir les références ici). Ce dernier projet envisage même la multiplication simultanée par un ensemble de constantes.
PS je vous encourage à envisager de changer votre nom d'utilisateur pour quelque chose de reconnaissable.
Je ne suis pas sûr que cela soit directement lié à la question, mais le résultat élémentaire suivant pourrait être intéressant. Étant donné un nombre naturel fixe , l'opération n → k n peut être réalisée par un automate séquentiel, à condition que n soit écrit en notation binaire inversée (c'est-à-dire bit le moins significatif en premier). Le nombre d'états de l'automate est k / 2 r, où 2 r est la plus grande puissance de 2 qui divise k . Par exemple, l'opération n → 6 n est réalisée par l'automate suivant.
Par exemple, et 6 × 185 = 1110 = 2 + 4 + 16 + 64 + 1024 . Ainsi, en binaire inverse, 185 est écrit 10011101 et 1110 (mauvais choix, je sais ...) 01101010001 . Traitement de l'entrée 10011101 sur cet automate donne le chemin 0 → 0 1 | 1 → 1 qui donne la sortie correcte01101010001. Le type d'automate séquentiel que j'utilise ici a été appelésous-séquentielpar Schützenberger: comme vous pouvez le constater, il existe unpréfixe initial(en vert) et unefonction de sortie du terminal.