Petri Net入门
前段时间有朋友问了关于Petri Nets相关的程序问题,就花了点时间学习了下,因此本文是Petri Nets自学入门过程中的总结。因为当时只关注程序设计上的问题,所以是比较基础的内容,不会涉及到数学和程序上的内容。
看懂Petri Nets
先解释下这个图中的元素:
- Place(P):蓝色的圆
- Transition(T):黄色的方形
- Arc(A):红色的连线
- Weight(W):Arc上的数字,如果没有写,则为1
- Token:紫色的圆
其中Arc
只能连接Place
和Transition
,也就是下面这种情况是不允许的:
Token
只存在Place
中,理论上来说一个Place
中可以存储的Token
是没有上限的(当然也可以根据需求做限制)。
当Transtion
的入口所有Place
都满足条件(即Place
种的Token
数量不少于Weight
),以及出口的所有Place
都满足条件(即Place
种的Token
数量加上Weight
的数量不能超过Place
本身允许的Token
数量上限),那么称这种情况为Fireable
。当满足Fireable
时,就可以进行Fire
,Fire
就是从Transition
的入口所有Place
移除对应Weight
数量的Token
,同时在Transition
的出口Place
中添加对应Weight
数量的Token
。
以例图来说:T1
的Fire
条件是P1
中至少有1个Token
,因此Fire
之后:
T2
的Fire
的条件是P2
中至少有2个Token
,但现在P2
中只有1个,因此不能Fire
。而T1
的Fire
条件仍然满足,因此T1
执行Fire
之后:
此时T2
的Fire
条件已经满足,因此T2
执行Fire
之后,会生产2个Token
:
另一个例子
可以看到T1
的Fire
条件是满足的,Fire
后T1
会生产1个Token
到P2
:
此时P2
有2种选择,因为T2
和T3
都是Fireable
(当有多个Transition
都是可以Fire
时,可以使用不同的策略),假设选择T3
,那么T3
会生产1个Token
给P1
,同时生产1个Token
给P3
:
死锁
当Petri Net
中没有可以Fire
的Transition
时,这时就进入了死锁,因此设计Petri Net
的时候需要尽量避免这种情况,比如这种情况:
最终会变成没有任何一个Transition
可以进行Fire
:
画一个生产者消费者模型
最简单的一个生产者消费者模型:
生产的条件:允许生产
消费的条件:允许消费并且生产完成
同时T(生产行为)
的下一步就是P(产品生产完成)
,而T(准备消费产品)
的下一步就是P(消费产品)
,而消费产品后就可以重新消费,同时可以重新开始生产:
最后就是初始的触发条件了,需要能够让状态动起来,可以看到需要在P(可以生产)
和 P(可以消费)
各自放入一个Token
::
代码实现
一个基于java
的Petri Net
实现:https://github.com/iyichen/petri-net