問題2.34 Hornerの方法についての補足
SICP読書会でHornerの方法を実装する問題をやったあと、これが何の役に立つのか?という話をしたのだけど、いまいちな説明だったように思うので文章で補足してみる。
前提知識は、以下3つくらいのつもり。
Hornerの方法とは何か
Hornerの方法とは、一元n次多項式を計算するときの簡単な(計算量の少ない)算法である。
という多項式の値は次のように計算してもよいはずだ。
これがHornerの方法である。
さて、計算量が少ないと言ったが、どの程度少ないのであろうか。
まず馬鹿正直にを計算してみよう。
を計算するのに、n回の足し算が必要である。
次に馬鹿正直にk次の項:を計算するには(k+1)回の掛け算が必要だ。
従って、n次多項式を計算するには、
回の掛け算が必要になる。
であるが、Σの計算は前提知識としていないので、Σの公式に頼らず計算する。を逆順に書いても総和は変わらないので、
各項を縦に足すと、
である。
以上によりの計算量オーダーはとなる*1。
一方、Hornerの方法を使う場合、自明にn回の掛け算とn回の足し算が必要なので、計算量オーダーはとなる。もちろんこれはよりもかなり早い。
他方、馬鹿正直にk次の項でk+1回の掛け算を行わず、逐次平方してやることによりk次の項の計算オーダーをで評価することもできる。
この場合、掛け算のオーダーは、
これの評価はちょっと悩むが、なので、
と大雑把に上限と下限を見積もってやることはできる。従って逐次平方する場合の計算オーダーはであるが、これはより大きく、よりは小さい。
何の役に立つか?
たとえば、ハッシュテーブルを実装するには文字列からハッシュ値を求める必要があり、ハッシュ値を求めるハッシュ関数として使うことができる。
これについては以前、Cでハッシュテーブルを作ってみたで書いたのでそちらを参照のこと。(これはつまり、長さnの文字列をx進数の多倍長整数とみなして、その値を求めるのに、n次多項式の値を求めるHornerの方法を使えるということである)
なお、文字列の情報を切り捨てないハッシュ関数は、文字列の長さをnとすれば少なくとものオーダーになると考えられるので、Hornerの方法によるハッシュ関数は計算オーダーとしては比較的素性がよいものと言える気がする。