离散事件动态系统作业 #Petri网 #可达图 #赋时Petri
本文章由作者独立创作,为研究生某课程作业,仅供参考
先吐槽一点:CSDN竟然无法使用svg矢量图
1. 图的类型
1.1 有向图是一个二元组
G
=
(
V
,
E
)
{
V
:
结点或定点的集合
E
:
有向弧或者有向边的集合
G=(V,E)\\ \begin{cases} \ V:结点或定点的集合\\ \ E:有向弧或者有向边的集合\\ \end{cases}
G=(V,E){ V:结点或定点的集合 E:有向弧或者有向边的集合
E = { ( V 2 , V 1 ) , ( V 2 , V 3 ) , ( V 4 , V 1 ) , ( V 4 , V 3 ) } E=\{\:(V2,V1),(V2,V3),(V4,V1),(V4,V3)\:\} E={(V2,V1),(V2,V3),(V4,V1),(V4,V3)}
1.2 二分图是一个三元组
G = ( V ˉ , V ^ , E ) V = V ˉ ∪ V ^ ∀ ( x , y ) ∈ E , ( x ∈ V ˉ ∩ y ∈ V ^ ) ∪ ( x ∈ V ^ ∩ y ∈ V ˉ ) G=(\bar{V},\hat{V},E)\\ V=\bar{V}\cup\hat{V}\\ \forall\:(x,y)\in E,\:(x\in\bar{V}\ \cap\ y\in\hat{V})\,\cup\,(x\in\hat{V}\ \cap\ y\in\bar{V})\\ G=(Vˉ,V^,E)V=Vˉ∪V^∀(x,y)∈E,(x∈Vˉ ∩ y∈V^)∪(x∈V^ ∩ y∈Vˉ)
1.3 加权图是一个三元组
G = ( V , E , W ) W : E → R \begin{aligned} &G=(V,E,W)\\ &W:\ E\rightarrow R \end{aligned} G=(V,E,W)W: E→R
2. Petri网
P e t r i Petri Petri网是德国当代数学家 C . A . P e t r i C.A.Petri C.A.Petri 定义的一种通用的数学模型,用以描述存在于条件与事件间的关系。这一工作进行于1960~1962年间。此后各国学者,例如美国 M I T MIT MIT(麻省理工学院)及欧洲的众多大学,对网作了大量的研究。1980年以来,“ P e t r i Petri Petri网理论及应用欧洲研讨会”每年召开一次年会,交流新的研究成果。法国的科研人员为此做出了贡献。早在1972~1973年,已利用 P e t r i Petri Petri网模型来描述逻辑控制器,它对 G r a f c e t Grafcet Grafcet的建立产生了影响。
P e t r i Petri Petri网的模型是丰富的,既有严格的数学表达式,又有形象生动的图形化结构,能够描述离散事件动态系统中的顺序、选择、互斥、并发等事件关系,能对具有并行( p a r a l l e l i s m parallelism parallelism)、并发( c o n c u r r e n c y concurrency concurrency)、同步( s y n c h r o n i z a t i o n synchronization synchronization)、资源分享( r e s o u r c e s h a r i n g resource sharing resourcesharing)等特性建立模型并使之形象化。 P e t r i Petri Petri网在离散事件动态系统的建模、分析、仿真、形式化验证、故障诊断和调度控制等方面都有广泛的应用。
2.1 Petri网的表示
P
e
t
r
i
Petri
Petri网是一个四元组,有向二分加权图
N
=
(
P
,
T
,
F
,
W
)
{
P
:
库所集合,圆圈
T
:
变迁集合,矩形
(
方框
)
F
:
有向弧集合
W
:
F
→
Z
(
权值
)
N=(P,T,F,W)\\ \begin{cases} \ P:库所集合,圆圈\\ \ T:变迁集合,矩形(方框)\\ \ F:有向弧集合\\ \ W:F\rightarrow Z(权值)\\ \end{cases}
N=(P,T,F,W)⎩
⎨
⎧ P:库所集合,圆圈 T:变迁集合,矩形(方框) F:有向弧集合 W:F→Z(权值)
另外,
C − = P × T C^-=P \times T C−=P×T表示 ∣ P ∣ × ∣ T ∣ |P|\times |T| ∣P∣×∣T∣维的前置关联矩阵;
C + = T × P C^+=T \times P C+=T×P表示 ∣ T ∣ × ∣ P ∣ |T|\times |P| ∣T∣×∣P∣维的后置关联矩阵;
m 0 = [ 0 , 1 , . . . ] m_0=[0,1,...] m0=[0,1,...]表示初始标识的集合,每个库所中的标识皆称作 t o k e n token token, t o k e n token token用圆点表示,该集合中 t o k e n token token的总数量为非负整数;
C C C表示关联矩阵,其是由前后置关联矩阵计算得到的, C = C − − C + C=C^--C^+ C=C−−C+
2.2 使能变迁
如果一个变迁的每个输入库所的 t o k e n token token数不小于该库所到它弧上的权值,那么变迁是使能的。
即
m
≥
C
−
(
:
,
t
)
m\geq C^- (:\;,t)
m≥C−(:,t)
2.3 氢氧生水Petri网实例
下面以一个氢氧生水的例子来简单描述
P
e
t
r
i
Petri
Petri网
前置关联矩阵 C − C^- C−,表示每个变迁 ( t 1 , t 2 ) (t_1,t_2) (t1,t2)输入的变化, C − = [ 2 0 1 0 0 2 ] C^-=\left[ \begin{matrix} \:2&0\\\:1&0\\\:0&2\end{matrix}\:\right] C−= 210002
后置关联矩阵 C + C^+ C+,表示每个变迁 ( t 1 , t 2 ) (t_1,t_2) (t1,t2)输出的变化, C + = [ 0 2 0 1 2 0 ] C^+=\left[ \begin{matrix} \:0&2\\\:0&1\\\:2&0\end{matrix}\:\right] C+= 002210
关联矩阵 C = C + − C − = [ − 2 2 − 1 1 2 − 2 ] C = C^+-C^- =\left[ \begin{matrix} \:-2&2\\\:-1&1\\\:2&-2\end{matrix}\:\right] C=C+−C−= −2−1221−2
m 0 m_0 m0为初始状态,即初始每个库所中的 t o k r n tokrn tokrn数, m 0 = [ 3 1 2 ] m_0=\left[ \begin{matrix} \:3\\\:1\\\:2\end{matrix}\:\right] m0= 312
Petri网的激发有如下基本规则:
r u l e 1 rule1 rule1:只有使能的变迁才可以激发;
r u l e 2 rule2 rule2:变迁的激发耗时为0;
r
u
l
e
3
rule3
rule3:如果一个变迁激发,会从它的每个输入库所取走弧上权值个
t
o
k
e
n
token
token,并给它的输出库所放入弧上权值个
t
o
k
e
n
token
token;
m
k
+
1
=
m
k
+
C
(
:
,
t
)
=
m
k
+
C
⋅
e
→
k
+
1
m_{k+1} = m_k + C(:\;,t) = m_k + C \cdot \overrightarrow{e}_{k+1}
mk+1=mk+C(:,t)=mk+C⋅ek+1
在氢氧生水的例子中,激发第一次变迁,可以得到
m
1
=
m
0
+
C
⋅
e
→
1
=
[
3
1
2
]
+
[
−
2
2
−
1
1
2
−
2
]
⋅
[
1
0
]
=
[
3
1
2
]
+
[
−
2
−
1
2
]
=
[
1
0
4
]
\begin{aligned} m_1 &= m_0 + C \cdot \overrightarrow{e}_1 \\ &=\left[ \begin{matrix} \:3\\\:1\\\:2\end{matrix}\:\right] + \left[ \begin{matrix} \:-2&2\\\:-1&1\\\:2&-2\end{matrix}\:\right] \cdot \left[ \begin{matrix} \:1\\\:0\end{matrix}\:\right]\\ &=\left[ \begin{matrix} \:3\\\:1\\\:2\end{matrix}\:\right] + \left[ \begin{matrix} \:-2\\\:-1\\\:2\end{matrix}\:\right] = \left[ \begin{matrix} \:1\\\:0\\\:4\end{matrix}\:\right]\\ \end{aligned}
m1=m0+C⋅e1=
312
+
−2−1221−2
⋅[10]=
312
+
−2−12
=
104
2.4 典型的Petri网实例
2.4.1 典型Petri网结构图
2.4.2 典型Petri网matlab代码实现
%% petri_fun.m
function m=petri_fun(k)
m0 = [3;1;2;1;2;2;1];
m = m0;
if k>0
C_minus = [2 0 0 0 0 0 0 0 0 0;
1 0 0 0 0 0 0 0 0 0;
0 2 0 0 0 0 0 0 0 0;
0 0 1 0 1 0 0 0 0 0;
0 0 0 2 0 1 0 0 0 0;
0 0 0 0 0 0 2 0 1 0;
0 0 0 0 0 0 0 1 0 1];
C_plus = [0 0 1 0 0 0 0 0 1 0;
0 0 0 1 0 0 0 0 0 1;
2 0 0 0 0 0 0 0 0 0;
0 1 0 0 0 0 1 0 0 0;
0 1 0 0 0 0 0 1 0 0;
0 0 0 0 1 0 0 0 0 0;
0 0 0 0 0 2 0 0 0 0];
C = C_plus - C_minus;
E = eye(10);
for i=1:k
e = E(:,i);
if all(m0 + C_minus*e >=0)
m = m0 + C*e;
m0 = m;
else
fprintf("当前变迁无法激活,m = \n");
end
end
elseif k==0
fprintf("初始状态 m0 = \n");
else
fprintf("未发生变迁,m = \n");
end
end
%% run.m
display(petri_fun(0));
for i=1:10
fprintf("第%d次变迁,状态 m%d = \n",i,i);
disp(petri_fun(i));
end
2.4.3 执行结果
3. Petri网可达图
3.1 Petri网可达图算法
输入:后置关联矩阵 C + C^+ C+,前置关联矩阵 C − C^- C−,初始标识 m 0 m_0 m0
输出:可达图 G r = ( V , E , W ) G_r = (V,E,W) Gr=(V,E,W),加权有向图
算法步骤:
s t e p 1 step1 step1:设 V n e w V_{new} Vnew表示新结点的集合;
s t e p 2 step2 step2:画出可达图的根结点,并将其标为 m 0 m_0 m0,即 V = V ∪ { m 0 } V=V\cup\{m_0\} V=V∪{m0};
s t e p 3 step3 step3:将 m 0 m_0 m0标为新结点,即 V n e w = { m 0 } V_{new}=\{m_0\} Vnew={m0};
s t e p 4 step4 step4: i f if if 已经没有待扩展的新结点 ( V n e w = ∅ ) (V_{new}=\emptyset) (Vnew=∅),则输出可达图 G G G,并退出算法;
e l s e else else,从 V n e w V_{new} Vnew中任意选择一个新结点 m m m,并将 m m m从 V n e w V_{new} Vnew中删除;
s t e p 5 step5 step5:令 T e = { ∀ t ∈ T ∣ m ≥ C − ( : , t ) } T_e=\{\ \forall t \in T \ |m\geq C^-(:,t)\ \} Te={ ∀t∈T ∣m≥C−(:,t) } ;
s t e p 6 step6 step6:从 T e T_e Te中任意选择一个变迁 t t t,并将其从 T e T_e Te中删除;
s t e p 7 step7 step7: m ′ = m + C + ( : , t ) − C − ( : , t ) m^{'} = m + C^+(:,t) - C^-(:,t) m′=m+C+(:,t)−C−(:,t) ;
s t e p 8 step8 step8: i f if if m ′ m^{'} m′还没出现过 ( m ′ ∉ V ) (m^{'}\notin V) (m′∈/V),则 V = V ∪ { m ′ } V=V\cup \{m^{'}\} V=V∪{m′}, E = E ∪ { ( m , m ′ ) } E=E\cup \{(m,m^{'})\} E=E∪{(m,m′)}, W { ( m , m ′ ) } = t W\{(m,m^{'})\}=t W{(m,m′)}=t,并将 m ′ m^{'} m′放入 V n e w V_{new} Vnew中;
e l s e else else, E = E ∪ { ( m , m ′ ) } E=E\cup \{(m,m^{'})\} E=E∪{(m,m′)}, W { ( m , m ′ ) } = t W\{(m,m^{'})\}=t W{(m,m′)}=t;
s t e p 9 step9 step9: i f if if T e = ∅ T_e = \emptyset Te=∅,返回 s t e p 4 step4 step4;
e l s e else else T e ≠ ∅ T_e \neq \emptyset Te=∅,返回 s t e p 6 step6 step6。
3.2 可达图matlab代码实现
注:以下两个文本文档为前置后置关联矩阵,自己创一个.txt即可
C_minus.txt
2 0 1 0 0 0 0 0 0 0
1 0 0 0 0 0 0 1 1 0
0 2 1 0 1 0 0 0 0 0
0 0 0 2 0 1 0 0 1 0
0 2 0 0 0 0 2 1 0 1
C_plus.txt
0 0 1 0 0 0 2 0 1 0
2 0 0 0 2 0 0 0 1 0
0 1 0 0 0 0 0 1 0 0
0 0 0 2 1 0 2 0 1 0
0 0 0 1 0 2 0 0 0 1
%% step1~3: Initial
clear all;
clc;
C_minus = readmatrix("C_minus.txt");
C_plus = readmatrix("C_plus.txt");
C = C_plus - C_minus
m0 = [4;2;3;1;3];
V = {};
V = [V,m0];
E = {};
W = {};
V_new = {m0};
Te = {};
symbol = 0;
origin = {};
destination = {};
weight = {};
%% main circulate
while true
if symbol==0
% step4: Exit or select random node
[exit,m,V_new] = select_node(V_new,V,E,W,origin,destination,weight);
if exit==1
break;
end
Te = crate_Te(Te,m,C_minus); % step5: Create Te
if isempty(Te)
else
[t,Te]=select_t(Te); % step6: Select random t from Te
child=transition(C,m,t); % step7: Transition
mask=judge(child,V); % Judge whether 'child' has ever apperaed
% step8: Add to Collection
[V,E,W,V_new,origin,destination,weight]=collection(C,m,child,mask, ...
t,V,E,W,V_new,origin,destination,weight);
symbol = 0;
end
else
[t,Te]=select_t(Te); % step6: Select random t from Te
child=transition(C,m,t); % step7: Transition
mask=judge(child,V); % Judge whether 'child' has ever apperaed
% step8: Add to Collection
[V,E,W,V_new,origin,destination,weight]=collection(C,m,child,mask, ...
t,V,E,W,V_new,origin,destination,weight);
end
% step9: Return and execute the next circulate
if isempty(Te)
symbol = 0;
else
symbol = 1;
end
end
%% step4: Exit or select random node
function [exit,m,V_new]=select_node(V_new,V,E,W,origin,destination,weight)
if isempty(V_new)
V = cell2mat(V);
writematrix(V,'V.txt');
fprintf('V=\n');
disp(V);
fprintf('E=\n');
disp(E);
W = cell2mat(W);
writematrix(W,'W.txt');
fprintf('W=\n');
disp(W);
m = [];
exit = 1;
G = digraph(origin,destination);
figure(1)
plot(G,"EdgeLabel",weight,"LineWidth",1.5,"MarkerSize",6, ...
"ArrowSize",9,"NodeColor",'red','EdgeFontSize',9, ...
'NodeFontSize',10)
figure(2)
plot(G,"EdgeLabel",weight,"LineWidth",1.5,"MarkerSize",6, ...
"ArrowSize",9,"NodeColor",'red','EdgeFontSize',9, ...
'NodeFontSize',10,'Layout','force3')
else
index = randi([1,length(V_new)]);
m = V_new(index);
V_new(index) =[]; % delete m from V_new
exit = 0;
end
end
%% step5: Create Te
function Te=crate_Te(Te,m,C_minus)
sign = 0;
I = eye(10);
m = cell2mat(m);
while true
sign=sign+1;
if sign>10 || length(find( m-C_minus(:,sign) <0))~=0
break;
else
temp = {I(:,sign)};
Te = [Te,temp];
end
end
end
%% step6: Select random t from Te
function [t,Te]=select_t(Te)
if isempty(Te)
return
else
sign = randi(length(Te));
t = Te(sign);
Te(sign) =[]; % delete t from Te
end
end
%% step7: Transition
function child=transition(C,m,t)
t = cell2mat(t);
m = cell2mat(m);
child = m + C*t;
end
%% Judge whether 'child' has ever apperaed
function mask=judge(child,V)
child_cell = {child};
mask = 0;
for i=1:length(V)
if ~isequal(child_cell,V(1,i))
else
mask = i; % appera,record
break;
end
end
end
%% step8: Add to Collection
function [V,E,W,V_new,origin,destination,weight]=collection(C,m,child,mask, ...
t,V,E,W,V_new,origin,destination,weight)
m = cell2mat(m);
t = cell2mat(t);
temp = sprintf('m%d',length(V));
origin = [origin,temp];
if mask==0
arc = [m,child];
V = [V,child];
temp = sprintf('m%d',length(V));
destination = [destination,temp];
E = [E,arc];
W = [W,C*t];
temp = sprintf('t%d',length(W));
weight = [weight,temp];
V_new = [V_new,child];
else
child = V(1,mask);
child = cell2mat(child);
arc = [m,child];
temp = sprintf('m%d',mask);
destination = [destination,temp];
E = [E,arc];
W = [W,C*t];
temp = sprintf('t%d',length(W));
weight = [weight,temp];
end
end
3.3 Petri网可达图执行结果
输出可达图如下所示:
输出三维力导向图如下:
窗口输出V, E, W 如下所示:
4. 赋时Petri网
4.1 赋时Petri网模型
所谓赋时Petri网就是在普通Petri网的基础上加入了时间因素,需要引入
d
k
,
x
k
,
λ
k
d_k,x_k,\lambda_k
dk,xk,λk 这几个时间变量
{
G
=
(
N
,
d
,
m
0
)
X
k
=
m
k
,
v
k
,
g
k
\begin{cases} \:G=(N,d,m_0)\\ \:X_k=m_k,v_k,g_k\\ \end{cases}
{G=(N,d,m0)Xk=mk,vk,gk
其中,
{
N
是一个
P
t
r
i
网结构
d
是时延
m
0
是初始标识
m
k
是经过
k
次变迁激发到达的标识
v
k
是
t
o
k
e
n
在库所中已经等待的时间
g
k
是
P
e
t
r
i
网到达
x
k
时已经等待的时间
\begin{cases} \:N是一个Ptri网结构\\\:d是时延\\\:m_0是初始标识\\\:m_k是经过k次变迁激发到达的标识\\\:v_k是token在库所中已经等待的时间\\\:g_k是Petri网到达x_k时已经等待的时间\end{cases}
⎩
⎨
⎧N是一个Ptri网结构d是时延m0是初始标识mk是经过k次变迁激发到达的标识vk是token在库所中已经等待的时间gk是Petri网到达xk时已经等待的时间
激发条件:
{
m
k
−
C
−
(
:
,
e
k
)
>
0
v
k
(
p
)
≥
d
(
p
)
\begin{cases} \:m_k-C^-(:,e_k)>0\\ \:v_k(p)\geq d(p)\\ \end{cases}
{mk−C−(:,ek)>0vk(p)≥d(p)
定义:
λ k \lambda_k λk表示第 k k k次和第 k + 1 k+1 k+1次变迁之间的时间间隔
定理:
对于
G
=
(
N
,
d
,
m
0
)
G=(N,d,m_0)
G=(N,d,m0),对处于第
k
k
k个激发时刻的状态
X
k
X_k
Xk,
λ
k
+
1
\lambda_{k+1}
λk+1表示第
k
+
1
k+1
k+1个变迁还需等待的时间,那么:
{
m
k
≥
C
−
(
:
,
e
k
+
1
)
λ
=
m
a
x
(
d
(
p
)
−
v
k
(
p
)
)
m
k
+
1
=
m
k
+
C
(
:
,
e
k
+
1
)
v
k
+
1
=
v
k
−
d
i
a
g
(
v
k
)
⋅
C
−
(
:
,
e
k
+
1
)
+
λ
k
+
1
⋅
(
m
k
+
1
−
C
+
(
:
,
e
k
+
1
)
)
g
k
+
1
=
g
k
+
λ
k
+
1
\begin{cases} \ m_k\geq C^-(:,e_{k+1})\\ \ \lambda = max(\ d(p)-v_k(p)\ )\\ \ m_{k+1} = m_k+C(:,e_{k+1})\\ \ v_{k+1} = v_k - diag(v_k)\cdot C^-(:,e_{k+1}) + \lambda_{k+1}\cdot (m_{k+1} - C^+(:,e_{k+1}))\\ \ g_{k+1} = g_k + \lambda_{k+1}\\ \end{cases}
⎩
⎨
⎧ mk≥C−(:,ek+1) λ=max( d(p)−vk(p) ) mk+1=mk+C(:,ek+1) vk+1=vk−diag(vk)⋅C−(:,ek+1)+λk+1⋅(mk+1−C+(:,ek+1)) gk+1=gk+λk+1
4.2 赋时Petri网可达图算法
输入: C − , C , d , m 0 , m g C^-,\ C,\ d,\ m_0,\ m_g C−, C, d, m0, mg
**输出:**赋时 P e t r i Petri Petri网可达图
步骤如下:
(1)初始化 X 0 = ( m 0 , v 0 , g 0 ) X_0=(m_0,v_0,g_0) X0=(m0,v0,g0),其中 m 0 m_0 m0作为初始标识, v 0 = 0 v_0=0 v0=0, λ 0 = 0 \lambda_0=0 λ0=0, g 0 = 0 g_0=0 g0=0;
(2)将初始状态 X 0 = ( m 0 , v 0 , g 0 ) X_0=(m_0,v_0,g_0) X0=(m0,v0,g0)作为可达树的根结点,并标记为 n e w new new;
(3)如果 m 0 = m g m_0=m_g m0=mg,将 X 0 X_0 X0标记为 g a o l gaol gaol,算法退出,否则继续执行下一步;
(4)从可达树中任意选择一个 n e w new new结点,表示为 X k = ( m k , v k , g k ) X_k=(m_k,v_k,g_k) Xk=(mk,vk,gk),并将该结点标记为 o l d old old
(5)计算 X k X_k Xk状态下使能的变迁集合 E k = { t ∈ T ∣ m k ≥ C − ( : , t ) } E_k=\{t\in T \ |\ m_k \geq C^-(:,t) \} Ek={t∈T ∣ mk≥C−(:,t)};
(6) f o r a l l e k ∈ E k , d o for\ \ all\ \ e_k\in E_k\ ,\ \ do for all ek∈Ek , do
(7) 激发 e k e_k ek,产生新状态 X k + 1 X_{k+1} Xk+1,根据公式分别计算 λ k + 1 , m k + 1 , v k + 1 和 g k + 1 \lambda_{k+1},\ m_{k+1},\ v_{k+1}和g_{k+1} λk+1, mk+1, vk+1和gk+1;
(8) 如果 X k + 1 X_{k+1} Xk+1是新状态,在可达树中添加一个表示 X k + 1 X_{k+1} Xk+1的结点;
(9) 画一条从 X k X_k Xk指向 X k + 1 X_{k+1} Xk+1的弧,弧上标记激发变迁 e k e_k ek;
(10) 如果 m k + 1 = m g m_{k+1}=m_g mk+1=mg,将 X k + 1 X_{k+1} Xk+1对应的结点记为 g o a l goal goal,否则记为 n e w new new;
(11) e n d end end
(12)如果可达树中存在 n e w new new结点,那么返回第4步。
4.3 赋时Petri网实例
4.3.1 设计赋时Petri网结构
改进了课堂上的赋时 P e t r i Petri Petri网例子,如下图所示
为使
P
2
P2
P2不会一直积累,
c
o
n
s
t
r
a
i
n
t
constraint
constraint:
P
2
≤
1
P_2\leq1
P2≤1
i
n
t
r
o
d
u
c
e
C
,
s
o
h
a
v
e
introduce\ C ,\ so\ have
introduce C, so have
P
2
+
C
=
1
w
h
i
c
h
0
∗
P
0
+
0
∗
P
1
+
1
∗
P
2
+
0
∗
P
3
+
0
∗
P
4
+
0
∗
P
5
+
0
∗
P
6
+
C
=
b
w
=
[
0
0
1
0
0
0
0
]
(
w
是
P
0
∼
P
6
的系数
)
w
ˉ
=
w
∗
C
=
[
0
0
1
0
0
0
0
]
∗
[
−
1
1
0
−
1
1
0
−
1
0
1
0
0
0
1
−
1
0
1
−
1
0
0
1
0
]
=
[
−
1
0
1
]
m
0
(
c
)
=
b
−
w
∗
m
0
=
1
−
[
0
0
1
0
0
0
0
]
∗
[
0
0
0
1
1
1
0
]
=
1
−
0
=
1
P_2 + C =1\\ which\quad 0*P_0+0*P_1+1*P_2+0*P_3+0*P_4+0*P_5+0*P_6+C\ =\ b \\ w = \left[ \begin{matrix} 0 & 0 & 1 & 0 & 0 & 0 & 0 \end{matrix} \right]\quad(\ w\ 是P_0\sim P_6的系数)\\ \bar{w} = w*C = \left[ \begin{matrix} 0 & 0 & 1 & 0 & 0 & 0 & 0 \end{matrix} \right]*\left[ \begin{matrix} -1 & 1 & 0 \\ -1 & 1 & 0 \\ -1 & 0 & 1 \\ 0 & 0 & 0 \\ 1 & -1 & 0 \\ 1 & -1 & 0 \\ 0 & 1 & 0 \\ \end{matrix} \right] =\left[ \begin{matrix} -1 & 0 & 1 \end{matrix} \right] \\ m_0(c) = b - w*m_0 = 1 - \left[ \begin{matrix} 0 & 0 & 1 & 0 & 0 & 0 & 0 \end{matrix} \right]*\left[ \begin{matrix} 0 \\ 0 \\ 0 \\ 1 \\ 1 \\ 1 \\ 0 \end{matrix} \right] =1-0=1\\
P2+C=1which0∗P0+0∗P1+1∗P2+0∗P3+0∗P4+0∗P5+0∗P6+C = bw=[0010000]( w 是P0∼P6的系数)wˉ=w∗C=[0010000]∗
−1−1−101101100−1−110010000
=[−101]m0(c)=b−w∗m0=1−[0010000]∗
0001110
=1−0=1
因此, C C C的库所初始值为1,在变迁中, C C C从 T 0 T_0 T0获得1个 t o k e n token token,从 T 1 T_1 T1获得0个 t o k e n token token,并给 T 2 T_2 T2赋予1个 t o k e n token token
4.3.2 赋时Petri网可达树matlab代码实现
注:以下两个文本文档为前置后置关联矩阵,自己创一个.txt即可
C_minus.txt
1 0 0
1 0 0
1 0 0
0 0 1
0 1 0
0 1 0
0 0 0
0 0 1
C_plus.txt
0 1 0
0 1 0
0 0 1
0 0 1
1 0 0
1 0 0
0 1 0
1 0 0
%% Time_given_Petri.m
clear;clc;
C_minus = readmatrix("C_minus.txt");
C_plus = readmatrix("C_plus.txt");
C = C_plus - C_minus;
d = [10 8 0 12 10 8 0 0]';
mg = [1 1 0 1 0 0 6 1]';
%% Step1~2: Initial
X0 = state_X;
Ek = {};
V = [X0];
V_new = [X0];
origin = {};
destination = {};
weight = {};
%% Step3: Judge whether X0 is goal
if isequal(X0.m,mg)
X0.goal = true; % mark X0 as goal, algorithm exit
origin = [origin,'X0 is goal'];
destination = [destination,'X0 is goal'];
else
while ~isempty(V_new)
%% Step4: Random select a node from V_new as Xk
index = randi([1,length(V_new)]);
Xk = V_new(index);
V_new(index) = []; % delete Xk from V_new
% V = [V,Xk]; % set Xk -> old
for j = 1:length(V)
if isequal(V(j).m,Xk.m) % if Xk_plus has ever appear
father_index = j; break;
end
end
%% Step5: Calculate Transfer_Collection
[Xk,Ek] = Transfer_Collection(Xk,C_minus);
%% Step6
for i = 1:length(Ek)
%% Step7: Calculate lamda, m, v, g of Xk_plus
ek = Ek(i);
Xk_plus = state_X;
Xk_plus.m = Xk.m + C(:,ek);
Xk_plus.lamda = max(d(C_minus(:,ek)~=0)-Xk.v(C_minus(:,ek)~=0));
Xk_plus.v = Xk.v-diag(Xk.v)*C_minus(:,ek)+Xk_plus.lamda*(Xk_plus.m-C_plus(:,ek));
Xk_plus.g = Xk.g + Xk_plus.lamda;
%% Step8: append Xk_plus
sign = 1; % default Xk_plus is new
for j = 1:length(V)
if isequal(V(j).m,Xk_plus.m) % if Xk_plus has ever appear
sign = 0; break;
end
end
if sign==1 % if Xk_plus is new, append to V
%% Step9: Digraph
temp = sprintf('X%d',father_index-1);
origin = [origin,temp];
V = [V,Xk_plus];
temp = sprintf('X%d',length(V)-1);
destination = [destination,temp];
temp = sprintf('t%d',ek-1);
weight = [weight,temp];
end
%% Step10: If Vk_plus.m==mg, mark -> goal, else -> new
if isequal(Xk_plus.m,mg)
Xk_plus.goal = true;
temp = sprintf('X%d is goal',length(V)-1);
destination(end) = {temp};
break;
else
V_new = [V_new,Xk_plus];
end
end
end
end
G = digraph(origin,destination);
figure(1)
plot(G,"EdgeLabel",weight,"LineWidth",1.6,"MarkerSize",6,"ArrowSize", ...
11,"NodeColor",'red','EdgeFontSize',9,'NodeFontSize',10, ...
'ArrowPosition',0.9,'EdgeLabelColor','blue');
figure(2)
plot(G,"EdgeLabel",weight,"LineWidth",1.6,"MarkerSize",6,"ArrowSize", ...
11,"NodeColor",'red','EdgeFontSize',9,'NodeFontSize',10, ...
'Layout','force3','ArrowPosition',0.9,'EdgeLabelColor','blue');
%% state_X.m
classdef state_X
properties
m = [0 0 0 1 1 1 0 1]'; % initial m0, v0, g, lamda
v = [0 0 0 0 0 0 0 0]';
g = 0;
lamda = 0;
goal = false;
end
methods
function [object,Ek] = Transfer_Collection(object,C_minus)
Ek = [];
for t=1:length(C_minus(1,:))
if all(object.m>=C_minus(:,t))
Ek = [Ek,t];
end
end
end
end
end
4.3.3 赋时Petri网可达树执行结果
notes:由于程序中设定随机选择 V n e w V_{new} Vnew中的结点扩展,因此程序每次运行的结果不一定相同。
输出可达树如下所示:
输出三维力导向图如下:
5. 有色Petri网
5.1 颜色集
C = { g , w , b , . . . } C=\{g,w,b,...\} C={g,w,b,...}
t o k e n token token上的颜色集: C t o k e n ⟹ C t k n C_{token} \Longrightarrow C_{tkn} Ctoken⟹Ctkn
变迁上的颜色集: C t r a n s i t i o n ⟹ C t r s C_{transition} \Longrightarrow C_{trs} Ctransition⟹Ctrs
C ^ t k n \hat C_{tkn} C^tkn:由 C t k n C_{tkn} Ctkn中元素组成的多重集的集合;
m : P → C ^ t k n m:P\rightarrow\ \hat C_{tkn} m:P→ C^tkn
5.2 有色Petri网(普通Petri网的折叠)
有色Petri网就是在Petri网的基础上引入颜色的概念,对同类的个体赋予相同的颜色,不同类的个体以不同的颜色加以区分。另外token也增加了颜色,可以描述对象的属性信息,在弧上和变迁上存在着条件表达式和函数,说明弧的权值和颜色属性以及变迁触发的约束条件。
有色Petri网用七元组来表示,即$CPN={{P,T,E,C_{tkn},C_{trs},m_0,W_{arc}} } $
(1) P P P : 库所的有限集合, P = { p 1 , p 2 , . . . , p m } P={\{p_1,p_2,...,p_m}\} P={p1,p2,...,pm};
(2) T T T : 变迁的有限集合, T = { t 1 , t 2 , . . . , t n } T={\{t_1,t_2,...,t_n}\} T={t1,t2,...,tn};
(3) W a r c W_{arc} Warc : 弧的有限集合,满足$P\cap T=P\cap W_{arc}=T\cap W_{arc}=\varnothing $;
(4) C t k n C_{tkn} Ctkn : 每个库所对应的颜色集合
(5) C t r s C_{trs} Ctrs : 每个变迁对应的颜色集合
(6) m 0 m_0 m0 : P → C ^ t k n P\rightarrow \widehat C_{tkn} P→C tkn (由 C t k n C_{tkn} Ctkn 中的每个元素组成的多重集合)
5.3 激发规则与更新规则
∀ C ∈ C t r s , t ∈ T \forall C \in C_{trs} , t \in T ∀C∈Ctrs,t∈T , m k ≥ C c − ( : , t ) m_k\geq C_c^-(:,t) mk≥Cc−(:,t) ,则该颜色对应的变迁可激发
m k + 1 = m k + C c ( : , t ) m_{k+1}=m_k+C_c (:,t) mk+1=mk+Cc(:,t)
5.4 可覆盖树算法
输入:前置关联矩阵C − ^- −,后置关联矩阵C + ^+ +,初始标识 m 0 m_0 m0
(1)绘制根结点记为 m 0 m_0 m0,并将之标记为新结点 n e w new new;
(2)判断可覆盖树中是否含有 n e w new new结点:如果没有,将可覆盖树输出,判断终止,算法结束;反之,执行3;
(3)在 n e w new new结点中任意选择一个 m m m;
(4) f o r a l l t ∈ T for \ all\ \ t\in T for all t∈T
(5) i f if if $ \ m\geq$ C − ( : , t ) C^-(:,t) C−(:,t), t h e n then then
(6) 进行m的更新 m k + 1 = m k + C ( : , t ) = m k + C ⋅ e → m_{k+1}=m_k+C(:,t)=m_k+C\cdot \overrightarrow{e} mk+1=mk+C(:,t)=mk+C⋅e
(7) 如果树中存在一个标识 m ‘ m^` m‘
KaTeX parse error: Undefined control sequence: \and at position 16: m^`\geq m^{``} \̲a̲n̲d̲(\ \exists \ p\…
(8) ∀ p ∈ P , m ‘ ( p ) > m ‘ ‘ ( p ) , m ‘ ( p ) = ω \forall p\in P,m^`(p)>m^{``}(p),m^`(p)=\omega ∀p∈P,m‘(p)>m‘‘(p),m‘(p)=ω
(9) 遍历树,判断 m ‘ m^` m‘是否为旧结点,标记为 o l d old old,反之,标记为新结点 n e w new new
(10) e n d i f endif endif
(11) e n d f o r endfor endfor
(12)返回第2步
致歉
由于课业繁多,且离散系统优化调度不是本人研究方向,因此止步于皮毛,仅供参考。