コンピュータサイエンスにおいて、コック・ヤンガー・カサミアルゴリズム(別名CYKまたはCKY)は、1961年に酒井一郎によって発表された文脈自由文法の構文解析アルゴリズムである。 [ 1 ] [ 2 ]このアルゴリズムは、ジョン・コック、ダニエル・ヤンガー、笠見忠雄、ジェイコブ・T・シュワルツといった再発見者の名前にちなんで名付けられている。ボトムアップ構文解析と動的計画法を採用している 。
CYKの標準バージョンは、チョムスキー標準形(CNF)で与えられた文脈自由文法のみを扱います。しかし、任意の文脈自由文法は、同じ言語を表現するCNF文法にアルゴリズム的に変換できます(Sipser 1997 )。
CYKアルゴリズムの重要性は、特定の状況におけるその高い効率性に由来します。ビッグO記法を用いると、CYKの最悪実行時間は次のようになります。、 どこは解析された文字列の長さであり、CNF文法のサイズ(Hopcroft & Ullman 1979 、p. 140) 。このため、最悪ケースの漸近的複雑性の観点から最も効率的な構文解析アルゴリズムの1つとなっていますが、多くの実用的なシナリオでは、平均実行時間がより優れた他のアルゴリズムも存在します。
動的計画法アルゴリズムでは、現在のシーケンスを2つのより小さなシーケンスに分割できる可能性をテストするため、文脈自由文法をチョムスキー標準形(CNF)に変換する必要があります。空文字列を生成しない任意の文脈自由文法は、以下の形式の生成規則のみを使用してCNFで表現できます。そして; 空文字列を許可するには、明示的に許可することができます、 どこは開始記号です。[ 3 ]
擬似コードによるアルゴリズムは以下のとおりです。
入力はn文字からなる文字列I : a 1 ... a nとする。 文法はr 個の非終端記号R 1 ... R rを含み、開始記号はR 1とする。P [ n , n , r ] をブール値の配列とする。P のすべての要素をfalse に初期化する。back [ n , n , r ]をバックポイント トリプルのリストの配列とする。back のすべての要素を空のリストに初期化する。各s = 1 からnに対して、各単位生産R v → a sに対して、 P [ 1 , s , v ] = true とします。各l = 2 からnまで-- スパンの長さ各s = 1 からn - l +1まで-- スパンの開始各p = 1 からl -1まで-- スパンの分割各生成規則R a → R b R c P [ p , s , b ] およびP [ l - p , s + p , c ]の場合、P [ l , s , a ] = true と設定します。 <p,b,c> をback [ l , s , a ]に追加する P [n, 1 , 1 ]が真であれば、Iは言語の要素である 。backを返す 。backを通して手順をたどることで、文字列のすべての可能な構文木を簡単に構築できる。そうでなければ、 「言語の要素ではない」を返す。
すべての生成規則の確率に基づいて、最も可能性の高い構文解析結果を復元することを可能にする。
入力はn文字からなる文字列I : a 1 ... a nとする。 文法はr 個の非終端記号R 1 ... R rを含み、開始記号はR 1とする。P [ n , n , r ]を実数の配列とする。P のすべての要素をゼロに初期化する。back [ n , n , r ]をバックポイント トリプルの配列とする。 各s = 1 からnについて、各単位生成R v → a sについて、 P [ 1 , s , v ] = Pr( R v → a s ) と設定する。各l = 2 からnについて-- スパンの長さ、各s = 1 からn - l +1について-- スパンの開始、各p = 1 からl -1について-- スパンの分割、各生成R a → R b R cについて 、prob_splitting = Pr( R a → R b R c ) * P [ p , s , b ] * P [ l - p , s + p , c ] と設定する。prob_splitting > P [ l , s , a ]の場合、P [ l , s , a ] = prob_splitting と 設定し、 [ l , s , a ] = <p,b,c> と設定する。P [n, 1 , 1 ] > 0の場合、逆 方向にたどって構文木を見つけ、構文木を 返す。そうでない場合は 、「言語のメンバーではありません」を返す。
非公式に言えば、このアルゴリズムは入力文字列のすべての可能な部分文字列を考慮し、長さのサブストリングが真である場合から非終端から生成できる長さ1の部分文字列の処理が終わると、長さ2の部分文字列の処理に移り、以下同様に続きます。長さ2以上の部分文字列については、部分文字列を2つの部分に分割するすべての可能な方法を考慮し、何らかの生成規則が存在するかどうかを確認します。そのため最初の部分と一致し、2番目の部分と一致します。そうであれば、記録します。部分文字列全体に一致する場合。この処理が完了すると、入力文字列全体を含む部分文字列が開始記号に一致する場合、文法によって入力文字列が生成されます。

これは文法の例です。
次に、 「彼女はフォークで魚を食べる」という文をCYKアルゴリズムで分析します。次の表では、iは行番号 (下から 1 で始まる)、jは列番号 (左から 1 で始まる) です。
読みやすさのために、 Pの CYK テーブルは、 R kがに含まれる非終端記号のセットを含む2 次元行列Mとしてここで表されます。ならば、そしてその場合に限り、上記の例では、開始記号Sは、文は文法によって生成できます。
上記のアルゴリズムは、文が対象言語に含まれるかどうかのみを判定する認識器です。これを、ブール値1の代わりに構文木ノードを配列の要素として格納することで、構文木も構築する構文解析器に簡単に拡張できます。ノードは、そのノードを生成するために使用された配列要素にリンクされ、ツリー構造を構築します。1つの構文木のみを生成する場合は、各配列要素にそのようなノードが1つだけ必要です。しかし、曖昧な文のすべての構文木を保持する場合は、対応するノードが構文解析プロセスで取得できるすべての方法のリストを配列要素に格納する必要があります。これは、いわゆるバックポインタの2番目のテーブルB[n,n,r]を使用して行われることがあります。最終的な結果は、可能な構文木の共有フォレストとなり、共通のツリー部分はさまざまな構文解析間で分割されます。この共有フォレストは、解析された文のみを生成する曖昧な文法として都合よく読むことができますが、元の文法と同じ曖昧さを持ち、非終端記号の非常に単純な名前変更を除いて同じ構文木を持ちます。これはLang(1994)によって示されています。
Lange & Leiß (2009)が指摘しているように、チョムスキー標準形への既知の変換の欠点は、文法サイズの望ましくない肥大化につながる可能性があることである。文法のサイズは、その生成規則のサイズの合計であり、規則のサイズは右辺の長さに 1 を加えたものである。元の文法のサイズを表すために、最悪の場合のサイズ拡大は、に変換アルゴリズムによって異なる。教育での使用のために、LangeとLeißはCYKアルゴリズムを少し一般化したものを提案している。「アルゴリズムの効率性、説明の明瞭さ、証明の簡潔さを損なうことなく」(Lange & Leiß 2009 )。
CYKアルゴリズムを拡張して、重み付き確率的文脈自由文法を用いて文字列を解析することも可能です。この場合、ブール値の代わりに重み(確率)がテーブルPに格納されるため、P[i,j,A]には、iからjまでの部分文字列がAから導出される最小の重み(最大の確率)が格納されます。さらにアルゴリズムを拡張すると、文字列のすべての解析結果を、重みが低い順(確率が高い順)から高い順(確率が低い順)に列挙できるようになります。
確率的CYKアルゴリズムを長い文字列に適用すると、多くの確率を掛け合わせるため、分割確率が非常に小さくなることがあります。この問題は、確率を掛け合わせる代わりに、対数確率を合計することで解決できます。
CYKの最悪実行時間はここで、nは解析された文字列の長さ、| G | は CNF 文法Gのサイズです。これにより、これは実際に一般的な文脈自由言語を認識するための最も効率的なアルゴリズムの 1 つになります。Valiant (1975)は CYK アルゴリズムの拡張を提供しました。彼のアルゴリズムは CYK アルゴリズムと同じ構文解析テーブルを計算しますが、0-1 エントリを持つ行列の効率的な乗算アルゴリズムをこの計算に利用できることを示しました。
これらの行列の乗算にCoppersmith–Winogradアルゴリズムを使用すると、漸近的な最悪実行時間は次のようになります。しかし、ビッグオー記法で隠された定数項は非常に大きいため、コッパースミス・ウィノグラードアルゴリズムは、現代のコンピュータでは処理できないほど大きな行列に対してのみ有効であり(Knuth 1997 )、このアプローチは減算を必要とするため、認識にしか適していません。効率的な行列乗算への依存は完全には避けられません。Lee (2002)は、時間で動作する文脈自由文法のパーサーは、は、積を計算するアルゴリズムに効果的に変換できます。-時間内に0-1エントリを持つ行列そしてこれは、Abboud ら[ 4 ]によって定数サイズの文法に適用するように拡張されました。