Black box linear algebra

Latest Author anta /Date 2015-12-04 16:05:06 / Views 16806
24 (Favした一覧ページはユーザーページから)

はじめに

この記事では、競技プログラミングにおいて使える Black box linear algebra, 特に Wiedemann [1] によるアプローチのテクニックについていくつか書きます。

この記事はCompetitive Programming Advent Calendar 2015の4日目の記事です。

導入

競技プログラミングにおいて、数え上げ問題は1つの大きなジャンルです。 多くの場合、10000000071000000007などの数で割った余りを求めることを行います。今回は、特に素数による剰余を取る場合について考えていきます。

数え上げ問題の解法には多くの種類がありますが、その中でも大きなものとしてあるのは行列を用いた解法です。線形代数を用いているとも言えるでしょう。 そのような例として、今回は以下の2つを取り上げます。

行列累乗によるDPの高速化

行列累乗は数え上げ問題で非常によく用いられるテクニックです。 状態遷移を行列として表することでDPを表現します。 つまり、初期状態をベクトルbb, 遷移行列をAAとしたとき、KK回遷移した後の状態はAKbA^K bとして表現できます。 バイナリ法により累乗することにより、行列サイズをNNとしたときΘ(N3logK)\Theta(N^3 \log K)時間で答えを求められます。

行列累乗は様々な特殊ケースにおいてさらに高速化ができることがあります。 たとえば行列が巡回行列である場合、そのような行列同士の掛け算はO(N2)O(N^2)時間(または高速多項式乗算を用いてその計算量)で求めることができ、 また巡回行列同士の積は巡回行列であるので合計O(N2logK)O(N^2 \log K)時間で実行できます。 三角テプリッツ行列の場合でも同じように高速化できます。

今回は、高速に行列累乗ができるクラスを上記の特殊ケースたちから大きく広げ、一般の場合の行列累乗をも高速化できるテクニックを紹介します。

行列式を求める問題

競技プログラミングにおいて、行列式が必要になることはよくあります。 これは準同型写像であり、非常に基本的なものであるといえ、応用も数えきれないほどあります。 そのため、それを使う問題が多くあることは驚くことではないでしょう。

たとえば、行列木定理と呼ばれる定理は、 グラフが与えられたとき、全域木の個数を行列式を用いて求められると述べています。 非自明な数え上げを多項式時間で行ってしまうというのだから行列式の力の大きさがわかるでしょう。

N×NN \times Nの行列の行列式はガウスの消去法を用いてΘ(N3)\Theta(N^3)時間で求めることができます。 より高速にできる特殊ケースとしては、KK重対角行列の場合Θ(NK2)\Theta(N K^2)時間でガウスの消去法を実行できます。

今回は、他の大きなクラスにおいて計算を高速化させます。

準備

線型漸化列とその最小多項式

VVを体FF上のベクトル空間とする。 VV上の無限列{ai}i=0\{a_i\}_{i=0}^{\infty}が線型漸化的であるとは、 あるFF上の多項式c(X)=i=0nciXi\displaystyle c(X) = \sum_{i=0}^n c_i X^iが存在し、全ての0i0 \le iに対してj=0ncjai+j=0\displaystyle \sum_{j=0}^n c_j a_{i+j} = 0となることをいう。 このとき、ccaaをannihilateしていると呼ぶ。

aaをannihilateする多項式の集合はイデアルを成す。 多項式環はPIDなので生成元が存在するが、零イデアルでないならそのうちleading係数が1のものが唯一に決まり、それをaaの最小多項式と呼ぶ。 ただし、零イデアルが生成される場合00を最小多項式とする。そうでない場合aaを線型漸化的であると呼ぶ。

ffを2つのベクトル空間上の線形写像とすると、f(a)f(a)の最小多項式はaaの最小多項式の約数である。

行列の最小多項式と特性多項式

正方行列AAに対し、列{Ai}i=0\{A^i\}_{i=0}^{\infty}を考える。 この列の最小多項式を行列AAの最小多項式と呼ぶ。

正方行列AAの特性多項式はchar(A)=det(XIA){\rm char}(A) = {\rm det}(X I - A)として定義される。ここでXXは多項式の変数。 nnAAの大きさとするとき、char(A)(0)=(1)ndet(A){\rm char}(A)(0) = (-1)^n {\rm det}(A)であることを確認しておく。

ケイリー・ハミルトンの定理は、 {Ai}\{A^i\}は線型漸化的であり、最小多項式は特性多項式の約数であると述べている。 また、大きさnnの行列の最小多項式の次数はnn以下であることは帰結である。

行列AAのある固有値とそれに対応する固有ベクトルをλ,v\lambda, vとしたとき、 多項式ffに対しf(A)v=f(λ)vf(A) v = f(\lambda) vであることが確認できる。つまり、{Ai}i\{A^i\}_iをannihilateするffに対し、全ての固有値はffの根となる。 また、最小多項式が特性多項式の約数であることと組み合わせると、最小多項式と特性多項式の根の集合は一致するということが言える。

最小多項式を求める

最小多項式はどうやっても求めればいいのだろうか? そもそも、無限列は普通には入力できない。 そこで、最小多項式の次数の上限nnと列の先頭2n2n要素を入力することにする。 先頭2n2n要素から最小多項式が一意に求められることは、以下のアルゴリズムと一緒に構成的に証明される。

体上の場合

入力列がある体FFの要素である場合を考える。 この場合、拡張ユークリッド互除法やBerlekamp–Massey algorithmを用いて O(n2)O(n^2)時間で求めることができる。詳細は文献を参考のこと。 なお、後者のアルゴリズムの実装は非常に簡単である。

ベクトルの場合

次に、入力列bbがある体FFのベクトルFmF^mの要素である場合を考える。 まず、FFの有限部分集合UUを取り、そのUUから一様ランダムにmm要素を選びベクトルuuとする。 そしてai=uTbia_i = u^T b_iとして新たなFF上の列aaを計算する。 このときaaの最小多項式が高確率でbbの最小多項式と一致するというのが重要な定理である。詳細は割愛する。 合計O(mn+n2)O(mn + n^2)時間となる。

行列の場合

最後に、行列AAの最小多項式を求めることを考える。 この場合、上の場合と同じように、ランダムなベクトルbbを取って列{Aib}i=02n1\{A^i b\}_{i=0}^{2n-1}を求め、 その列に対して上記のアルゴリズムを適用することにより、これもまた高確率でAAの最小多項式を求められる。 各iiに対しAibA^i bを求めるのに行列乗算は必要なく、あるベクトルとAAの乗算のみでよいことに注意する。 ここで、ベクトルとAAの乗算にT(n)T(n)時間かかるとすると、合計O(n2+nT(n))O(n^2 + n T(n))時間で最小多項式が求められた。

最小多項式の応用

行列累乗の高速化

行列AA, ベクトルbb, 自然数KKに対し、AKbA^K bが求めたいのであった。 ここで、上記で述べたとおり列{Aib}i\{A^i b\}_iが線型漸化的であることに注目する。

まず、列{Aib}i\{A^i b\}_iの最小多項式を求める。すると、問題は線型漸化式の第KK項を求めるものとなる。 ここで、多項式を使うテクニックたちに書いてある方法が使える。 その方法を用いAKbA^K bAib(i<n)A^i b (i < n)の線型和で表せば、単純に求めた初項と掛けあわせればよい。 ベクトルとAAの乗算をT(n)T(n)時間で求められるとすると、合計O(n2+nT(n)+M(n)logK)O(n^2 + n T(n) + M(n) \log K)時間で実行できる。 ここで、M(n)M(n)は多項式乗算の時間計算量を表す。

上記の計算量は、一般の場合T(n)=Θ(n2)T(n) = \Theta(n^2)の場合でもO(n3+M(n)logK)O(n^3 + M(n) \log K)となり、高速化となっている。 また、巡回行列や(三角とは限らない)テプリッツ行列の場合はO(nM(n)+M(n)logK)O(n M(n) + M(n) \log K)となる。 さらに、スパースな行列で非0要素がSS個のものの場合、ベクトルにそれを乗算することはO(S)O(S)時間で可能なので、O(n2+nS+M(n)logK)O(n^2 + n S + M(n) \log K)で計算できることとなる。 DPの高速化の場合、遷移行列がスパースである場合は多い。

行列式を高速に求める

サイズnnの正方行列AAが与えられたとき、行列式det(A){\rm det}(A)を求めたいのであった。 行列式は(1)nchar(A)(0)(-1)^n {\rm char}(A)(0)であることを思い出すと、AAの特性多項式を求められればいいこととなる。

もしAAの最小多項式の次数がnnであれば、それは特性多項式と一致する。 また、上記のとおりそれらは根の集合が一致する。 しかし最小多項式の次数はnnより小さくなることがある。 アイデアは、AAに前処理を行うことで最小多項式と特性多項式を一致させるというものである。

まず、det(A)=0{\rm det}(A) = 0である場合、特性多項式と最小多項式は共に00を根に持つということになるため、それにより判定できる。 AAが非特異行列であると仮定する。 DDをランダムに選んだdet(D)0{\rm det}(D) \neq 0となる対角行列とする。このとき、ADADの最小多項式は高確率で次数nnとなるというのが重要な補題である。割愛する。 これによりADADの最小多項式を求め、それからdet(AD){\rm det}(AD)を求め、det(D){\rm det}(D)で割れば答えが出る。

ベクトルとAAの乗算をT(n)T(n)時間で求められるとすると、ベクトルとADADの乗算はO(n+T(n))O(n + T(n))時間で求められるので、合計O(n2+nT(n))O(n^2 + n T(n))時間で行列式が求められる。

終わりに

Black box linear algebra

上記の例では、実際には行列は明示的に与えられなくてもよいことに注意する。 つまり、ベクトルを入力としてある行列を掛ける(別の言葉で言うと、線形変換を行う) 「ブラックボックス」さえ入力されれば、その中身に関係なくアルゴリズムは実行できるということである。 このような線形代数のアルゴリズムを"Black box linear algebra"と呼ぶ。

上記で紹介した以外にも様々なアルゴリズムが発見されている。 例えば、線形方程式Ax=bAx = bも、同じようなアプローチで高速に解くことができる。

結論

今回は非常に幅広い計算問題を高速化する方法を紹介した。 競技プログラミングにおいても線形代数を使う問題は豊富にある。 たとえこの方法が想定解でなかったとしても使える場面は多いだろう。 是非活用していただきたい。

参考文献

  • [1] Wiedemann, Douglas H. "Solving sparse linear equations over finite fields." Information Theory, IEEE Transactions on 32.1 (1986): 54-62.
  • Von Zur Gathen, Joachim, and Jürgen Gerhard. Modern computer algebra. Cambridge university press, 2013.