Petri Net入门

前段时间有朋友问了关于Petri Nets相关的程序问题,就花了点时间学习了下,因此本文是Petri Nets自学入门过程中的总结。因为当时只关注程序设计上的问题,所以是比较基础的内容,不会涉及到数学和程序上的内容。

看懂Petri Nets

图1

先解释下这个图中的元素:

  • Place(P):蓝色的圆
  • Transition(T):黄色的方形
  • Arc(A):红色的连线
  • Weight(W):Arc上的数字,如果没有写,则为1
  • Token:紫色的圆

其中Arc只能连接PlaceTransition,也就是下面这种情况是不允许的:

Token只存在Place中,理论上来说一个Place中可以存储的Token是没有上限的(当然也可以根据需求做限制)。

Transtion的入口所有Place都满足条件(即Place种的Token数量不少于Weight),以及出口的所有Place都满足条件(即Place种的Token数量加上Weight的数量不能超过Place本身允许的Token数量上限),那么称这种情况为Fireable。当满足Fireable时,就可以进行FireFire就是从Transition的入口所有Place移除对应Weight数量的Token,同时在Transition的出口Place中添加对应Weight数量的Token

以例图来说:
T1Fire条件是P1中至少有1个Token,因此Fire之后:

T2Fire的条件是P2中至少有2个Token,但现在P2中只有1个,因此不能Fire。而T1Fire条件仍然满足,因此T1执行Fire之后:

此时T2Fire条件已经满足,因此T2执行Fire之后,会生产2个Token

另一个例子

可以看到T1Fire条件是满足的,FireT1会生产1个TokenP2

此时P2有2种选择,因为T2T3都是Fireable(当有多个Transition都是可以Fire时,可以使用不同的策略),假设选择T3,那么T3会生产1个TokenP1,同时生产1个TokenP3

死锁

Petri Net中没有可以FireTransition时,这时就进入了死锁,因此设计Petri Net的时候需要尽量避免这种情况,比如这种情况:

最终会变成没有任何一个Transition可以进行Fire

画一个生产者消费者模型

最简单的一个生产者消费者模型:

  • 生产的条件:允许生产

  • 消费的条件:允许消费并且生产完成

同时T(生产行为)的下一步就是P(产品生产完成),而T(准备消费产品)的下一步就是P(消费产品),而消费产品后就可以重新消费,同时可以重新开始生产:

最后就是初始的触发条件了,需要能够让状态动起来,可以看到需要在P(可以生产)P(可以消费)各自放入一个Token::

代码实现

一个基于javaPetri Net实现:https://github.com/iyichen/petri-net