【问题标题】:Given all roots, how do I find the coefficients of a polynomial in time faster than O(n^2)?给定所有根,我如何在时间上比 O(n^2) 更快地找到多项式的系数?
【发布时间】:2015-02-11 22:02:15
【问题描述】:

鉴于多项式的所有根,我必须找出一种算法,它可以比 O(n^2) 更快地生成系数。我在解决这个问题时遇到了麻烦。我很确定我应该使用快速傅里叶变换或傅里叶逆变换的概念,但我不知道如何将输入修改为不是统一的第 n 个根。谁能指出我正确的方向?

【问题讨论】:

  • 1.什么域? (R,C,...?) 2. R 域的直接多项式写入有什么问题,例如:roots={ x0,x1,x2,x3,x4 } -> polynom(x) =(x-x0)*(x-x1)*(x-x2)*(x-x3)*(x-x4) 所以你只需要代数乘以得到系数...... 3. N 是什么?根数?在那种情况下,乘法可悲的是 O(N^2) ...所以可能是 FFT 多项式乘法 ...

标签: algorithm


【解决方案1】:

这是一个 O(n * (log n)^2) 的解:

  1. 基本情况:对于一个根 a,答案就是 x - a。

  2. 假设我们有一个包含多个根的列表。我们可以对列表的前半部分和后半部分递归求解,然后使用快速傅里叶变换将结果相乘。

时间复杂度由公式T(n) = 2 * T(n / 2) + O(n log n)得到,根据Master定理为O(n * (log n)^2) .

【讨论】:

  • 我曾想过这样的事情,但我搞砸了重复设置。如果我有四个根,r1、r2、r3、r4,算法基本上是把r1和r2、r3和r4的二项式相乘,那么两者的结果都正确吗?
【解决方案2】:

kraskevich 基本上做到了。缺少一些细节,并且太长而无法放入评论字段。以下是详细信息。

基本上,您希望设置为多项式乘法问题。您的输入将是 p1,...pN 其中 pj(x) = (x-rj)。

这是伪代码:

function multiply2Poly(p1, p2)

   // here, use FFT, multiply and use IFFT back


function multiplyPoly(p[1],...p[N])
    if (N==1) return p[1]
    if (N==2) return multiply2Poly(p[1],p[2])
    else {
         return multiply2Poly(multiplyPoly(p[1],...p[N/2]),multiplyPoly(p[1+N/2],...,p[N])
    }


function getCoef(r[1],...r[N])

    return multiplyPoly((p[1]=x-r[1]),...(p[N]=x-r[N]));

对于 FFT 部分:

观察如果两个多项式是:

p1 = a[0]+a[1] x + ...+a[n] x^n
p2 = b[0]+a[1] x + ...+a[n] x^n

那么 p1 * p2 = c[0] + c[1] x + ...+c[n] x^n

其中 C = A [x] B 其中 [x] = 卷积。 A = (a[0],...,a[n]), B = (b[0],...,b[n]) 和 C = (c[0],...,c[ n])。

然后使用 FFT 和卷积定理来加快速度。

C = A [x] B = IFFT{ FFT{A} * FFT{B} } 其中 * 这里只是乘法。

IFFT 的运行时间 = FFT 的运行时间 = O(n log n)。
乘法运行时间为 n,因此总运行时间为 O(n log n)。

那么,multiplyPoly 的总运行时间为:

T(N) = R(N/2) + T(N/2)*2

而 R(N/2) = O(n log n) 就是上面所说的 multiply2Poly 的运行时间。

所以

T(N) = T(N/2) * 2 + O(n log n)

现在 Master 定理给出 O(n (log n)^2)

【讨论】:

    猜你喜欢
    • 2011-03-08
    • 2018-11-05
    • 2019-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    • 1970-01-01
    相关资源
    最近更新 更多