【问题标题】:multiplication of two numbers in 6 of n/3 bits 6T(n/3) karatsuban/3 位 6T(n/3) 中的两个数的乘法 karatsuba
【发布时间】:2014-10-06 01:46:25
【问题描述】:

两个数相乘

x*y ----> x =(x0*10^(n/3)+x1*10^(n/3)+x2) and y=(y0*10^(n/3)+y1*10^(n/3)+y2)

它是 10^n/3 个数的 9 次乘法,所以 9T(n/3) 但可以通过以下方法减少到 5。

x*y= x0*y0+x1*y1+x2*y2+x0*y1+x0*y2+x1*y0+x1*y3+x2*y0+x2*y1

我可以通过类似 Karatsuba 算法的技巧将两个数字的乘法减少到 5T(n/3)

(x0+x1+x2)(y0+y1+y2)-x0*y0-x1*y1-x2*y2= x0*y1+x0*y2+x1*y0+x1*y3+x2*y0+x2*y1

n/3 位数字的全部和全部 5 次乘法,所以 5T(n/3)+O(n) 但我怎么能像 6T(n/3)+O(n) 那样进行 6 次乘法运算

Q1 可以减少到 6 而不是 5 吗?

[edit1]从 Spektre 重新提出的问题中复制的更正

x 和 y 有 n 位

x=x0*(10^2n/3)+x1*10^n/3+x2
y=y0*(10^2n/3)+y1*10^n/3+y2
x*y=x2y2+(x2y1+x1y2)10^n/3+(x2y0+x1y1+x0y2)10^2n/3+(x1y0+x0y1)10^n+x0y0*10^4n/3
  • 现在 n/3 位数字的 9 次乘法运行时间为 9T(n/3),即 O(n^2)

像 Karatsuba 的乘法这样的小技巧:

  • 首先计算 x0y0、x1y1 和 x2y2 这是 n/3 位数字的 3 次乘法
  • 然后使用 x0y0、x1y1 和 x2y2 计算其他如下:
  • x2y1+x1y2=(x1+x2)(y1+y2)-x1y1-x2y2 ->> n/3 位数的 1 次乘法
  • x2y1+x1y1+x0y2=(x0+x2)(y0+y2)-x0y0-x2y2+x1y1 ->> n/3 位数的 1 次乘法
  • x1y0+x0y1=(x0+x1)(y0+y1)-x0y0-x1y1 ->> n/3 位数的 1 次乘法

递归解决6个子问题

  • 并将它们与 O(n) 位数字上的 7 个加法相结合。
  • 现在总共需要 n/3 位数字的 6 次乘法运行时间 6T(n/3)

Q2 如何将其减少到 5 次而不是 6 次?

  • 由于 OP 中的错误,Q1 现已过时

【问题讨论】:

  • 您的第二个公式显示了九个部分产品,但似乎缺乏缩放。您声称五个((n / 3)+ c)乘法和第三个等式(左边四个乘积,右边六个)让我迷失了:有什么联系?六个而不是五个(n/3 乘法?)有什么优势? (第一个等式可能应该是 x=(x0*10^(2n/3)+x1*10^(n/3)+x2) ... ,从这里的十进制数字切换到更远的位没有帮助。)
  • 仅供参考,他在stackoverflow.com/q/26218011/2336725 重新提出了这个问题。但这是更进一步的,所以我想说我们忽略重新询问,把注意力集中在这里。
  • @Teepeemm 已将重新提出的问题正文 + 重新格式化和样式复制到此问题中。
  • 1.现在我有点困惑,首先你想要 5 muls,现在 6 是什么? 2.您是否验证了您的解决方案? 3. 顺便说一句,这个三重递归的意义通常比减半要慢,因为堆/堆栈垃圾更少(即使三元组的复杂性要好一些)

标签: algorithm math multiplication


【解决方案1】:

不是答案,但作为评论将无法阅读

如果你将数字分成 3 组,那么 greybeard 是对的

a0=10^(2n/3)
a1=10^(1n/3)
a2=10^(0n/3)
x=x0*a0+x1*a1+x2*a2
y=y0*a0+y1*a1+y2*a2

所以乘法看起来像这样:

x*y=a0(x2*y2+x1*y2+x0*y2)
    +a1(x2*y1+x1*y1+x0*y1)
    +a2(x2*y0+x1*y0+x0*y0)

重写为数字:

b0=(x2*y2+x1*y2+x0*y2)
b1=(x2*y1+x1*y1+x0*y1)
b2=(x2*y0+x1*y0+x0*y0)
x*y=a0*b0+a1*b1+a2*b2

现在简化 b0,b1,b2

[提示]

  • 您利用了什么技巧?
  • 为什么您的结果中没有数字权重a0,a1,a2

[edit1] 如果您想解决此问题,请使用标准符号而不是您的

较低的有效数字是较低的索引,所以:

a0=10^(0n/3)
a1=10^(1n/3)
a2=10^(2n/3) // this is max wieght for operand
a3=10^(3n/3)
a4=10^(4n/3)
a5=10^(5n/3) // this is max weight for multiplication result
x=x0*a0+x1*a1+x2*a2
y=y0*a0+y1*a1+y2*a2

所以乘法看起来像这样:

x*y=a0(x0*y0+x1*y0+x2*y0)
    +a1(x0*y1+x1*y1+x2*y1)
    +a2(x0*y2+x1*y2+x2*y2)

重写为数字:

b0=(x0*y0+x1*y0+x2*y0)
b1=(x0*y1+x1*y1+x2*y1)
b2=(x0*y2+x1*y2+x2*y2)
x*y=a0*b0+a1*b1+a2*b2

粗略的 b0,b1,b2 不在个位数范围内 - 相反,由于乘法,它们都是两位数

所以你必须将它们分成单数:

x*y=a0*B0+a1*B1+a2*B2+a3*B3+a4*B4+a5*B5

地点:

B0=(b0/a0)%a1
B1=(b0/a1+b1/a0)%a1
B2=(b0/a2+b1/a1+b2)%a1
B3=(b0/a3+b1/a2+b2/a1)%a1
B4=(b0/a4+b1/a3+b2/a2)%a1
B5=(b0/a5+b1/a4+b2/a3)%a1
  • 并且不要忘记处理溢出...

【讨论】:

  • 我建议以另一种方式对权重进行编号(考虑一下,x 和 y 的部分也是为了保持一致性),结果将由部分结果和权重 base^n 到 0 到 4 的幂
  • @greybeard 是的,我也更喜欢它,但我希望拥有与 OP 中相同的索引,所以它不会太令人困惑......我只是想表明提出的解决方案是不正确的,因为他是缺少权重...
  • 我实际上在这里编辑了这个问题,并让另一个问题得到了正确的评论stackoverflow.com/questions/26218011/…
猜你喜欢
  • 1970-01-01
  • 2020-04-07
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 2019-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多