8.1 霍纳法则

  以下是一个典型的多项式运算

int y = 4*x*x*x*x +9*x*x*x +2*x*x +7*x +1;

  这个表达式能不能性能优化?
  细数一下这个表达式用了4+3+2+1=10次乘法,同时用到了4次加法。
  可以优化为

int y = (((4*x+9)*x+2)*x+7)*x+1;

  优化后,只有4次乘法和4次加法。直接减少了6次乘法运算。
  这就是霍纳法则,也叫秦九韶算法,最早由中国人发明,用于减少多项式的计算次数。
  霍纳法则原理很简单,缓存重复运算的结果,但是不是动态规划思想,因为不包含递归。
y = a x 4 + b x 3 + c x 2 + d x + e y=ax^4+bx^3+cx^2+dx+e y=ax4+bx3+cx2+dx+e
  合并 a x 4 + b x 3 ax^4+bx^3 ax4+bx3包含的乘以 x 3 x^3 x3重复运算:
( a x + b ) x 3 + c x 2 + d x + e (ax+b)x^3 +cx^2+dx+e (ax+b)x3+cx2+dx+e
  进一步合并乘以 x 2 x^2 x2重复运算:
( ( a x + b ) x + c ) x 2 + d x + e ((ax+b)x+c)x^2+dx+e ((ax+b)x+c)x2+dx+e
  进一步合并乘以x重复运算,得到结果,本质是空间换时间:
( ( ( a x + b ) x + c ) x + d ) x + e (((ax+b)x+c)x+d)x+e (((ax+b)x+c)x+d)x+e
  代码实现就非常简单了

public static int horner(int[] args, int x) {
    int r = args[0];
    for (int i = 1; i < args.length; i++) {
        r = r * x + args[i];
    }
    return r;
}

  python代码如下:

# _*_ coding:utf-8 _*_

class HornerPolynomial:

    def __init__(self, items: list):
        self.__polynomial = items

    @property
    def polynomial(self):
        return self.__polynomial

    # 本身是个函数
    def __call__(self, *args, **kwargs):
        result = 0
        for coefficient in self.polynomial:
            result = result * args[0] + coefficient
        return result

  那霍纳法则实用在哪里?
  1 java String类的hashcode使用霍纳法则计算
  2 用切比雪夫近似值计算sin(x) cos(x)时也用到了霍纳法则
  3 开发工具生成得hashcode代码用到了霍纳法则。
  尤其是切比雪夫近似值的优化,霍纳法则的使用可以说支撑了整个游戏世界。因为3D游戏中的投影计算中,大量使用了正弦余弦。但是计算机的正弦余弦都是用多项式近似值去计算的。只要用到多项式,必用霍纳法则。
  对于计算机来说,乘法的开销远远大于加法,所以减少乘法次数非常重要,常见的减少乘法次数的算法还有矩阵strassen算法,二进制快速幂,Karatsuba算法等。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

醒过来摸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值