摘要
本文介绍了一种新的建模系统--Simio,该系统旨在通过促进建模范式从面向过程向面向对象的转变来简化模型的建立。Simio 是一个基于智能对象的仿真建模框架。智能对象由建模人员构建,然后可在多个建模项目中重复使用。尽管 Simio 框架侧重于基于对象的建模,但它也支持多种建模范式的无缝使用,包括基于事件、流程、对象和代理的建模。
1.建模范例
在离散事件仿真的早期,主流建模范式是由 Simscript(Markowitz 等,1962 年)和 GASP(Pritsker,1967 年)等工具实现的事件导向。在这种建模范式中,系统被视为一系列改变系统状态的瞬时事件。建模者定义系统中的事件,并对这些事件发生时的状态变化进行建模。这种建模方法非常灵活高效,但也是一种相对抽象的系统表示法。因此,很多人认为使用事件导向建模很困难。
80 年代,过程导向取代了事件导向,成为离散事件仿真的主流方法。在流程视图中,我们将被动实体在系统中的运动描述为流程。过程流由一系列过程步骤(如 "捕获"、"延迟"、"释放")来描述,这些步骤模拟了系统中发生的状态变化。这种方法可以追溯到 20 世纪 60 年代的 GPSS(Gordon,1960 年),它为描述系统提供了一种更自然的方法。然而,由于最初的 GPSS 存在许多实际问题(如整数时钟和执行速度慢),直到 GPSS 的改进版本(Henriksen,76)以及 SLAM(Pegden/Pritsker,79)和 SIMAN(Pegden,82)等更新的过程语言在 80 年代得到广泛应用后,GPSS 才成为主流方法。在 80 和 90 年代,图形建模和动画也成为仿真建模工具的主要功能。图形建模简化了建立过程模型的过程,而图形动画则极大地改进了仿真结果的查看和验证。微软视窗系统的引入使建立更好的图形用户界面成为可能,并出现了许多基于图形的新工具(如 ProModel 和 Witness)。
这一时期出现的另一个概念性进步是引入了支持特定领域流程库概念的分层流程建模工具。其基本概念是允许用户通过组合现有流程步骤来创建新的流程步骤。广泛使用的 Arena 建模系统(Pegden/Davis,1992 年)就是这种功能的一个很好的例子。
自从广泛转向基于图形的流程导向以来,工具得到了改进和完善,但基础框架却没有真正的进步。绝大多数离散事件模型仍然使用过去 25 年来广泛使用的过程导向来建立。
尽管过程导向在实践中被证明是非常有效的,但对象导向提供了一种有吸引力的替代建模范式,它有可能更自然、更易于使用。在面向对象中,我们通过描述构成系统的对象来为系统建模。例如,我们通过描述组成系统的工人、机器、传送带、机器人和其他对象来对工厂进行建模。系统行为产生于这些对象之间的相互作用。
尽管已经推出了许多支持面向对象的产品,但迄今为止,许多从业人员仍然坚持使用面向过程的方法。其中一个重要原因是,虽然底层建模范例可能更简单、更不抽象,但具体实现可能难以学习和使用(例如需要编程),或者执行速度较慢。这与流程导向在取代事件导向时所面临的挑战并无二致。尽管第一个流程建模工具(GPSS)早在 1961 年就已问世,但 25 年后,流程导向才发展到说服从业人员进行范式转换的地步。本文介绍的 Simio 是一种新的仿真建模工具,旨在使面向对象更易于使用和高效执行。尽管 Simio 在实现这一目标的过程中融入了许多创新功能,但只有时间才能证明该工具是否解决了许多实际问题,而这些问题必须得到解决,才能引发从业人员构建模型方式的广泛范式转变。
该工具从设计之初就支持对象建模范式,但也支持多种建模范式的无缝使用,包括流程导向和事件导向。它还完全支持离散和连续系统,以及基于代理建模的大规模应用。这些建模范式可以在一个模型中自由混合。
2.Simio 对象范式
Simio 是一个基于智能对象的仿真建模框架。智能对象由建模者创建,然后可在多个建模项目中重复使用。对象可以存储在库中,易于共享。初学建模者可能更喜欢使用库中的预建对象,但系统的设计使初学建模者也能轻松创建自己的智能对象,用于构建分层模型。
对象可以是机器、机器人、飞机、顾客、医生、坦克、公共汽车、轮船或任何其他在系统中可能遇到的事物。模型是由代表系统物理组件的对象组合而成的。Simio 模型看起来就像真实系统。模型的逻辑和动画都是一步完成的。
对象可以通过三维动画来反映对象的变化状态。例如,叉车升起和降低其升降机,机器人打开和关闭其抓手,战车转动其炮塔。动画模型提供了系统运行的动态画面。
对象是利用面向对象的概念建立的。但与其他面向对象的模拟系统不同的是,建立对象的过程非常简单,而且完全是图形化的。无需编写程序代码来创建新对象。
在 Simio 中创建对象的活动与创建模型的活动完全相同--事实上,对象与模型之间没有任何区别。这一概念被称为等价原则,是 Simio 设计的核心。无论何时建立一个模型,根据定义,它都是一个可以实例化为另一个模型的对象。例如,如果将两台机器和一个机器人组合成一个工作单元模型,那么工作单元模型本身就是一个对象,可以任意实例化到其他模型中。工作单元是一个对象,就像机器和机器人是对象一样。在 Simio 中,无法将建立模型的概念与建立对象的概念分开。在 Simio 中建立的每个模型都自动成为一个构件,可用于建立更高层次的模型。
3.面向对象的基础
许多流行的编程语言,如 C++、C# 和 Java,都是围绕面向对象编程(OOP)的基本原理构建的。在这种编程范式中,软件是由一个个从类中实例化出来的合作对象集合构建而成的。这些类的设计采用了抽象、封装、多态、继承和组合等核心原则。
抽象原则可以概括为关注本质。其基本原则是尽可能简化类的结构。
封装原则规定只有对象才能改变其状态。封装将对象类的实现与外界隔绝开来。
多态性为触发对象动作的消息提供了一致的方法。每个对象类都可以决定如何响应特定的消息。
继承是一个关键概念,它允许从现有对象类派生出新的对象类:这有时被称为 "is-a "关系。这也被称为子类化,因为我们正在创建一个更专业的对象类。子类通常允许用新的逻辑扩展对象行为,也允许通过覆盖某些现有逻辑来修改对象行为。
通过组合现有的对象类,可以创建新的对象类:这有时被称为 "has-a "关系。对象成为创建更高级对象的构件。
有趣的是,这些想法的根源可以追溯到 20 世纪 60 年代初的 Simula 67 仿真建模工具。该建模工具由奥斯陆挪威计算中心的克里斯汀-尼加德和奥勒-约翰-达尔(1962 年)创建,用于模拟船舶的行为。他们引入了创建对象类的基本概念,这些对象类拥有自己的数据和行为,并可实例化为其他对象。这就是分层建模和面向对象编程的诞生。
许多人认为面向对象编程概念是在编程领域发展起来的,但事实并非如此。这些原则是为建立仿真模型而开发的,然后被编程领域所采用。
尽管仿真领域创造了最初的面向对象概念,但它尚未产生一个被从业人员广泛接受的面向对象建模框架。虽然有很多人试图提供这样一个框架,但最终从业人员大多还是坚持使用他们经过验证的面向过程建模。其中一个重要原因是,过去的大多数尝试都是简单的面向对象编程库,要求用户回到 25 年前,再次用编程语言编码他们的模型和/或对象。
4.Simio 对象框架
Simio 对象框架基于与面向对象编程语言相同的基本原理构建,但这些原理应用于建模框架而非编程框架。例如,设计 C# 的微软开发团队在设计该编程语言时就应用了这些基本原则。虽然 Simio 的设计也遵循这些原则,但其结果并不是编程语言,而是图形建模系统。这一区别对于理解 Simio 的设计非常重要。
Simio 不仅仅是一个用 OOP 语言编程的仿真建模工具(尽管它是用 C# 编程的)。同样,Simio 也不是一套简单的 OOP 语言(如 Java 或 C++)中可用来构建仿真模型的类。Simio 是一个支持仿真模型构建的图形建模框架,其设计围绕基本的面向对象原则。例如,当您在 Simio 中创建 "机器 "等对象时,继承原则允许您创建一个新的机器类,该类继承了 "机器 "的基本行为,但这种行为可以修改(覆盖)和扩展。在编程语言中,我们通过编写方法来扩展或覆盖行为,而在 Simio 中,我们通过添加和覆盖图形定义的流程模型来扩展或覆盖行为。
这种面向对象建模和面向对象编程之间的区别至关重要。在 Simio 中,为系统定义和添加新对象所需的技能是建模技能,而不是编程技能。
5.对象(模型)的剖析
在 Simio 中创建一个模型时,就等于创建了一个对象类,从中可以创建多个实例。这个过程被称为实例化。
将对象实例化到模型中时,您可以指定对象的属性,这些属性将管理该对象特定实例的行为。例如,一台机器的属性可能包括安装、加工和拆卸时间,以及安装过程中所需的材料清单和操作员。对象的创建者决定属性的数量和含义。Simio 中的属性是强类型的,可以表示数值、布尔值、字符串、对象引用、日期和时间等。由于您创建的任何模型都是一个对象,因此您也有机会通过属性对模型进行参数化。
需要注意的是,实例化模型并不等于复制或克隆模型。当一个模型被用作构建其他模型的构件时,它可能会在许多不同的模型中被实例化很多次。模型实例只是对重复使用的模型定义的引用。实例还保存属性值,因为这些属性值对每个实例都是唯一的。但是,所有实例都共享模型逻辑。无论创建了多少个实例,对象的类定义都只有一个,每个实例都会引用这个单一的定义。每个实例都拥有该实例独有的属性,但都会回溯到定义来获取其底层行为。如果定义中的行为发生了改变,那么所有实例都会自动使用这种新行为。
除了属性,对象还有状态。状态也是强类型的,但总是映射到数值。例如,布尔值 true 和 false 映射到 1 和 0,而状态名称的枚举列表则映射到列表中的索引位置(0, 1, ...., N)。状态的变化是对象内部逻辑执行的结果。属性可以看作是对象的输入,而状态可以看作是对象逻辑执行过程中不断变化的输出响应。状态可能代表已完成部件的数量、从枚举状态列表中选择的机器状态、熔炉中加热的钢锭温度、正在灌装的船舶中的油位或传送带上的积油水平。
状态有两种基本类型:离散和连续。离散状态是仅在事件发生时(客户到达、机器故障等)才会改变的值。连续状态(如油箱液位、推车位置等)的值随时间不断变化。
6.三个对象层
Simio 重要而独特的内部设计特点之一是使用三层对象结构,将对象分为对象定义、对象实例和对象实现。对象定义指定了对象的行为,并为对象的所有实例所共享。对象实例只是父对象定义中的一个对象实例(例如,车床实例被置于工作单元定义中)。对象实例定义了每个对象实例的属性值,所有对象实现都共享这些实例数据。
对象实现用于表示扩展模型层次结构中实例的特定实现。例如,每次在父对象定义(如生产线)中放置一个新的工作单元实例时,就需要为嵌入式车床创建一个新的实现。虽然工作单元定义是由单个车床实例建立的,但单个车床实例无法保存与多个车床实现相对应的状态值,而多个车床实现是由多个工作单元实例产生的。对象实现提供了以非常紧凑的形式保存这种分层状态信息的机制。对象实现仅在模型执行过程中创建,并仅保存模型状态变量及其父对象实例的引用。这是一种高效的结构,对于像基于代理的模型(可能有成千上万个对象实现)这样的大规模应用至关重要。
7.构建对象定义的三种方法
在前面的例子中,我们通过组合其他对象(机器和机器人)定义了一个新的对象定义(工作单元),这就是我们如何在 Simio 中创建对象定义的一个例子。这种类型的对象被称为组合对象,因为我们是通过组合两个或多个组件对象来创建对象的。这种对象构建方法是完全分层的,也就是说,一个组合对象可以用作构建更高层次对象的组件对象。这只是 Simio 中创建对象的一种方法,还有另外两种重要方法。
在 Simio 中创建对象的最基本方法是通过定义逻辑过程来改变对象对事件的响应状态。例如,可以通过定义在部件到达、工具故障等事件发生时改变机器状态的过程来创建机器对象。这种类型的建模类似于目前使用的传统建模系统(如 Arena 或 GPSS)中的流程建模。通过描述原始流程定义的对象称为基础对象。
在 Simio 中构建对象的最后一种方法是基于继承概念。在这种情况下,我们通过覆盖(即替换)对象中的一个或多个进程,或添加额外进程来扩展其行为,从而从现有对象创建对象。换句话说,我们从一个几乎是我们想要的对象开始,然后对其进行必要的修改和扩展,使其达到我们的目的。例如,我们可以在通用机器对象的基础上建立一个专门的钻头对象,通过添加额外的流程来处理钻头的故障和更换。以这种方式创建的对象被称为派生对象,因为它是从现有对象中子类化出来的。
无论使用哪种方法创建对象,一旦创建,其使用方式都是完全相同的。一个对象可以多次实例化到模型中。您只需选择感兴趣的对象并将其放入模型(实例化)即可。
8.对象类别
Simio 中有六种基本的对象类别。这六类对象是在 Simio 中创建智能对象的起点。默认情况下,所有这六类对象都没有多少本地智能,但都有能力获得智能。您可以将这些对象的行为建模为一系列事件驱动流程,从而创建这些对象的智能版本。
第一类是固定对象。该对象在模型中具有固定位置,用于表示系统中不会从一个位置移动到另一个位置的事物。固定对象用于表示固定设备,如机器、加油站等。
代理是可以在三维空间中自由移动的物体。代理通常也用于开发基于代理的模型。这种建模视角对于研究由许多独立行动的智能对象组成的系统非常有用,这些智能对象相互影响,从而产生了整个系统的行为。应用实例包括新产品或服务的市场接受度,或环境中竞争物种的数量增长。
实体是代理类的子类,具有一个重要的附加行为。实体可以通过链接和节点网络在系统中的对象间移动。实体的例子包括服务系统中的客户、制造系统中的工件、运输系统中的船只、战斗系统中的坦克,以及医疗服务系统中的医生、护士和病人。
需要注意的是,在传统建模系统(如 GPSS 或 Arena)中,实体是被动的,由模型流程执行。但在 Simio 中,实体可以拥有智能并控制自己的行为。
链接和节点对象用于构建实体可以流动的网络。链接定义了实体在对象间移动的路径。节点定义了链接的起点或终点。链接和节点可以组合成复杂的网络。虽然基本链接没有什么智能,但我们可以添加一些行为,使其能够模拟无约束的流动、拥挤的交通流或复杂的材料处理系统,如积放式输送机或动力和自由系统。
最后一类对象是传送器,它是实体类的子类。运输器是一种具有拾取、搬运和放下一个或多个其他实体的附加功能的实体。默认情况下,运输工具不具有这些行为,但通过在该类中添加模型逻辑,我们可以创建多种运输工具行为。运输器可以模拟出租车、公交车、AGV、地铁车厢、叉车或任何其他能够将其他实体从一个位置运到另一个位置的物体。
Simio 的一个主要特点是能够从这六个基本类中创建各种对象行为。Simio 建模框架是应用领域中立的,也就是说,这六个基本类并非专门针对制造、服务系统、医疗保健、军事等领域。不过,要建立由这六个类中的智能对象组成的、针对特定应用的应用库还是很容易的。例如,建立一个对象(在本例中是一个链接)来表示复杂的积放式输送机,用于制造应用就相对简单。根据 Simio 的设计理念,这种特定领域的逻辑属于用户构建的对象,而不是编入核心系统的程序。
9.利用流程创建智能对象
Simio 中的建模始于基础对象--它是构建更高层次对象的基础。Simio 中的基础对象是一个固定的对象、代理、实体、链接、节点或传输器,它通过一个或多个流程添加了智能。流程通过定义响应事件时执行的逻辑来赋予对象智能。
每个流程都是由事件触发并由令牌执行的流程步骤序列。流程总是以一个单一的开始步骤开始,以一个单一的结束步骤结束。令牌由开始步骤释放,只是一个执行线程(类似于 Arena 中的实体)。令牌可能具有控制流程步骤执行的属性(输入参数)和状态(运行时可更改的值)。您可以定义具有不同属性和状态组合的令牌类。
Simio 的建模能力来自于为六类基本对象自动触发的一系列事件,以及可用于建模响应这些事件所发生的状态变化的流程步骤。要完全掌握构建智能对象的技巧,需要学习事件和可用流程步骤集合,以及如何将这些步骤组合起来以表示复杂逻辑的知识和经验。
Simio 中的每个步骤都是一个简单流程的模型,例如在一定时间内保持标记、扣押/释放资源、等待事件发生、为状态分配新值或在不同的流程路径之间做出决定。有些步骤(如延迟)是通用步骤,可用于对象、链接、实体、传送器、代理和组的建模。其他步骤只对特定对象有用。例如,"拾取 "和 "卸载 "步骤只适用于为运输工具添加智能,而 "接合 "和 "脱离 "步骤只适用于为链接添加智能。
每个对象类都有自己的事件集。例如,当实体进入和离开链接、完全合并到链接上、与链接上的其他实体碰撞或分离、在另一个实体的指定范围内移动等时,链接会触发事件。通过提供响应这些事件的模型逻辑,我们可以完全控制实体在链接上的移动。例如,要在链接上添加累积逻辑,我们只需编写一个小进程,当实体与跟随的实体相撞时触发该进程,并重新分配实体的速度,使其与跟随实体的速度相匹配。
用于定义对象底层逻辑的流程步骤是无状态的,即它们有属性(输入参数),但没有状态(输出响应)。这一点很重要,因为这意味着对象类定义可以保存流程的单个副本,并由任意数量的对象实例共享。如果流程逻辑发生变化,该对象的所有实例都会自动反映这一事实。
对象实例的状态保存在元素中。元素定义了对象的动态组件,既可以有属性(输入参数),也可以有状态(运行时可更改的值)。在一个对象中,令牌可以执行改变对象所拥有的元素状态的步骤。
元素的一个例子就是在对象中定义位置的站。站台还用于定义进出对象的入口和出口。实体可以转入或转出站台(使用 "转移 "步骤),站台维护着当前在站台中的实体队列以及等待转入站台的实体队列。站点的容量限制了转入站点的实体数量。因此,通过链路到达对象的实体,只有在对象入口站有可用容量的情况下,才能离开链路进入对象。
10.有限容量调度
虽然仿真历来被应用于设计问题,但它也可用于为工厂车间生成生产计划。在这种模式下使用时,仿真是一种有限产能调度器(FCS),是优化算法和作业时间排序器等其他有限产能调度方法的替代方法。然而,基于模拟的 FCS 有许多重要优势(如执行速度和灵活的调度逻辑),使其成为调度应用的强大解决方案
仿真为工厂车间生成有限产能计划提供了一种简单而灵活的方法。仿真排产的基本方法是使用工厂的起始状态和计划生产的订单集运行工厂模型。在模型中加入决策规则,以做出工作选择、资源选择和路由决策。仿真通过模拟工厂内的工作流,并根据指定的排产规则做出 "智能 "决策,从而构建排产计划。模拟结果通常显示为加载在交互式甘特图上的作业,用户可对其进行进一步操作。仿真模型中可以应用大量规则来生成不同类型的排程,这些规则主要针对以下措施:最大化吞吐量、保持瓶颈处的高利用率、最小化转换或满足指定的到期日期。
由于调度应用的特殊要求(如需要专门的决策规则,以及需要以交互式甘特图的形式查看结果),基于仿真的调度应用通常采用专门为这一应用领域设计的专用仿真器。这种方法的问题在于,专门的模拟器具有内置的、数据驱动的工厂模型,无法为适应应用而进行更改或变更。在许多情况下,这种内置模型过于简化了生产车间的复杂性。 这种一刀切的方法严重限制了这些工具的应用范围。一些生产流程可以通过这种固定的模型得到充分体现,但许多其他流程却不能。
Simio 采用了不同的方法,允许使用工具的全部通用建模功能来定义工厂模型。因此,应用范围不再受限于固定的内置模型,无法在不同应用之间进行更改或变更。用户建立的 Simio 模型可以完全捕捉到生产流程的复杂性。这不仅包括每个工作中心内的逻辑,还包括在工作中心之间移动作业所需的物料处理。
通过在 Simio 中加入专门支持 FCS 需求的功能,可以满足 FCS 应用的特殊要求。这些功能包括支持外部定义的作业数据集,以及非常灵活的资源和物料建模。虽然这些功能是专门为充分发挥 Simio 在 FCS 应用中的建模能力而设计的,但它们在一般建模应用中也非常有用。
Simio 作业数据集允许从外部定义作业列表,供仿真模型处理。作业定义在包含一个或多个表的数据集中,表列之间定义了关系。保存作业数据的具体模式是任意的,可由用户定义,以与制造数据(如 ERP 系统)的数据模式相匹配。作业数据通常包括发布日期和到期日期、作业路线、设置和处理时间、材料要求以及与相关系统有关的其他属性。Simio 中的对象可以直接引用作业数据集中指定的值(如加工时间),而无需了解用于存储数据的模式。
Simio 中的任何对象都可以充当容纳资源,并拥有自己的独立行为。可以根据灵活的规则(如最短转换时间或最长闲置时间)从列表中选择资源。.资源还支持非常灵活的规则(最早到期日期、最少剩余闲置时间、临界比率等),用于在等待占用资源的竞争作业中进行选择。最后,还可以在交互式甘特图上显示资源的作业使用历史。
Simio 中的 "材料 "元素可直接支持在模型执行过程中消耗和生产的物品建模。还可以分层定义材料,为制造应用中的传统物料清单(BOM)建模。因此,一个制造步骤可以建模为分层 BOM 中特定材料清单的消耗。
11.总结
Simio 是一种基于面向对象建模核心原则的新型建模框架。它在以下方面独树一帜:
- Simio 框架是一个图形化的面向对象建模框架,而不仅仅是面向对象编程语言中用于仿真建模的一组类。Simio 的图形建模框架完全支持面向对象建模的核心原则,无需编程技能即可为系统添加新对象。
- Simio 框架是领域中立的,允许构建支持许多不同应用领域的对象。Simio 的流程建模功能可以创建具有复杂行为的新对象。
- Simio 框架支持多种建模范式。该框架支持离散和连续系统建模,并支持事件、流程、对象和代理建模视图。
- Simio 框架提供了专门的功能,可直接支持仿真和有限容量调度方面的应用,从而充分利用 Simio 的通用建模功能。
参考文献
- Gordon,Geoffrey,1960 年 10 月 25 日。A general purpose systems simulator.(Unpublished manual.) White Plains, N.Y.: IBM.Corp.ASDD Commercial Dept.
- Henriksen, J. O. 1976.建立更好的 GPSS:3:1 增强。In Proceedings of the 1975 Winter Simulation Conference, 465-469.New Jersey:AFIPS Press
- Markowitz, H., Hausner, B., and Karr, H. SIMSCRIPT: A simulation programming language, Prentice Hall, Englewood Cliffs, N. J. 1962.
- Nygaard, K and O-J Dahl, .SIMULA -An Extension of ALGOL to the Description of Discrete-Event Networks(《SIMULA--AN Extension of ALGOL to the Description of Discrete-Event Networks》),在第二届信息处理国际会议上发表(1962 年
- Pegden, C. D. and A. A. B. Pritsker (1979).SLAM: Simulation Language for Alternatives Modeling.模拟》,第 33 卷,第 5 期。
- Pegden, C. D. (1982).SIMAN 简介。系统建模公司。
- Pegden, C. D. and D. A. Davis (1992) Arena: a SIMAN/Cinema-based Hierarchical Modeling System; In Proceedings of the 1975 Winter Simulation Conference 390-399.
- Pritsker, A. A. B. 1967.GASP H User's Manual.亚利桑那州立大学。

