令为大小为位的固定正整数。ñ
允许对这个整数进行适当的预处理。
给定另一个大小为位的正整数,乘法的复杂度是多少?M A B
请注意,我们已经有算法。这里的查询是我们是否可以通过任何更聪明的方法使\ epsilon = 0?
令为大小为位的固定正整数。ñ
允许对这个整数进行适当的预处理。
给定另一个大小为位的正整数,乘法的复杂度是多少?M A B
请注意,我们已经有算法。这里的查询是我们是否可以通过任何更聪明的方法使\ epsilon = 0?
Answers:
尽管它不一定总是最有效的算法,但这个问题与加法链有非常密切的关系。通过加法链快速计算任何算法都可以转换为通过重复加法计算的算法(每个加法当然是运算)。相反,对于任何,一种用于计算的快速算法都会导致一种用于计算的快速算法,但是当然,该算法不一定必须具有加法链的形式。不过,这似乎是一个不错的起点。看看http://en.wikipedia.org/wiki/Addition_chain或查看第一卷。2之有关更多详细信息,请参见计算机编程艺术。
为了扩展史蒂文·斯塔德尼基(Steven Stadnicki)的想法,我们可以快速构造一个天真算法,该算法比使用离散傅立叶变换的矩阵乘法要好。
我们计算的个数。如果少于一半的位是1,我们将构造一个位置链表。要相乘,我们只需将左移列表中的每个位置(乘以表示的那个位)并相加结果。
如果一半以上的位为1,则与上述相同,但是我们使用零代替填充位置列表。想法是,我们将从所有乘积中获得的总和中减去该总和。为了让所有的人的总和,我们转向通过的位数和减去来源于此。然后我们可以减去从链表中获得的总和。
我们可以称其为朴素的链表算法。在最坏的情况下,它的运行时间为,但在平均情况下,它的运行时间为,对于小情况,它的运行时间比DFT快。
为了最佳地使用列表的思想,我们使用了分而治之。我们将分成两半,并使用朴素算法找到关联列表的大小。如果它们大于5,则在大于5的一半处再次调用朴素算法,直到我们设法将所有一半减为小于5。(这是因为我们可以将其减少为4个减法)
更好的是,我们改进了分治法。我们遍历分支的所有可能组合,并贪婪地选择最佳分支。此预处理与实际乘法大约需要相同的时间。
如果允许预处理具有无限的自由度,则可以针对所有分支优化求解最优的分治算法。在最坏的情况下,这需要花费时间,但是通过加法链方法应该是最佳的。
我正在为上述算法计算更精确的值。
名为乘以常数的乘是亚线性(PDF)的论文给出了移位/加法运算的算法,其中是常数的大小。
本质上,它的工作原理是寻找在恒定-Bits,移位和添加数量为那些仅被乘以在恒定比特(如长乘法二进制,其中位在底部数相乘的装置顶部不会移位和添加,而位表示顶部已移位和添加)。但是,这仍然是,因为常量中可以有。
纸张然后谈到改变常数的数字表示到双基数系统,其中,显然,非 -Bits是稀疏,如果转换正确地完成(它是一个非常冗余数系统)。他们计算出它的稀疏程度。非零位数的数量限制为小于,因此需要一个亚线性的加法数。但是,由于每次加法的成本(其中是以下项的大小),它仍然是实际操作常数,是其他数字的大小)。
因此,要回答您的问题,是的,与矩阵向量乘法的结果相似,如果常数不变,则会得到加速。但是当然,这种加速仅是通过天真的长乘法实现的,并且存在比您可以得到的更好的乘法算法。此算法。
正如Matt Groff所建议的那样,您可能有兴趣向实践社区寻求灵感(或者您所处环境中的是否在当前CPU的位宽范围内)。确实,许多编译器作者和电路设计人员已经考虑了将常量乘以整数的问题,尽管他们通常对“无乘数乘法器”(使用移位,加法和减法进行乘法)感兴趣。我知道的早期参考资料之一是(我从Hacker's Delight 8.4节中学到了这一点):
Bernstein,R.(1986),乘以整数常数。软件:实践与经验,16:16:641–652。doi:10.1002 / spe.4380160704
文森特·莱夫弗尔(VincentLefèvre)的更多现代作品可以在这里找到(一定要看他的后续作品),他还注意到一个有关有效电路综合的CMU项目(请参见那里的参考资料)。后一个项目甚至考虑同时乘以一组常数。
PS我鼓励您考虑将用户名更改为可识别的名称。
我不确定这是否与问题直接相关,但以下基本结果可能会引起人们的兴趣。给定固定的自然数,只要以反向二进制符号(即,最低有效位在前)写入,就可以通过顺序自动机来实现操作。自动机的状态数是,其中是除的最大幂。例如,通过以下自动机来实现的运算。
例如,和。因此,在反向二进制,被写为和(坏的选择,我知道...)为。在此自动机上处理条目给出了路径