符号模型检验(5)扩展OBDD

⇑ ⇑ ⇑ ⇑ ⇑ \Uparrow\Uparrow\Uparrow\Uparrow\Uparrow 上方专栏内有更多内容 ⇑ ⇑ ⇑ ⇑ ⇑ \Uparrow\Uparrow\Uparrow\Uparrow\Uparrow

扩展OBDD

集合的OBDD表示
对于一个集合的子集来说,可以用一个特征函数来定义。在此定义中,每个元素可以用二进制位编码来代表。而函数取1则代表此子集存在。

例如给出集合 { p 0 , p 1 , p 2 , p 3 , p 4 , p 5 } \{p_0,p_1,p_2,p_3,p_4,p_5\} {p0,p1,p2,p3,p4,p5}
和编码
p 0 = x 2 ′ x 1 ′ x 0 ′ p 1 = x 2 ′ x 1 ′ x 0 p 2 = x 2 ′ x 1 x 0 ′ p 3 = x 2 ′ x 1 x 0 p 4 = x 2 x 1 ′ x 0 ′ p 5 = x 2 x 1 ′ x 0 \begin{matrix} p_0=x_2'x_1'x_0'&p_1=x_2'x_1'x_0&p_2=x_2'x_1x_0'&\\p_3=x_2'x_1x_0&p_4=x_2x_1'x_0'&p_5=x_2x_1'x_0& \end{matrix} p0=x2x1x0p3=x2x1x0p1=x2x1x0p4=x2x1x0p2=x2x1x0p5=x2x1x0
x 0 , x 1 , x 2 ∈ { 0 , 1 } x_0,x_1,x_2\in\{0,1\} x0,x1,x2{0,1},这里省略布尔 ∗ * 运算符号,不是排列)
现在有子集 { p 0 , p 2 , p 3 } \{p_0,p_2,p_3\} {p0,p2,p3}
那么,对于变量 { x 0 , x 1 , x 2 } ∈ { 0 , 1 } \{x_0,x_1,x_2\}\in\{0,1\} {x0,x1,x2}{0,1}
可以构造出一个函数
ϕ { p 0 , p 2 , p 3 } ( x 0 , x 1 , x 2 ) = x 2 ′ x 1 ′ x 0 ′ + x 2 ′ x 1 x 0 ′ + x 2 ′ x 1 x 0 \phi_{\{p_0,p_2,p_3\}}(x_0,x_1,x_2)=x_2'x_1'x_0'+x_2'x_1x_0'+x_2'x_1x_0 ϕ{p0,p2,p3}(x0,x1,x2)=x2x1x0+x2x1x0+x2x1x0
ϕ = 1 \phi=1 ϕ=1即表示此子集成立。
可以看出,此表示方法由原来n个变量降维到 l o g 2 ( n ) log_2(n) log2(n)个变量。
对于这个特征函数,可以发现,就是一个布尔函数,既然是布尔函数自然就可以用OBDD来表示。

0
1
x2
x1
x0

特征函数的操作
特征函数既然是表示集合,那么集合的操作也应该可以降维到函数的运算。
(以下是布尔符号运算)
空集: χ ∅ = 0 \chi_\emptyset=0 χ=0
并集运算: χ S ∪ T = χ S + χ T \chi_{S\cup T}=\chi_S+\chi_T χST=χS+χT
交集运算: χ S ∩ T = χ S ∗ χ T \chi_{S\cap T}=\chi_S*\chi_T χST=χSχT
差运算: χ S − T = χ S ∗ ( χ T ) ′ \chi_{S- T}=\chi_S*(\chi_T)' χST=χS(χT) (当 S ⊂ T S\subset T ST χ S − T = 0 ) \chi_{S- T}=0) χST=0)

矩阵的OBDD
OBDD可以表示关系矩阵(元素只有0,1)。

矩阵行元素和列元素同样是集合。
需要注意的是
在OBDD表示矩阵行列元素与我们通常做法不同。
通常我们用 X 0 , X 1 , … X n X_0,X_1,…X_n X0,X1,Xn表示第1,2,…,n行
在OBDD中,依然可以把 X 0 , X 1 , … X n X_0,X_1,…X_n X0,X1,Xn看作集合 X = { X 0 , X 1 , … X n } X=\{X_0,X_1,…X_n\} X={X0,X1,Xn}编码得到新集合
X = { ( x t ′ x t − 1 ′ … x 0 ′ ) , ( x t ′ x t − 1 ′ … x 0 ) , … … , ( x t x t − 1 … x 0 ) } , t ≤ l o g 2 ( n ) X=\{(x_t'x_{t-1}'…x_0'),(x_t'x_{t-1}'…x_0),……,(x_tx_{t-1}…x_0)\},t\le log_2(n) X={(xtxt1x0),(xtxt1x0),,(xtxt1x0)},tlog2(n)
对Y同理。
于是矩阵中元素可以表示为笛卡尔积 X × Y = { x t x t − 1 … x 0 y t y t − 1 … y 0 ∣ x i , y j ∈ { 0 , 1 } } X\times Y=\{x_tx_{t-1}…x_0y_ty_{t-1}…y_0|x_i,y_j\in\{0,1\}\} X×Y={xtxt1x0ytyt1y0xi,yj{0,1}}

简单实例
已知有向图G(V,E),给定一个起始节点s和终点t,找出所有从s到t的最短路径。

0
1
2
3
4

按照一般的做法可以运用搜索相关的知识。这里介绍OBDD视角。
参考集合的OBDD表示法,对节点V进行编码[ x 0 x 1 x 2 x_0x_1x_2 x0x1x2]
0 = [ 000 ] 1 = [ 001 ] 2 = [ 010 ] 3 = [ 011 ] 4 = [ 100 ] 0=[000] \quad1=[001]\quad 2=[010]\quad 3=[011]\quad 4=[100] 0=[000]1=[001]2=[010]3=[011]4=[100]
有向图的特征函数可以表示为
f G ( v x , v y ) = x 0 ′ x 1 ′ x 2 ′ y 0 ′ y 1 ′ y 2 + x 0 ′ x 1 ′ x 2 ′ y 0 ′ y 1 y 2 ′ + x 0 ′ x 1 ′ x 2 y 0 ′ y 1 y 2 ′ + x 0 ′ x 1 ′ x 2 y 0 ′ y 1 y 2 + x 0 ′ x 1 ′ x 2 y 0 y 1 ′ y 2 ′ + x 0 ′ x 1 x 2 ′ y 0 ′ y 1 y 2 f_G(v_x,v_y)=x_0'x_1'x_2'y_0'y_1'y_2\\ +x_0'x_1'x_2'y_0'y_1y_2'\\ +x_0'x_1'x_2y_0'y_1y_2'\\ +x_0'x_1'x_2y_0'y_1y_2\\ +x_0'x_1'x_2y_0y_1'y_2'\\ +x_0'x_1x_2'y_0'y_1y_2 fG(vx,vy)=x0x1x2y0y1y2+x0x1x2y0y1y2+x0x1x2y0y1y2+x0x1x2y0y1y2+x0x1x2y0y1y2+x0x1x2y0y1y2
其中 v x , v y v_x,v_y vx,vy表示编码后的节点。这样特征函数就表示了边。即
f G ( v i , v j ) = 1 ⇔ ⟨ v i , v j ⟩ ∈ E f_G(v_i,v_j)=1 \Leftrightarrow \langle v_i,v_j \rangle \in E fG(vi,vj)=1vi,vjE
对应OBDD
在这里插入图片描述
(左边: f G f_G fG的实际OBDD,右边:将0节点和1节点模仿决策树展开的图。这里展开图作为辅助理解的工具,实际上0节点和1节点都是唯一的节点。)

始点s对应的点的特征函数为 X s ( v ) = x 0 ′ x 1 ′ x 2 ′ X_s(v)=x_0'x_1'x_2' Xs(v)=x0x1x2
终点t对应点的特征函数为 X t ( v ) = x 0 ′ x 1 x 2 X_t(v)=x_0'x_1x_2 Xt(v)=x0x1x2
这里用 X ( ⋅ ) X(\cdot) X()表示单独使用 x 0 , x 1 , x 2 x_0,x_1,x_2 x0,x1,x2作为变量的函数,相对应的,单独使用 y 0 , y 1 , y 2 y_0,y_1,y_2 y0,y1,y2作为变量的函数可以被记为 Y ( ⋅ ) Y(\cdot) Y()

s对应的OBDD
x0
x1
0
x2
1
t对应的OBDD
x0
x1
0
x2
1

接下来就是搜索操作。
首先我们知道,起始点s与特征函数与(合取)操作的结果就是以起始点s为起点的合法有向边的集合,暂且定义为 f ( 1 ) f^{(1)} f(1)。(OBDD的合取操作在上一节有说明,忘记了的可以回去再看看)
f ( 1 ) ( v i , v j ) : = X s ( v i ) ∧ f G ( v i . v j ) f ( 1 ) ( v i , v j ) = 1 ⇔ v i = s & ⟨ v i , v j ⟩ ∈ E f^{(1)}(v_i,v_j):=X_s(v_i) \land f_G(v_i.v_j)\\ f^{(1)}(v_i,v_j)=1 \Leftrightarrow v_i=s \& \langle v_i,v_j \rangle \in E f(1)(vi,vj):=Xs(vi)fG(vi.vj)f(1)(vi,vj)=1vi=s&vi,vjE
在这里插入图片描述
得到 f ( 1 ) f^{(1)} f(1)也就意味着得到对s距离为1的可达点,把它们的特征函数定义为 X ( 1 ) ( v ) X^{(1)}(v) X(1)(v)
Y ( 1 ) ( v ) : = ∃ x , f ( 1 ) ( x , v ) X ( 1 ) ( v ) : = Y ( 1 ) ( v ) Y^{(1)}(v):=\exist x ,f^{(1)}(x,v)\\X^{(1)}(v):=Y^{(1)}(v) Y(1)(v):=x,f(1)(x,v)X(1)(v):=Y(1)(v)
这里使用 Y ( 1 ) ( v ) Y^{(1)}(v) Y(1)(v)作为中转函数。这个中转函数是必要的。因为在OBDD中 x x x y y y表达的意义是不一样的。
在这里插入图片描述
接下来重复这些步骤就可以找出距离s步长为2,3,4……的可达点。即递推过程
{ f ( i ) ( v i , v j ) : = X ( i − 1 ) ( v i ) ∧ f G ( v i . v j ) Y ( i ) ( v ) : = ∃ x , f ( i ) ( x , v ) X ( i ) ( v ) : = Y ( i ) ( v ) s . t . X ( 0 ) ( v ) = X s ( v ) i ∈ N \begin{cases} f^{(i)}(v_i,v_j):=X^{(i-1)}(v_i)\wedge f_G(v_i.v_j)\\ Y^{(i)}(v):=\exist x, f^{(i)}(x,v)\\ X^{(i)}(v):=Y^{(i)}(v) \end{cases} s.t. \begin{matrix} X^{(0)}(v)=X_s(v)\\ i\in \mathbb N \end{matrix} f(i)(vi,vj):=X(i1)(vi)fG(vi.vj)Y(i)(v):=x,f(i)(x,v)X(i)(v):=Y(i)(v)s.t.X(0)(v)=Xs(v)iN
直到出现边界条件 ∃ n , X ( n ) ( t ) = 1 \exist n,X^{(n)}(t)=1 n,X(n)(t)=1,( t t t指终点)。
(判断有没有环,有没有连通等等操作也可以修改边界条件达成)

连通性是知道了,但是还有那么多额外的边, X ( n ) ( v ) X^{(n)}(v) X(n)(v)也不是只有 t t t一个点。怎么排除这些多余的路径?反向搜索就可以了。具体过程留给读者思考。我给出一个大致的框架。
{ f s h o r t e s t ( j ) ( v i , v j ) : = Y s h o r t e s t ( j ) ( v i ) ∧ f ( j ) ( v i . v j ) X s h o r t e s t ( j − 1 ) ( v ) : = ∃ y , f s h o r t e s t ( j ) ( v , y ) Y s h o r t e s t ( j − 1 ) ( v ) : = X s h o r t e s t ( j − 1 ) ( v ) s . t . Y s h o r t e s t ( n ) ( v ) = X t ( v ) j ∈ N , j < n \begin{cases} f^{(j)}_{shortest}(v_i,v_j):=Y^{(j)}_{shortest}(v_i)\wedge f^{(j)}(v_i.v_j)\\ X^{(j-1)}_{shortest}(v):=\exist y, f^{(j)}_{shortest}(v,y)\\ Y^{(j-1)}_{shortest}(v):=X^{(j-1)}_{shortest}(v) \end{cases} s.t. \begin{matrix} Y^{(n)}_{shortest}(v)=X_t(v)\\ j\in \mathbb N,j<n \end{matrix} fshortest(j)(vi,vj):=Yshortest(j)(vi)f(j)(vi.vj)Xshortest(j1)(v):=y,fshortest(j)(v,y)Yshortest(j1)(v):=Xshortest(j1)(v)s.t.Yshortest(n)(v)=Xt(v)jN,j<n
观察式子可知,这是一个反向递推的过程,实践中完全可以把 X s h o r t e s t ( j ) , Y s h o r t e s t ( j ) , f s h o r t e s t ( j ) X^{(j)}_{shortest},Y^{(j)}_{shortest},f^{(j)}_{shortest} Xshortest(j),Yshortest(j),fshortest(j)直接覆盖到原来的 X ( j ) , Y ( j ) , f ( j ) X^{(j)},Y^{(j)},f^{(j)} X(j),Y(j),f(j)

至此我们可以用我们已知的方法来找出最短路径链。下面是一种dfs的思路。

typedef OBDD_Of_Points OP
typedef OBDD_Of_Edges OE
Array[Chain] ans;
int n;//由前面的步骤算出来的n
//初始的u=s(初始点),i=0
function DFS(Array[OP] X,Array[OE] f,Chain c,Point u,int i)
	if i==n
		ans.add(c.copy())
		return
	Array[Point] any_v=X[i+1].toPointArray() //将OBDD转换为点集
	for Point v in any_v
		if f[i+1].judge(u,v)==1
			c.add(v);
			DFS(X,f,c,v,i+1)
			c.remove(v)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值