CYK算法

CYK算法（英語：Cocke–Younger–Kasami algorithm，縮寫為CYK algorithm）是由約翰·科克，Younger和嵩忠雄（日语：嵩忠雄）共同研究出来大约发表于1965年的一个算法，它是一个用来判定任意给定的字符串   w ∈ Σ ∗ {\displaystyle ~w\in \Sigma ^{*}} 是否属于一个上下文无关文法的算法。普通的回溯法（backtracking）在最坏的情况下需要指数时间才能解决这样的问题，而CYK算法只需要多项式时间就够了（   O ( n 3 ) {\displaystyle ~O(n^{3})} ， n 为字符串 w 的长度）。CYK算法采用了动态规划的思想。 对于一个任意给定的上下文无关文法，都可以使用CYK算法来计算上述问题，但首先要将该文法转换成乔姆斯基范式。   G = ( V , Σ , S , P ) {\displaystyle ~G=(V,\Sigma ,S,P)} 是一个上下文无关文法 对于任意字符串 w = σ 1 . . . σ n ∈ Σ ∗ {\displaystyle w=\sigma _{1}...\sigma _{n}\in \Sigma ^{*}} ，定义 w [ i , j ] = σ i . . . σ j ,   1 ≤ i ≤ j ≤ n {\displaystyle w[i,j]=\sigma _{i}...\sigma _{j},~1\leq i\leq j\leq n} 对于任意选择的   i , j {\displaystyle ~i,j} ，定义 V i , j = { X ∈ V   |   X ⇒ ∗ w [ i , j ] } {\displaystyle V_{i,j}=\{X\in V~|~X\Rightarrow ^{*}w[i,j]\}} 通过由下而上的方法计算   V i , j {\displaystyle ~V_{i,j}} 这个集合，如果 S ∈ V 1 , n {\displaystyle S\in V_{1,n}} ，那么就说明   w {\displaystyle ~w} 是被上下文无关文法   G {\displaystyle ~G} 接受的字符串。 因为   G {\displaystyle ~G} 是一个乔姆斯基范式，当且仅当有下面描述的情况时 X ∈ V i , j {\displaystyle X\in V_{i,j}} ： i < j ,   ∃ Y , Z , k : X → Y Z {\displaystyle i<j,~\exists Y,Z,k:X\rightarrow YZ} 是   G {\displaystyle ~G} 中的一个规则且 Y ∈ V i , k , Z ∈ V k + 1 , j {\displaystyle Y\in V_{i,k},Z\in V_{k+1,j}} FOR i:= 1 TO n DO V i , i := { X ∈ V   |   X → σ i   i n   P } {\displaystyle V_{i,i}:=\{X\in V~|~X\rightarrow \sigma _{i}~in~P\}} FOR l:= 1 TO n-1 FOR i:= 1 TO n-l DO   V i , i + l := ∅ {\displaystyle ~V_{i,i+l}:=\varnothing } FOR k:= i TO i+l-1 DO   V i , i + l := V i , i + l ∪ { X   |   X → Y Z , Y ∈ V i , k , Z ∈ V k + 1 , i + l } {\displaystyle ~V_{i,i+l}:=V_{i,i+l}\cup \{X~|~X\rightarrow YZ,Y\in V_{i,k},Z\in V_{k+1,i+l}\}} IF S ∈ V 1 , n {\displaystyle S\in V_{1,n}} THEN accept ELSE reject 对于上述CYK算法作一个小改动，也就是说记住每次的k，就可以自动产生一个由该上下文无关语言的推导树。 FOR i:= 1 TO n DO V i , i := { X ∈ V   |   X → σ i   i n   P } {\displaystyle V_{i,i}:=\{X\in V~|~X\rightarrow \sigma _{i}~in~P\}} FOR l:= 1 TO n-1 FOR i:= 1 TO n-l DO   V i , i + l := ∅ {\displaystyle ~V_{i,i+l}:=\varnothing } FOR k:= i TO i+l-1 DO   V i , i + l := V i , i + l ∪ { ( X , k )   |   X → Y Z , Y ∈ V i , k , Z ∈ V k + 1 , i + l } {\displaystyle ~V_{i,i+l}:=V_{i,i+l}\cup \{(X,k)~|~X\rightarrow YZ,Y\in V_{i,k},Z\in V_{k+1,i+l}\}} IF ∃ k : ( S , k ) ∈ V 1 , n {\displaystyle \exists k:(S,k)\in V_{1,n}} THEN accept ELSE reject 通过对下面的方法递归运行就可以生成推导树。 Tree(X,i,j): IF i=j THEN RETURN   σ i {\displaystyle ~\sigma _{i}} 选择一个 k 使 ( X , k ) ∈ V i , j {\displaystyle (X,k)\in V_{i,j}} 选择 Y 和 Z 使 X → Y Z , Y ∈ V i , k , Z ∈ V k + 1 , j {\displaystyle X\rightarrow YZ,Y\in V_{i,k},Z\in V_{k+1,j}} RETURN Tree(X,Tree(Y,i,k),Tree(Z,k+1,j)) 给定一个乔姆斯基范式的上下文无关文法   G = ( { S , A , B , C } , { a , b } , S , P ) {\displaystyle ~G=(\lbrace S,A,B,C\rbrace ,\lbrace a,b\rbrace ,S,P)} ，其中规则 P 如下： S → A B ∣ B C {\displaystyle S\rightarrow AB\mid BC} A → B A ∣ a {\displaystyle A\rightarrow BA\mid a} B → C C ∣ b {\displaystyle B\rightarrow CC\mid b} C → A B ∣ a {\displaystyle C\rightarrow AB\mid a} 问：字符串 bbabaa 能不能通过该文法产生？ CYK算法可以通过一个表格来运算，表中 i 列 j 行表示由哪几个非终结符可以产生字字符串 σ i … σ j {\displaystyle \sigma _{i}\dots \sigma _{j}} 。 如果在表格的最左下角一格中有文法的开始非终结符 S ，那么字符串 bbabaa 就能由上面给出文法 G 产生。 John Cocke and Jacob T. Schwartz (1970). Programming languages and their compilers: Preliminary notes. Technical report, Courant Institute of Mathematical Sciences, New York University. T. Kasami (1965). An efficient recognition and syntax-analysis algorithm for context-free languages. Scientific report AFCRL-65-758, Air Force Cambridge Research Lab, Bedford, MA. Daniel H. Younger (1967). Recognition and parsing of context-free languages in time n3. Information and Control 10(2): 189–208. Interaktives Java-Applet zur Demonstration（页面存档备份，存于互联网档案馆）