Free Essay

Simulation

In: Science

Submitted By baylee
Words 42251
Pages 170
第3章

Arena 概貌

在第二章的 2.4 部分,我们实际上利用 Arena 完成了“手工”仿真过程,而且在 2.6 部 分对该模型和修改后的模型(即到达率加倍)进行了多次重复仿真运行。这一章本书将带你 领略应用 Arena 建模仿真的整个过程,首先教你启动 Arena,浏览为上一章手工仿真建立的 现成模型,并运行该仿真模型,然后学习如何从头开始建立模型。本章也会探讨用户界面问 题,以及如何使用帮助文件系统,并讨论运行仿真的不同方法,同时讲解绘图和图形工具的 用法。 3.1 节介绍如何启动 Arena;3.2 节带你浏览一个现成的模型;在 3.3 节你可以更加详细 地查看这一模型,浏览对话框和动画,运行模型和查看结果;3.4 节帮助你从头开始一步步 建造该模型;3.5 节简要介绍 Arena 的一些主要建模功能,包括菜单和工具条中的可用选项 以及绘图打印功能等;3.6 节介绍 Arena 强大的帮助文件系统以及所有详细的技术文件;3.7 节讨论有关运行和控制仿真的各种选项。 看完本章后,你将会了解 Arena 是如何工作的,并知道用 Arena 可以做些什么,而且你 可以有效地运用 Arena 建立一些简单的模型,甚至可能借助帮助系统,通过自己摸索有关菜 单和对话框完成一些更为复杂的工作。仅通过阅读本章,你也许就能了解不少有用的东西, 但如果能同时在电脑上加以实际操作, 效果会更好。 有关如何建立模型的更多内容将会在第 四章及以后章节讨论。

3.1 启动系统
Arena 是一种真正的微软“视窗”操作系统(Windows)的应用软件,因此用户对它的 外观和风格会比较熟悉, 并且其一般的特征和操作也与 Windows 操作系统一致。 另外, Arena 与其它 Windows 软件全面兼容,例如文字处理软件、电子表格软件和 CAD 软件等,所以用 户可以很容易地在不同软件系统与 Arena 之间来回移动对象(第 10 章将详细介绍 Arena 与 其它软件地交互和通信)。 顺便补充一句,本书假设读者对 Windows 的基本概念和操作都已经熟悉了,例如:  磁盘,文件,文件夹和路径。  鼠标和键盘的使用,包括单击、双击和右击鼠标。

 操作窗口,如移动、调整大小、最大化、最小化和关闭。  对菜单的操作。书中使用如下符号“M > C> S > T”,表示打开菜单M,从中选择C, 然后从子菜单中选择S(如果有的话),最后选择带有标签T的页面(如果有的话)。  Control、Alt和Shift键的使用。“Ctrl+任意键”意味着同时按下Ctrl键和任意键(这一 点同样适用于“Alt+任意键”和“Shift+任意键”)。如果“任意键”是键盘键,则不区分 大小写。“任意键”也可以是鼠标点击,例如“Ctrl+单击”可以拓展某个选择使其包括增 列项目。  对文本和其它项目的剪切 Cut(或者菜单命令 Edit>Cut,或者组合快捷键 Ctrl+X), 复制 Copy(或 Edit>Copy,或 Ctrl+C)和粘贴 Paste(或 Edit>Paste,或 Ctrl+V)。  填写对话框,包括输入和编辑文本条目、按下按钮、选定和清除(即取消选定)选 项框、 从一列选择按钮 (单选按钮) 中单击选中其中一个按钮、 以及从下拉菜单中选择项目。 如果读者对以上提到的操作不熟悉,在阅读下面的内容前最好先要复习一下Windows 操作指南。 下面来到电脑旁,电脑中已按随书附带的说明书安装了 Arena 系统(可以参阅附录 E 来了解如何安装 Arena 教学版,安装程序在随书附带的光盘内),找到 Arena 图标或快捷方 式并双击它(或者启动 Windows,单击开始按钮,在程序菜单中找到 Rockwell Software,进 而找到 Arena 7.0 子菜单,最后在其中找出 Arena 7.01 的图标并单击来启动 Arena),很快 Arena 版权窗口就会出现,如果你运行的是教学版(本书光盘提供的即为该版本)或评估版 的 Arena,你将会看到一个相应的信息框,阅读后请点击确定(OK)(由于 OK 按钮是默认 选项,也可以在键盘上之间点击回车键)。 此时在Arena窗口左上方会出现文件 (File) 视图 、 (View) 工具 、 (Tools) 和帮助 (Help) 菜单(如果一个空的模型文件在Arena启动后被自动打开,则还可以看到其它几个菜单)。 你还可以看到含有不同按钮的工具栏, 不过在打开模型文件之前, 只有如下几个工具栏可用 (处于激活状态): 创建一个新的空模型文件,这个按钮等同于菜单命令 File >New 和键盘操作 Ctrl+N。 显示一个对话框用以打开一个以前保存过的模型,等同于 File >Open 和 Ctrl+O。你 可能需要在其它文件夹或磁盘中去寻找所要打开的模型文件。 模板添加(系统提供了若干模板(Template),每个模板中包含了相应的建模元素),

等同于 File >Template Panel >Attach。这些模板文件(扩展名为.tpo)保存在 Arena 7.0 文件夹下的 Template 文件夹中。 模板断开 (当你不再需要相应的建模元素出现在活动面板里时) 等同于 File >Template , Panel >Detach。 关联帮助按钮,提供关于菜单或者工具栏命令的帮助。单击它鼠标箭头上会增加一个 问号,用带有问号的箭头单击想要得到帮助的工具栏按钮或者菜单命令即可得到相应 的帮助信息,关闭帮助窗口后鼠标指针就会返回原来的单箭头。 工具提示(Tooltips)可以提供另外一种更加快速和简洁的关于工具栏按钮的帮助。将 鼠标停留在某个按钮上面保持一两秒种不动, 就会出现一个小方框显示该按钮的名称。 如果 你想知道那个按钮更多的信息,可以使用 ,也可以在帮助系统中查阅相关信息(因为你

此时已知道了该按钮的名称)。关于帮助功能的更多描述可以参考3.6节。如果你对频繁出 现工具提示感到厌烦,可以通过View>Toolbars菜单打开Toolbars标签项,在其中清除Show Tooltip(显示工具提示)选项。当想从Arena系统退出时,点击右上角的 命令File>Exit,或者按Alt+F4。 ,或者使用菜单

3.2 Arena 的窗口组成
在这一部分,我们将打开一个现成的模型,看看Arena的各种窗口,以便读者熟悉,同 时介绍一些Arena的基本术语。

3.2.1 打开模型文件
已有的模型可以通过 File>Open 菜单命令打开 (或者单击 弹出 “打开文件” 对话框) ,

文件名称会出现在滚动框内,当然你也可以直接搜索其它文件夹或磁盘。找到名为 Model 03-01.doe 的文件(Arena 文件的默认扩展名为.doe1)。当使用典型安装时,该模型文件保存 在 Arena 7.0 文件夹下的 Book Examples 文件夹内。单击文件名选中该文件,并点击 Open 按钮即可(或者双击该文件名)。

1

在早期系统中,Arena 的代号为 Bambi。此处不再详述。

你会看到一个如图3-1所示的Arena窗口(你看到的工具栏和按钮也可能会有些差异,或 所处的位置不同),我们称之为模型3-1。

3.2.2 Arena 窗口的构成和关联
如图3-1所示,该模型所在的Arena窗口可分为几个部分。 在右边占据屏幕大部分的是模型窗口,它实际上位于Arena窗口的内部,如果你同时打 开几个模型,每个模型窗口单独容纳一个模型,但所有窗口都在Arena窗口内,就像文字处 理和电子表格软件一样。 你可以通过点击某个窗口以便在不同窗口之间切换, 或者从Window 菜单的窗口列表里选取。如果有大量模型窗口同时被打开,可以使用Ctrl+Tab键在窗口之间 切换,或者使用“”按钮使部分窗口缩小为图标形式,此外,Window菜单里还有一些其 它命令(层叠、平铺等)来安排打开的模型和被最小化的图标。可使用 File>New或者Ctrl+N)来创建一个空的模型窗口,使用 来保存当前的活动模型窗口,使用 工具按钮(即

按钮(即File>Save或者Ctrl+S)

(即File>Open或者Ctrl+O)来打开以前保存过的模型

窗口,改变窗口大小或重新定位窗口的操作与其它Windows操作系统下的应用软件是一样 的。

原书P52 项目工具栏 工具栏 模型窗口中的流程图视图 状态栏 模型窗口中的电子表格视图

图3-1 简单加工系统(模型3-1)的Arena窗口 我们所熟悉的剪切、 复制和粘帖功能在Arena内部以及Arena和其它应用软件之间均可进 行。例如,你同时打开了几个模型窗口,想把一些对象从其中一个窗口复制到另一个窗口,

可先用鼠标选择对象(可用Ctrl+单击或者拖动鼠标画框来选择多个对象),再复制对象到 剪切板 (Ctrl+C或Edit>Copy) 切换到另一窗口, , 然后将其粘贴进去 (Ctrl+V或Edit>Paste) 。 当选择了“粘贴”操作之后,在选项的西北角鼠标箭头会变成十字线,然后在想要粘帖的位 置点击鼠标即可完成操作。再比如,你同时打开了Arena和工作表,你想要将表中的一个长 数字放到Arena文本对话框中,可首先从工作表单元格中复制该数字,再切换到Arena窗口中 (通过Windows任务栏或使用Alt+Tab键在打开的软件之间切换),在对话框中定位你想要 放数字的插入点,然后粘贴进去。如果你在文字处理系统中写报告,想要粘贴一幅Arena屏 幕的“快照”,则进入Arena窗口,按Prnt Scrn键,然后切换回正在处理的文档,在你想要 的位置粘贴该快照;如果你只想粘贴当前活动的窗口(例如一个对话框),则按住Alt+Prnt Scrn,然后粘贴到你想要的位置。 模型窗口分为两个区域或两种视图:流程图视图(flowchart view)和电子数据表格视图 (spreadsheet view),通常情况下在模型窗口中能够同时看到两种视图是很有用的(但也可 通过在菜单命令View中清除Split Screen选项或者单击 来关闭一个视图,以便让模型窗口

集中显示某个视图。在这种情况下,要想看流程图视图或电子数据表格视图,只需在屏幕左 边的项目栏里单击任何一个流程模块( )或电子数据表格模块( )即可)。流程图

包含了模型的图形符号,有加工流程、动画和其他一些绘图元素。电子数据表格能够显示诸 如时间等参数的模型数据, 允许用户进入和编辑数据。 许多模型参数在两种视图中都可以被 看到并编辑, 但电子数据表格视图使用户能够一次处理更多的参数, 并且相似的参数被集中 存放,对于大模型来说非常便于编辑。当同时显示两种视图时,可通过上下拖动分割两种视 图的水平线,以改变两种视图在模型窗口中的比例。 图3-1中Arena窗口的左下方是项目工具栏(Project Bar),它存放各种面板(panel), 每个面板包含了用户所使用的各种对象。面板一次只能显示一个。当前项目栏显示的是“基 本操作面板(Basic Process Panel)”,它包含了基本建模模块(module),这些模块在仿 真模型中有广泛的用途。在基本加工面板下面的是标有“报告(Report)”的水平按钮,这 个面板可以显示仿真运行后的结果, 可试着点击这个按钮观察该面板, 再次点击基本操作面 板返回。“导航(Navigate)”面板可以使用户从不同角度观察模型,在多层递阶模型中还 可以看不同的子模型(模型3-1没有多层子模型,因此唯一的视角是顶层模型,单击左边的 “+”键,在打开的树状结构中可以看到三个条目,具体将是在3.2.3节讨论)。项目工具栏

通常被放置在窗口左侧,但也可以将其“悬浮”在屏幕的任何位置,当然如果你愿意,也可 以把它放在模型窗口的右侧。当用户在建模时,一般需要显示项目工具栏,然而当需要更大 的空间来查看模型窗口中的事物时,可以按项目工具栏右上角的“”按钮或者在View菜单 中清除Project Bar选项来隐藏工具栏。 Arena中还有其它一些面板 (可能会与版本的授权情况有关) 包括 , “高等操作 (Advanced Process) (用 ” “更小” 的建模操作块来对各种细节建模) “高等运送 , (Advanced Tranfer) ” (包括移动实体的许多选项)、“操作块(Block)”与“构模元素(Element)”(使用户 能充分使用作为Arena基础的仿真语言SIMAN; 参阅文献Pegden Shannon和Sadowski, 1995) 。 还有更多的面板,包括创建特殊的应用系统,例如对工厂、呼叫中心、以及高速包装线建模 等。为了能够在模型中使用使这些面板,需要通过File>Template Panel>Attach或者添加模板 按钮( )把相应的面板装载到模型中去。面板文件的扩展名为.tpo,位于Arena 7.0文件

夹 下 的 Template 文 件 夹 内 。 如 果 你 想 把 特 定 的 面 板 导 入 每 个 新 建 的 模 型 , 可 进 入 Tools>Options>Settings,然后把所需的.tpo文件输入到Auto Attach Panels框内。 在Arena窗口最下面是状态栏,它显示此刻正在进行的有关仿真状态的各种信息。现在 状态栏显示的是鼠标指针在建模空间中的坐标(x, y)(详见3.2.3节);当仿真运行时,显示 的是仿真时间、当前的重复仿真次数、重复仿真的总次数。也可以通过在View菜单中清除 Status Bar选项来隐藏状态栏。

3.2.3 流程图视图一览
在图3-1模型窗口中看到的流程图仅仅是该模型众多可能视图中的一种,这些模型的流 程被描述在一个图形建模空间中,图形建模空间的中心坐标为(0, 0),从中心坐标向四个方 向延伸出1000个单位长度,这些单位只是表示位置的,没有任何特殊的物理意思。点击模型 窗口右上角的按钮,可以最大化窗口尺寸,同样点击Arena系统窗口右上角的,可以最 大化Arena视窗。 为了看流程图的不同部分,可以使用窗口下面和右侧的滚动条或箭头来浏览(试一试, 你也可以先用鼠标激活模型窗口,然后通过上下左右键来浏览),你也可以对视图放大(用 按钮或“+”键或View>Zoom In菜单)或缩小(用 菜单),以便从不同“高度”看模型。点击 按钮或“-”键或View>Zoom Out

按钮(或View>Views>All菜单或用“*”键)

可以自动显示全景,以最可能近的焦距观看整个模型。如果你想返回看以前的视图,可以点



(或View>Previous菜单)。如果你正处在较高的高度上,但想拉近看某块区域以仔细

观察时,可以选择View>Views>Region菜单或点击“[”键,使鼠标指针变为十字线,从长方 形的一个角点开始拉到另一个角点以确定观察区域, 则可以近距离察看 (即在可能的最低的 高度上)该区域内的所有图象。 如果你有一个选好的视图,可以把它保存为命名的视图(Named View) ,同时给它分配 一个热键。首先通过缩放将你想要保存的视图定义好,选择View> Named Views菜单(或点 击“?”键),然后单击Add 键。你需要给这个视图一个描述性的名字,同时也可以选择给 它分配一个热键。通过选择View> Named Views菜单(或点击“?”键),单击想要显示的视 图,然后按Show键。你也可以在项目栏的导航(Navigate)面板里点击左上角的“+”键, 打开所有命名的视图构成的树状结构, 然后点击所要的视图条目。 最快的方式就是点击分配 给那个视图的热键来显示该视图, 不过你必须记住这些热键, 也可以用文本的形式记录在模 型上(参看3.5.3部分),命名的视图热键是Arena软件中少数几个区分大小写的地方(例如, “a”和“A”是不同的)。命名的视图在任何时候都可以访问,甚至在仿真运行过程中。 对于模型3-1已经建立了三个命名的视图:整个视图(热键a)、逻辑视图(热键l)和散点 图视图(热键p)。 打开新模型时,它会以特定的初始视图出现,一般位于图形建模空间原点(0, 0)位置的 东南部,可以在键盘按Home键(或View>Views>Home菜单)返回原来位置。为了看到图形 建模空间最大可能的面积(从最大的高度看),选择View>Views>Max菜单。 为了目测方位,可以通过View>Grid菜单(或点击 )显示有小点组成的背景网格,如 )。这两种

果你想进一步使新近放进去的对象对齐网格,可以选择View>Snap(或点击

操作键都是开关键, 也就是说你可以通过重复点击来取消操作。 为了使已有的对象对齐网格, 首先选择对象,然后单击 调整对象的位置与网格点对齐。为自定义网格点间隔,选择

View>Grid Settings菜单,对话框内的数值以图形建模空间的度量单位为标准。

3.2.4 模块
Arena模型的基本构件叫做模块(module),可利用这些模块定义仿真流程和数据,它 们存放在项目栏中的各种面板里,基本上可分为流程模块(flowchart module)和数据模块 (data module)两类。

流程模块在模型中描述了动态过程, 你可以把流程模块看成实体流经的结点或者模型起 止的过程。 要把一定类型的流程模块放到模型中去, 可以从项目栏里选取该模块并拖到流程 图窗口里 (当然在窗口里也可以拖动模块重新定位) 在某种情况下流程模块是相互关联的。 。 在基本操作面板中,可用的流程模块有创建(Create)、清除(Dispose)、处理(Process)、 决策(Decide)、批量(Batch)、分离(Separate)、赋值(Assign)和记录(Record)模 块,而别的面板中还有许多其它的流程模块。在基本操作面板中,每种类型的模块都有不同 的形状,类似于经典的流程图(参考Schriber, 1969),但是在其它面板中有更多的流程模块 的形状没有具体含义,它们只是用简单的长方形来表示,一些面板中(如“高等运送”面板) 使用不同颜色的长方块区分不同类型的流程模块, 另一些面板 (如用于联络中心和包装的专 用面板)使用更加复杂的图形表示流程模块。一旦流程模块被放到流程图窗口里,即可双击 该模块来编辑它, 此时会出现一个有关该模块的对话框。 另一种编辑的方法就是在项目栏或 流程图窗口中选择一种模块类型(例如单击Create或Process模块),此时在电子数据表格视 图中会出现一列该类型的模块, 这样就可在电子数据表格中编辑它们了。 这种方法可以使你 对模型中该种类型的所有模块情况一目了然,因此在大型模型中非常有帮助。 数据模块定义了各种操作元素(如实体、资源和队列)的属性,同样也能够创建整个模 型所用的各种数值变量和表达式,在项目栏里像小电子表格形状的模块就是数据模块的图 标。“基本操作”(Basic Process)面板里的数据模块有实体、队列、资源、变量、调度和 集合模块,别的面板里包含了其它种类的一些数据模块。实体不会流经数据模块,同时数据 模块也不能被拖进模型窗口内,实际上数据模块隐藏在“场景”背后,定义不同的数值、表 达式和条件。不能通过双击数据模块来编辑它们,但可以在工具栏里单击数据模块,这样相 应类型数据模块的电子表格就会出现在电子数据表格视图内, 通过双击可以编辑或增加数据 行。系统默认的是在电子数据表格内编辑模块,但如果双击左侧的数据列,则可以在对话框 内编辑。与流程模块不同,同一类型的数据模块在模型中不会出现多于一个,但一个数据模 块可能有很多行,每行描述一个独立的对象所包含的数据(例如,如模型中有三种不同的队 列,队列数据模块就会包含三行,每行在表格中代表一个队列)。 同一模型内流程和数据模块通过它们共有的对象(如队列、资源、实体类型和变量)名 称相互联系起来。Arena保存所定义过的对象名称目录,并把它们在适当的位置以下拉的形 式呈现出来,这样可以帮助用户记住对象的名称(可以使用户不必多次输入对象名称,或者 至少可以保证对象名称前后一致,从而保证模型顺利运行)。

3.2.5 内部模型文档
当把鼠标指针停留在一个模型符号或其它对象上时, 你将会看到相应的数据提示, 数据 提示分为默认描述和自定义描述。默认描述介绍有关对象的一般信息,如名称和类型;自定 义描述给出用户在对象属性区域内所键入的内容。在对象上点击鼠标右键,然后选择属性, 就会出现可键入文本的区域。数据提示的出现与否可以通过View>Data Tips菜单控制,默认 情况下,“默认描述”和“自定义描述”都处于激活状态,当然也可以将两种提示屏蔽掉。 除了对模块描述外, 也可以定义 “项目描述” 即给整个模型提供一些说明性文本信息, , 可利用项目描述很好地说明模型是做什么的、 为什么这么创建模型以及所做的假设等相关信 息,可通过Run>Setup>Project Parameters菜单键入项目描述(参看本章后面的图3-15)。 数据提示是一种很有用的功能, 但当模型很大时, 你可能想知道是否有其它方式去充分 利用这些信息, 答案是肯定的。 可利用Tools>Model Documentation Report菜单创建用户报告, 它汇总了所有模型数据,可在该菜单中的可选项中选择报告要包括的各种信息,即可生成 HTML形式的报告。

3.3 浏览现有模型:模型 3-1
为了了解模型3-1是如何创建的,本书将带你进入模型窗口中的流程模块和数据模块, 说明这些模块是如何联系起来的,然后再运行这个模型查看结果。之后在3.4节,本书将从 头开始教你如何建立模型。

3.3.1 Create 流程模块
首先从流程图视图左侧的“创建”模块(Create)开始,此处把该模块命名为“零件到 达系统”。 对于到达模型边界的实体来说,Create模块意味着从外部进入模型的起始点,在这个例 子中,实体就代表零件。双击该模块会打开一个图3-2所示的对话框。

原书P57

图3-2 模型3-1的Create模块对话框 在“名称”(Name)栏中输入Part Arrives to System(零件到达系统)作为该模块的名 字,这个名称将会出现在模块图标框内和数据提示部分。然后在“实体类型” (Entity Type) 栏中定义Part作为该实体的类型,在这个模型中只有一个实体类型,但是通常情况下会有很 多实体类型,此时需要分别命名使其直观,同时可以用于其它一些目的。 话框中部的“到达时间间隔”(Time Between Arrivals)区域是用于规定相邻实体到达 间隔时间属性的。在“类型”(Type)栏内选择Random (Expo)(可使用下拉列表箭头 )

定义到达时间间隔为一个服从指数分布的随机变量(如果需要复习概率知识可参看附录C; 查看指数分布或其它概率分布的定义参看附录D),在“参数值”(Value)栏内输入5,在 “单位”(Unit)栏内定义Minites(分钟)作为时间单位,表明此处是5分钟而不是5秒种、 5小时或5天, Arena不严格区分混合整数和实数,因此也可以输入“5.”或“5.0”。 在对话框底部,可以看到“每次到达实体数”(Entities per Arrival)栏中数值为1(默 认值),表明一次到达一个零件;“最大到达数”(Max Arrivals)栏中了定义仿真过程中 实体最大的到达数量, 此处为无穷大 (缺省) 如果有限制, , 则在达到最大到达数之后Create 模块将被“关闭”;“首次到达”(First Creation)栏表示第一个实体的到达时间,此处为0 (而不是经过一段初始时间)。 单击对话框中的Cancel按钮或右上角的 OK按钮。 另一种编辑Create模块的方法是通过电子数据表格视图来完成的。当单击流程图视图中 的Create模块(如果模型内Create模块有很多,单击其中任何一个即可)或项目栏中Create 模块图标,则Create模块的数据表格就会出现在电子数据表格视图内(如图3-3所示),单击 或双击每个区域都可以编辑数据元素或从可选项中做出选择, 图3-3通过单击 “类型” (Type) 打开相应的下拉列表(下拉列表会出现在任何起作用的地方)显示了一系列“类型”选项。 如果在模型内有多个Create模块,则每个模块在Create模块表格内有一个单独的行与其对应, 在大型模型中这种方法可以快速编辑很多元素,或者一次总揽所有Create模块。若在流程图 或表格视图选择一个特定的Create模块,同时也会在另外一个窗口中选定了那个特定模块。 在表格行上右击,可以选择以对话框的形式编辑模块,类似于图3-2。在数值区域右击,则 可以选择 “构造表达式” (Build Expressions)来帮助输入复杂的代数表达式,如各种Arena 来关闭对话框; 若要保存所做的改动, 则单击

变量、概率分布、数学方程和代数运算等(3.4.10和4.2.4节将讨论表达式构造器)。通过拖 拉分割表格字段的竖条标记可以改变表格字段的宽度。

原书P58

图3-3 模型3-1的Create模块数据表格

3.3.2 Entity 数据模块
上节在Create模块里所做的事情之一就是将实体类型定义为Part。在项目栏中选取“实 体”数据模块(Entity),则实体数据表格就会出现在电子数据表格视图中(图3-4),此时 可以看到并编辑模型中的各类实体的属性。图3-4显示了“初始图形”(initial picture)字段 的下拉列表, 告诉我们在仿真运行过程中零件实体的动画图形将显示为蓝色的球, 还有其它 几个字段用于定义实体的各类成本数据, 在行末还有一个复选框问你是否要这个实体类型的 统计报告表, 统计表包括了运行期间这类实体在系统中的平均逗留时间和最大逗留时间。 本 模型只有一个实体类型,如果有多个实体类型,每个类型在实体表中用一行来描述。

原书P59

图3-4 模型3-1的Entity模块数据表格

3.3.3 Process 流程模块
“处理” 模块 (Process) 代表机器, 包括资源、 队列和实体延时 (本例中指零件加工) , 本例的Process模块被命名为钻孔加工中心(Drilling Center)。双击该模块,可以看到如图 3-5所示对话框。

在“名称”(Name)栏键入模块名称Drilling Center后,在类型栏(Type)选取“标准” (Standard)类型,这意味着这项操作的逻辑将在Process模块中定义,而不是在其递阶子模 型中定义 (关于子模型和层次的内容将在5.2.4节讨论) 对话框底部是 。 “统计报告表” (Report Statistics)复选框,用于选择是否输出相关的统计报告,如利用率、队列长度和排队等待时 间等。 逻辑(Logic)区域占了对话框大部分面积,决定了该模块对实体的有关操作。 在“活动”(Action)栏中选取“占用-延时-释放”(Seize Delay Release),它表明在 该模块中实体会“占用”一定数量的资源,然后“延时”一段时间(表示服务),最后“释 放”资源以便其它实体能够占用。其它可能的“活动”主要有以下几种:Delay,仅仅“延 时”实体一段时间(可以把“延时”认为红色交通灯,信号过后实体才能继续进行);Seize Delay,“占用”资源然后“延时”(但不释放资源);Delay Release,“延时”然后“释 放”以前被“占用”的资源。几个Process模块结合起来可以表示很多类型的处理活动。

原书P60

图3-5 模型3-1的Process模块对话框 可以在模块中指定不同实体占用资源的优先权值(Priority),在Arena中,越小的数字 意味着越高的优先权。 对话框的资源(Resources)部分定义了所占用或释放的资源。点击“添加”(Add)按 钮可以在资源列表中增加一项资源, 双击表中某一资源行可以定义或编辑这种资源, 也可单 击资源行再选择“编辑”(Edit),此时会出现“资源”(Resources)对话框,如图3-6所 示。 在对话框内可以定义资源名称 (Name) 和加工单元数量 (Quantity) (例如单个服务器) , 这一数量是实体将要占用或释放的加工单元的数量 (而不是资源本身所拥有的加工单元的数 量,即资源容量,资源容量在“资源”数据模块中定义,将在以后讨论)。若填入一种以上 资源, 意味着实体在开始加工之前必须占用特定数量的每种资源 (例如一台机器和两名操作 人员),且相应地要释放特定数量的各种资源。

返回到如图3-5所示的对话框, “延时类型” (Delay Type)的下拉列表提供了三种概率分 布(正态分布、三角分布和均匀分布) 、一个“常量” (Constant)选择和一个“表达式” (Expression)选择。 “单位” (Units)域决定了延时的时间单位, “分配” (Allocation)域涉 及如何确定延时所带来的成本。下面一行的内容根据“延时类型”选择的不同而不同。值得 注意的是,延时类型中的“表达式”选项在定义延时持续时间方面有很大灵活性,它包括了 Arena所有概率分布,在表达式字段内单击右键还可以调出“表达式构造器”(Expression Builder)帮助你建立各种表达式(参见3.4.10和4.2.4)。

原书P61

图3-6 模型3-1的Resources对话框 点击Cancel按钮关闭Process对话框;如果要保存所做的改动,点击OK。 如果在流程图视图中选中某个Process模块,或在项目栏中选中Process模块,则在电子 数据表格视图中就会出现如图3-7所示的Process模块表格, 图上还显示了 “延时类型” (Delay Type)下拉列表。如果模型中有多个Process模块,则数据表格的每一行表示一个Process模 块,像Create模块一样,它提供了另一种描述方式,既可以同时查看多个Process模块,也可 以编辑模块的每个数据域。如果在Resources域单击“1 Rows”按钮,就会出现一个二级数 据表格(如图3-8),可以在该表中编辑、添加和删除资源,等同于图3-6所示的资源对话框 (在进行下一步之前,需要单击右上角的 按钮以退出二级数据表格)。

原书P61

图3-7 模型3-1的Process模块数据表格

原书P62

图3-8 模型3-1的Process模块中的Resources二级数据表格

3.3.4 Resource 数据模块
一旦在Process模块中定义了一种资源(本例中资源为钻床),就会自动在“资源” (Resource)数据模块中建立一个数据项。可在项目栏中单击Resource模块查看资源数据表 格,如图3-9所示。通过资源数据表格可以确定每种资源的特征,例如资源容量(Capacity) 是固定的还是可变的(图3-9显示了“资源类型”(Type)的下拉列表,其中“固定能力” 被选中)。也可以根据一些模式定义资源故障,单击“故障” (Failures)栏下面的“0 Rows” 按钮可以弹出Failures二级数据表格(故障模式在“高等操作”(Advanced Process)面板的 “故障”(Failure)数据模块里定义,该面板需要另外附加到项目栏中)。

原书P62

图3-9 模型3-1的Resource数据模块电子表格

3.3.5 Queue 数据模块
如果实体进入Process模块而钻床处于繁忙状态,实体必须排队等待。如果在项目栏中 选中“队列” (Queue)数据模块,队列数据表格就会出现在电子数据表格视图中,如图3-10 所示,此时可以定义队列的各个属性,例如排队规则,图3-10中“类型”(Type)列表中显 示了“先进先出”(First In First Out)规则(默认选项);也可以根据实体的某种属性规定 排队规则,假如选择了“最低属性值”(Lowest Attribute Value),则必须在“属性名称” (Attribute Name)栏里指明用于排序的具体属性,队列将按该属性的升序排列。

原书P62

图3-10 模型3-1的Queue数据模块电子表格

3.3.6 制作资源与队列动画
说到队列,你可能已经注意到了流程图视图里Process模块上方的符号 ,这

就是显示队列动画的地方。当在Process模块中指定实体需要“占用”(Size)资源时,模块 上方就会出现这个图形。 谈到动画时,毫无疑问你会注意到Process模块右上方的 ,它位于队列动画的队首位

置,这就是资源动画,在仿真过程中动画图象会根据钻床是空闲还是繁忙而改变。资源动画 不是凭空而来的,而是通过动画工具栏中的资源按钮( )添加到模型中去的,在 上双

击会得到如图3-11所示的“资源图形布局”(Resource Picture Placement)对话框,可以从图 形库(扩展名为.plb的文件,通常在Arena 7.0文件夹内)中根据资源的状态选出合适的图形 来表示资源的不同动画,本书将在3.4.8和4.3.3节讨论资源动画问题。

原书P63

图3-11 模型3-1的“资源图形布局”对话框

3.3.7 Dispose 流程模块
“清除”(Dispose)模块代表实体离开模型边界,双击Dispose模块会调出如图3-12所 示对话框和图3-13所示的Dispose数据表格。在这里没有更多的可做  仅仅是给模块起个

描述性的名字, 并决定是否要输出实体统计数据, 包括经过这个模块的实体在系统中的平均 和最大逗留时间以及实体的成本信息等。

原书P64

图3-12 模型3-1的Dispose模块对话框

原书P64

图3-13 模型3-1的Dispose模块数据表格

3.3.8 Connecting 流程模块
Create、Process和Dispose模块(从左向右的顺序)是通过连接线(Connector)连接起来 的,从而建立起了所有零件流经的序列,使零件从一个流程模块流向另一个模块。单击连接 (Connect)按钮( 单击源模块的出口点( )或者选择菜单Object>Connect进行连接时,鼠标指针变为十字线, ),再单击目标模块的入口点( )(如果你想用一系列的线段 )取消掉,

来连接,可以单击一些中间点)。如果发现很难进行连接,可以把自动对齐( 这样你可以很容易的单击出口点和进口点。

如果选择Object>Auto Connect,Arena将自动把新放进去的模块的入口点与一个此前选 中的模块的出口点相连接。 如果选择Object>Smart Connect,则新的连接线将自动遵循水平和垂直方向放置,当然 这只是感觉的问题,对模型操作和结果没有影响。

如果选择Object>Animate Connector(或把动画连接器按钮

按进去),当仿真运行的

时候,Arena将显示实体图形沿连接线运动的动画,这仅仅是让你知道运送正在进行  就 仿真和统计数据而言,此时运送时间实际上为0(即速度无穷大),在4.4节将讨论如何模拟 非0运送时间,以及如何用动画来表示。

3.3.9 动态散点图
模型中的两个散点图是通过动画(Animate)工具栏中的散点图(Plot)按钮( )创

建的,在仿真运行过程中,它们将被自动绘制,但仿真结束时图像会消失(7.2.1节将讨论绘 制更加详细的散点图,且在运行结束后仍存在)。 双击上面的散点图会调出如图3-14左面的“散点图”(Plot)对话框。在“表达式” (Expression)栏里只有一个条目,因此在散点图中仅有一条曲线,单击“添加”(Add) 按钮调出表达式对话框(填完后,其形式如图3-14右边部分),在表达式框中键入函数NQ (Drilling Center.Queue),即队列中实体数量(队长),其中实体数量在仿真过程中自动更新, 在框中右击可以使用表达式构造器来帮助我们键入正确的内容(关于表达式构造器参看 3.4.10和4.2.4节)。

原书P65

图3-14 模型3-1的队列长度Plot对话框及表达式对话框 在对话框中双击表达式(或单击表达式后再单击Edit)会调出如图3-14右边所示的填充 好的散点图“表达式”(Plot Expression)对话框。其中最小值(Minimum)表示绘图曲线 的y轴最小值,最大值(Maximum)表示y轴允许的最大值。由于本例模型是从空闲开始的, 因此很明显最小值应该是0;最大值可以是一个猜测的先验值,经过运行发现确切的最大队 长后,再对这个值加以调整。如果最大值设得很大,则散点图会被沿y轴压扁,相反如果设 得很小,则会截掉部分散点图(后面将会讨论Arena自动缩放功能)。# History Points表示在 任何给定的时间内所允许的最大拐点数, 若仿真运行时散点图的左部看不见, 则应该增大这 个值。由于该散点图描述队列长度,所以应该以分段常量形式来表示,因此应选择Stepped

选项来定义曲线外观。Color按钮用以改变曲线的颜色,这在同一坐标轴内绘制不同表达式 的曲线时会很有用。单击Cancel按钮关闭Plot Expression对话框返回到Plot对话框。 返回到Plot对话框后,在“时间范围”(Time Range)栏内输入20,这样在整个20分钟 (分钟是模型定义的基本时间单位)的仿真运行中允许在x轴上有足够空间绘图。既然宽度 足够,我们将在“刷新”(Refresh)栏处选择不刷新图像(None)(None下面的数字表示 按多大比例刷新图形)。在“边界”(Border)栏中选择Bounding Box,并选中Fill Area复 选框,表示将用某种颜色填充到曲线下面的区域中。如果要在同一张图上绘制几条曲线,可 以选择Synchronize Min and Max复选框,对曲线极值加以缩放,使按相当的幅度表示在同一 y轴上,此时还要键入对曲线最大和最小值的估计值;如果进而选择了Y-Label,则可通过选 择Auto Scale来让Arena根据所有曲线的需要调整y轴比例。也可以给散点图加上标题,“标 题”(Title)区域内的各栏内容应是不难理解的(Percent Height是指标题高度占整个散点图 高度的百分比)。X- Label选项可以让我们标注x轴的极值,在3.3.10节将介绍如何自己定制 标注,同样的Y-Label选项将显示曲线在y轴方向的最大与最小值。Plot对话框右边缩略图下 面的Area、Border和Fill Area按钮用于为图形区域(背景)、边框、曲线下的填充区域选择 颜色(此处选择亮灰色背景,深灰色填充区,黑色边框)。单击Cancel关闭Plot对话框。 用鼠标拖拉散点图的边界可以改变其大小,可以单击选中图形试一试(不用担心,使用 Undo功能可以恢复原状)。事实上,在填完对话框之后就确定了图形的初始尺寸,但这是 可以更改的,如通过拖拉散点图重新定位。 Drill Press: Number Busy(忙态钻床数)散点图及其表达式对话框跟上面提到的相似, 所以此处不再赘述。唯一不同之处是表达式形式,此处在y轴上绘制的表达式值是处于忙态 的钻床数量,很明显数值只能是0或1,所以在散点图表达式对话框内可指定最大值为2,这 样有利于图形美观。 如前所述, 可以在表达式框里使用表达式构造器来创建正确的名称与语 法。

3.3.10 修饰模型
在模型窗口中添加各种文字标注, 例如左上角的标题和散点图上的坐标轴标注等, 可以 通过绘图(Draw)工具栏中的本文(Text)按钮( )实现, 同时还可以控制文本的字

体、大小和字型,在本文输入中使用Ctrl+回车重新开始一行。为了改变文本颜色,首先选 中相应文本(在文本上单击),然后使用Text Color按钮( )选择相应的的颜色(单



)或者其它不同的颜色(单击

);还可单击文本后拖动下划线条来调整文本大小或

旋转文本。 另外绘图工具栏中还有方框、椭圆、多边形、直线以及控制它们颜色和字体的工具,这 些都可以用来装饰模型窗口, 当然这主要取决于个人的艺术创造力与天赋。 在本模型中只是 在模型标题后面绘制了一个阴影框。在排列(Arrange)工具栏和菜单中还有很多按钮和命 令用以操作对象,例如组合、旋转和把绘图对象送到层叠对象的前面或后面等。3.5.2和3.5.3 节将讨论更多艺术性工作。

3.3.11 设置仿真运行条件
通过Run>Setup菜单可以调出带有五个标签版面的对话框(Run Setup)来设置运行周期 和重复仿真运行次数,图3-15显示了“项目参数”(Project Parameters)选项卡,在这里可 以定义项目标题、分析员姓名、项目描述和选择以后输出何种性能指标。也可以选择键入一 个简单的项目描述来为模型提供一个内部说明。

原书P67

图3-15 模型3-1的Run>Setup> Project Parameters对话框 图3-16显示了“重复仿真运行参数”(Replication Parameters)选项卡,它控制仿真的 运行。“重复仿真次数”(Number of Replications)默认为1(此时我们仅考虑建模问题, 所以1是可以接受的)。在“日期与时间”(Start Date and Time)区域也选择默认值,这可 以使某个特定的日期与时间和开始仿真时刻0联系起来。可以指定每次重复运行前的“预备 时间”(Warm-up Period),预备时间过后系统会清除统计累加器以使仿真初始条件对系统 的影响减弱。本例指定“重复仿真运行周期”(Replication Length)为20,选定时间单位为 分钟,每天小时数默认为24(对于这个问题是很显然的,但如果习惯上以天为单位,一天有 两班生产,每班8小时,则可认为一天有16小时)。“基准时间单位”(Base Time Unit)指 明了默认的时间单位,因此基于时间的输出都将按这种默认时间单位形成报告,同样,在一 些没有指定时间单位的输入参数域也按这种默认时间单位处理(例如图3-14的Plot对话框里

的时间范围)。“终止条件”(Terminating Condition)框允许建立复杂的或与状态有关的 终止准则,在12.5.2节的一个例子中,利用这一选项可使仿真运行到结果满足精度时为止。 在模型3-1中,仿真在第20分钟时终止。单击Cancel关闭“运行设置”对话框。 说到终止,必须在每个Arena模型中指明如何终止仿真运行,这是建模的一部分,而且 Arena不知道你想要什么,因此也没有自带任何默认的终止条件。事实上,大多数情况下仿 真永远运行下去或直到你人为停止它。3.7节将介绍如何暂停运行和在必要时取消运行。

原书P68

图3-16 模型3-1的Run>Setup> Replication Parameters对话框

3.3.12 仿真运行
单击“标准”(Standard)工具栏中的“运行”(Go)按钮( )(或Run>Go菜单或

按F5键)开始运行模型,可以注意到这些按钮类似于媒体播放器上的那些按钮。当第一次 运行模型时,Arena将检查模型中的错误(也可以单击“运行交互”(Run Interaction)工具 栏中的 按钮或Run>Check Model菜单或按F4键来检查模型错误),如果存在错误,系统会

提出警告,同时给出一些寻找和纠正错误的帮助。检查无错后才能观看动画运行,此时必须 快看,因为运行时间很短。在动画运行中,可以看到零件实体(蓝色小球)到达和离开,资 源图形随着资源状态在“空闲”和“忙”之间转换而发生变化,当实体进入和离开时队列的 改变,状态栏中数字仿真时钟快速跳动,散点图被动态绘制等。根据模块类型不同,流程模 块旁边的记数器显示了不同的数量,对于Create模块,计数器显示的是创建的实体数量;对 于Process模块,显示的是目前在加工的实体数量;对于Dispose模块,显示的是离开系统的 实体数量。在3.7节将讨论其它运行模型的方式。 运行后的最终状态如图3-17所示(去掉了问是否查看结果对话框)。散点图显示了和手 工仿真图2-3相同的信息,状态栏里的时钟停在了最终时刻,在这一时刻可以看出资源处于 忙态,还有一个零件在队列中等待(与2.4.3节的最终状态和表2-2最下面一行信息相一致), 另外流程模块旁边的计数器显示的终值也和2.4.3节手工仿真结果一样。

运行结束后出现的对话框询问是否查看总结报告,关于总结报告将在3.3.13节讨论。在 看过报告后(或者选择不看报告),模型窗口将被“悬挂”起来,不能编辑任何事物,这是 因为你仍旧处在运行模式, 在这种模式下可以查看散点图和动画的最终状态, 若要退出运行 模式返回到编辑状态,必须单击结束按钮( )。

3.3.13 查看输出报告
仿真运行结束后,如果想要查看数值报告,在如图3-17右下角的对话框内单击Yes,这 样就会在Arena窗口中打开一个新的报告窗口(独立于模型窗口)。在项目栏中的“报告” (Reports) 面板中列出了一系列可以查看的各种不同形式的报告, “汇总报告” 如 (Category Overview)“重复仿真运行分类报告” 、 (Category by Replications) “资源报告” 和 (Resources) 等,单击每一种报告都会打开一个独立的报告窗口(可使用Arena窗口菜单查看打开了什么 报告),当查看完报告后别忘了关闭这些报告窗口,因为返回到模型窗口时,这些报告窗口 不会自动关闭,如果改动了模型并重新运行,可能会同时打开几个报告窗口,从而分不清楚 哪个报告对应哪个模型变更。实际上,当改动模型研究不同参数设置或假设的影响时,应该 略微改动.deo文件名, 因为如果不改动文件名, Arena会用同名的报告文件覆盖以前的结果, 这样以前的结果会丢失 (3.5.1节讨论的过程分析器能够提供一种更好的方式来管理多个模型 变更运行,并且能够跟踪结果)。

原书P70

图3-17 模型3-1的最终动画状态 默认选项下安装的Arena自动调出的是汇总报告,可以看到大多数结果,在项目栏中的 其它报告虽有一些重复,但报告得更详细。在“报告窗口”的左侧有一个目录树(单击“+” 可展开目录树,单击“-”则收缩目录树),它是所有报告的超级连接纲要。报告是按页面 组织的,通过报告窗口左上方的 或全部页面,点击报告窗口内的 , , , 按钮可以浏览各页面,如果想打印一些

按钮(不是Arena窗口内的类似按钮。如果报告窗口是活

动的,则Arena窗口内的类似按钮是暗淡的,处于非活动状态)。如果你想把报告输出到文 件,单击报告窗口的 按钮,然后依指示进行。

如果想寻找一些具体的报告,最好单击目录树中的“+”和“-”。例如,想查看仿真运 行中队列发生了什么变化, 通过在目录树中单击一系列的 “+” 进入到报告的 “队列” (Queue) 部分(Simple Processing → Queue → Time → Waiting Time → Drilling Center.Queue), 最终得到钻孔中心的等待时间信息,如图3-18所示。在目录树中选择的内容显示在右边的报 告中,在“等待时间”(Waiting Time)行上可以看到平均排队等待时间是2.5283分钟(报 告中提示基本时间单位是分钟),最大排队等待时间是8.1598分钟(两者都与2.4.2节手工仿 真结果一致),报告窗口再往下一点的“其它”(Other)标题下,能够看到平均排队等待 的零件数(队长)是0.7889,最大排队等待零件数为3,两者都与2.4.2节手工仿真结果一致。

原书P71

图3-18 模型3-1的“汇总报告”(部分) 通过浏览报告,可以注意到表2-3中的输出性能指标在报告中都有,并且还有Arena自动 收集的其它许多资料(将在以后讨论),例如,根据下面提示的目录树分支,可以发现:  Simple Processing → Entity → Total Waiting Time → Part:平均系统逗留时间为 6.4397分钟,最大系统逗留时间为12.6185分钟。  Simple Processing → Resources → Usage → Instantaneous Utilization → Drill Press:钻床利用率是0.9171(即运行时间的91.71%钻床处于忙态),利用率的不同指 标将在4.2.5节讨论。  Simple Processing → Process → Other → Number In → Drilling Center: 在仿真运行 过程中,有7个实体进入钻孔中心模块。

 Simple Processing → Process → Other → Number Out → Drilling Center:在仿真运 行中,有5个实体离开钻孔中心模块(比进入的少2个,这两个在仿真终止时尚未离开 钻孔中心),5还代表了模型中的总产量,因为零件离开钻孔中心就等于离开了系统。  Simple Processing → Entity → Time → Waiting Time → Part:离开系统的5个零件 在所有队列(当然此处只有一个)排队的平均等待时间是3.0340分钟,最大排队等待 时间是8.1598分钟。这个平均值之所以不同于2.5283分钟的钻孔中心平均排队等待时 间,是因为3.0340分钟计算的是5个离开系统的零件的平均等待时间,而2.5283分钟计 算的是所有6个离开队列的零件的平均等待时间,两个最大排队等待时间是相等的, 是因为那个最大等待时间的零件在仿真中完成加工较早(两个最大值不一定总是相 等)。  Simple Processing → Entity → Other → WIP → Part:在制品数平均为1.7060个, 最大能达到4个。 报告中的各种数据可以分为记数型统计量、时间持续型统计量和计数器统计量。  记数型统计量(Tally)是由一系列数字取平均值、最小值或最大值得到的结果。例 如,平均和最大系统逗留时间(分别是6.4397和12.6185)就是记数型统计量,因为它 们是仿真运行中5个离开系统的零件的平均和最大系统逗留时间。有时候记数型统计 量也被称为离散时间统计量(discrete-time statistics),因为它们的“时间”下标(1, 2,3,…)是按时间顺序的离散指标集。  时间持续型统计量(Time-persistent)是由散点图的平均值、最大值和最小值产生的 结果, 且散点图的x轴是连续的时间。 时间持续型统计量的平均值需要求散点图曲线下 的累积面积(即积分),平均和最大排队等待实体数(分别是0.7889和3个)与钻床的 瞬时利用率都是时间持续型统计量。  计数器统计量(Counter)从名字上就可以看出是某种事物的累计和,通常它们只是 记录事情发生的次数,如离开或进入钻孔中心的零件数量。计数器统计量所累计的数 字也可能并不都是1,例如在钻孔中心的累积等待时间是15.1700分钟(排队等待时间 之 和 ) 在 汇 总 报 告 中 , 这 个 数 值 可 以 通 过 Simple Processing → Process → , Accumulated Time → Accum Wait Time → Drilling Center.Queue 找到;通过Simple Processing → Resources → Usage → Total Number Seized → Drill Press,可以看到 另外一个计数器统计量,即钻床资源被使用了6次。

关闭报告窗口后,只要不删除模型运行后Arena创建的微软数据库文件,则还可以在以 后查看这些报告。 数据库文件通常命名为model_filename.mdb, 其中model_filename为模型文 件名(本例中数据库文件名为Model 03-01.mdb)。只要在项目栏的报告面板里单击想看的 报告便可以再次查看它。整个工作方式是Arena使用Crystal Reports第三方软件去读取数据库 文件,从中析取有用的材料,然后以报告窗口的形式展现出来。 在大型复杂的模型中采用这种结构非常有用, 它可以组织大量的不同输出数据, 帮助查 找资料、进行对比以及做出结论。 除了上面介绍的几种报告外,Arena还产生一份相当紧凑的仿真结果报告,像ASCII文 本一样,文件名为model_filename.out, 如图3-19所示。 报告中的一些标题有些不一样, 例如, “离散变化型变量”(Discrete-Change)等同于时间持续型统计量,你也会发现这份报告中 有些数据(可能有些微小的可四舍五入的差别)在前面已经讨论过,而另有一些数据则不在 前面提到的报告里(例如记数型统计量的观测次数)。某种情况下,这种方式比前面的报告 结构更简单快捷,可是报告中的顺序、安排和标识都不太友好,事实上这种形式是Arena早 期版本的产物,可以追溯到80年代早期使用SIMAN仿真语言的时候。如果想把这种报告形 式作为仿真运行结束后的默认报告,可以进入Run>Setup>Reports菜单,在“默认报告” (Default Report)列表中选中SIMAN Summary Report。 到目前为止,像平均值、最小值、最大值和时间平均这些概念的含义应该很清楚了,可 是报告中很多地方都提到了“半长”(Half Width)(虽然在这个模型内我们不可能得到这 些数值,而且被告知“数据不充分”),半长指的是性能指标期望值的置信区间(95%)的 半长,假如仿真过程能够提供足够的数据,就可计算出来。

原书P74

图3-19 模型3-1的SIMAN格式仿真输出报告(Model 02-01.out) 如果做多次重复仿真运行,每次运行Arena对一种输出性能指标生成综合报告,对多次 运行结果求平均值和样本标准差,则可计算出这种性能指标期望值95%置信区间的半长,

2.6.2节手工仿真就是这么做的,见表2-4。练习3-1将教你如何用Arena重新产生表2-4中的结 果。 如果对系统长期运行(或稳态)性能感兴趣,可以选择进行一次长时间仿真运行,具体 内容参看6.3节,如果运行时间足够长,也可以在报告中看到半长数值。Arena把单次长时间 运行结果分解为若干批量,这些批量相当于多次重复仿真运行产生的结果。有关内容将在 7.2.3节讨论, 包括如何从仿真输出数据中计算这些半长。 为什么有时我们在报告中看到的不 是半长的数值而是“数据不足”(有时候是“相关”)呢?这是因为只有运行周期足够长时 才能得出半长结果,如果运行周期不够长,Arena就会拒绝得出。

3.4 自己动手创建模型 3-1
本节将逐步介绍如何建造模型3-1,可能开始建造的模型看起来不十分像模型3-1,但在 功能上是等同的且能产生相同的结果。 在开始之前,先介绍两个经常会用的用户界面功能。  在流程图视图内的空白处右击鼠标会调出一个小选项框,其中一项就是“重复上一 操作”(repeat last action),当重复操作时(例如,可能需要多次放置一个模块), 使用这一功能可以节省时间。另外,选项框内还包括一些视图、运行和检查模型的操 作。  按Ctrl+D或按Ins键可复制在流程图视图选中的对象。

3.4.1 新建模型窗口和基本操作面板
按 按钮(或File>New或者Ctrl+N)打开一个新的模型窗口,默认文件名为Model1,

保存时默认扩展名为.deo,当然在保存模型窗口内容时也可以改变文件名。在这个模型操作 期间打开的一系列新模型窗口将会得到默认文件名Model2、Model3等等。单击模型窗口右 上角的 可以在Arena窗口中最大化模型窗口。

接下来,如果在项目栏中没有所需要的面板则需添加。对于这个模型,只需要“基本操 作”面板即可,它是Arena 7.0文件夹下的Template文件夹内名为BasicProcess.tpo的文件。单 击 按钮(或File>Template Panel>Attach或右键单击项目栏选择Attach)打开如图3-20所示

添加模板对话框,在这里打开“基本操作”面板文件BasicProcess.tpo(在文件上单击,然后

单击Open按钮或者直接在文件上双击);也可以让Arena自动添加一定的面板到新建模型窗 口的项目栏内,这可通过在Tools>Options>Settings菜单中把面板文件名(包括.tpo扩展名) 输入到Auto Attach Panels框内。

原书P76

图3-20 添加面板对话框 添加后的面板出现在项目栏内, 面板内有代表每种模块的图标。 在面板内右击可以改变 图标的大小或者只显示模块的本文信息, 如果意外添加了错误的面板, 也可以通过在错误的 面板内右击选择Detach来删除之(也可以用 按钮或者File>Template Panel>Detach),即

使已经在模型中放置了错误面板中的模块也可以删除它。 另外, 如果显示屏不够显示整个面 板内容,可以使用右边的滚动条来查找所有的模块。

3.4.2 放置和连接流程模块
这个模型需要Create、Process和Dispose三种流程模块。要添加一个流程模块,可以从项 目栏中把它的图标拖动到流程图窗口内, 然后释放到你想要的地方, 别忘了使用3.2.3节提到 的网格( 线。 如果在菜单中选中了Object>Auto-Connect功能, 按上面提到的顺序把流程模块拖到模型 中后,Arena将自动按正确的顺序连接模块;如果选中了Object>Smart Connect功能,则这些 连接线会自动调整为水平或垂直方向。 图3-21显示了在放置了三个流程模块后流程图窗口的样子(两种“连接”开关键都已打 开) ,其中Dispose模块还处于被选中的状态,因为它是最后被放进去的。如果没有选中 Object>Auto-Connect,则需要手工连接模块,单击连接按钮( 口点( )和进口点( ),然后选中模块上的出 )、自动对齐( )和按网格点对齐( )等功能帮助把模块调整成一条直

),如同3.3.8节所述;回想3.3.8节,如果动画连接线(Animate

Connector)按钮(

)被按下去(或选中Object> Animate Connectors),则可以看到动画

过程中实体沿连接线运动, 这样就会了解实体从一个模块移动到另一个模块的过程, 不过此 时的模拟运动时间为0,4.4节将介绍如何在模型中实现非零运动时间。

原书P77

图3-21 流程模块的初始布局

3.4.3 Create 流程模块
双击模型中的的Create模块打开如图3-22所示的对话框,在这里需要编辑几处内容。首 先,把模块名称从默认的“Create 1”改为“Part Arrives to System”,把实体类型从默认的 “Entity 1”改为“Part”,然后在“到达时间间隔”(Time Between Arrivals)区域内,接 受默认的“随机”(Random(Expo))类型,参数值由1改为5,在下拉列表内选择分钟作 为时间单位,在对话框最底部的三个区域都接受默认值,最后单击OK保存改动。保存时的 对话框应该如图3-2所示。回想起来,也可以通过电子数据窗口来查看和编辑流程模块,具 体参见3.3节,这个Create模块的完整电子表格显示在图3-3中,可以注意到这个模块的新名 字出现在流程图视图的模块中。

原书P77

图3-22 Create模块对话框

3.4.4 输入界面
在介绍新的模块和新的概念的时候,本书试图带你浏览每一个对话框,即像Create模块 这么简单,上面的描述也相当冗长,为了讲述得更加简洁,本书将使用输入界面(Display)

这样的直观形式,如输入界面3-1所示。注意到输入界面由三部分构成,右上部分是填写好 的对话框(见图3-2),在某些情况下,这部分也会显示几个相关联的对话框;左上部分显 示的是与右上对话框相关联的模块(以及将在该对话框中点击的按钮);输入界面的下面部 分是一个表格, 表格显示了用于完成对话框的必要操作, 表格左边一列为对话框栏目或提示, 右边一列包含了输入的数据或动作(选择复选框或按命令按钮)。一般而言,当介绍新模块 或模块新的二级对话框时,会提供整个输入界面;但对于介绍过的的模块;通常只提供输入 界面下部的表格部分,对于那些输入界面中没有显示的条目,表明接受默认值。

原书P78

输入界面3-1 完整的Create模块对话框 现在是保存模型的好时机, 选择一个不同于Model 03-01的名字保存, 或者把Model 03-01 保存在另一个文件夹内。

3.4.5 Entity 数据模块
在Create模块中你已经定义实体类型为Part,现在继续讨论一些有关实体的事情。以前 在这里所做的唯一事情是把实体的初始动画图形由“报告”( )改为“蓝色的小球”( ),

为实现这一步,在项目栏中单击Entity数据模块,在电子数据表格视图中会将其参数显示出 来(见图3-4),在“初始图形”(Initial Picture)列表中单击Picture.Blue Ball即可。

3.4.6 Process 流程模块
输入界面3-2指出了在Process流程模块中需要编辑的内容。由于规定“活动”(Action) 需要占用资源,所以必须单击“添加”(Add)按钮定义被占用的资源,这样就调出了“资 源”(Resources)二级对话框(也见输入界面)。如果想让队列在动画中能显示得更长, 可单击队列动画图标( 平、垂直或45°)。 ),然后拖住左端点向左移动(按住Shift键限制角度为水

原书P79

输入界面3-2 完整的Process模块

3.4.7 Resource 与 Queue 数据模块
一旦定义了Process模块,模型当中就有了资源和队列,两者的名字在前面已被指定(队 列名是whatever.Queue,whatever是队列所在的Process模块的名称)。如果你想为资源与队 列指定非默认的名字,可以在Resource和Queue数据模块中定义,参见3.3.4和3.3.5节。

3.4.8 资源动画
制作资源动画通常是很有好处的, 尽管对于仿真结果不一定起什么作用。 这样可以显示 资源的状态(闲或忙),也能够显示正在被加工的实体。 单击动画(Animate)工具栏内的资源(Resource)按钮( )调出“资源图形布局”

(Resource Picture Placement)对话框,现要为资源指定图形,单击“标识”(Identifier)栏 旁边的箭头从中选择资源名Drill Press,然后在左侧图形列表中选择“非活动状态” (Inactive),单击Delete按钮删除该图标;同样试着删除图形列表中的“故障”(Failure)。 现在钻床在空闲时显示为白色的方块,繁忙时显示为绿色的方块。若要改变动画图形, 双击相应的“方块”调出图形编辑器(Picture Editor),在这里可以自己动手绘制钻床相应 状态的图形,或者如果你有另外的描绘钻床的图形文件(可以来自数字摄象机),也可以复 制粘贴进图形编辑器内。 我们还可以从Arena的图形库中挑选一些吸引人的艺术图形。关闭图形编辑器返回到资 源图形布局对话框,在右栏中单击Open按钮打开Arena图形库文件,首先找到Arena 7.0文件 夹,你会看到一系列扩展名为.plb的文件,打开Machines.plb,在右边可以看到很多好看的图 形,向下滚动单击 ,再单击左边的Idle图标按钮,然后单击 ,把图形复制到左边变成

钻床空闲状态的图形,取代白色方块。同样地复制

到左边变为钻床忙态图形。最后,选

中底下的“占用区域”(Seize Area)框,以便正在加工中的零件能够出现在动画中。这时 资源图形布局对话框看起来应该如图3-11所示,4.3.3节将讨论关于资源图形的更多内容。

3.4.9 Dispose 流程模块
Dispose模块是最后一个流程模块,输入界面3-3显示了如何编辑这个模块(唯一要做的 就是改变默认名)。

原书P80

输入界面3-3 完整的Dispose模块

3.4.10 动态散点图
在3.3.9节已经描述了两个散点图动画元素的大多数输入项和属性。 现在从头一步步制作 这样的散点图,按下动画工具栏中的散点图(Plot)按钮( )调出一个空白的“散点图”

(Plot)对话框,然后按照输入界面3-4的说明填充对话框。记住,最初你必须估计在“散点 图表达式”(Plot Expression)对话框内的y轴最大值,在对结果有了进一步的认识后再调整 这个值。填写完对话框后单击OK,这时鼠标指针变成十字线,点击确定散点图的一个角点 位置,然后拖动鼠标到另外一个角点位置,即可在模型窗口中放置好散点图(当然以后还可 以调整散点图的大小和位置)。

原书P81

输入界面3-4 完整的“队列长度”散点图对话框 在“散点图表达式”二级对话框内可直接键入NQ(Drilling Center.Queue)。在Arena当中, 有许多地方可以直接键入普通代数表达式, 但为了输入正确, 你必须知道模型中各种对象的

正确名称(像Drilling Center.Queue)和Arena内部函数(如NQ,它能返回队列中当前的实体 数量)。为了避免需要大量记忆的困难,Arena提供了一个“表达式构造器”(Expression Builder),通过在“表达式”栏内右击便可在弹出菜单中选择进入表达式构造器。图3-23 显示了表达式构造器窗口,在图中我们展开了左边的“表达式类型”树,找到了想要的“当 前队列长度”散点图表达式。随着我们选择的表达式类型的不同,右上角框内的显示内容也 会随之改变,可以在下拉列表中指明所需队列的名称(在这个模型中只有一个队列,因此下 拉列表很短)。在底部的“当前表达式”(Current Expression)框内显示出由表达式构造器 得出的结果,单击OK,系统就会把该结果送回我们开始右击的栏内。当然在“当前表达式” 框内也可以编辑和修改表达式, 例如使用运算按钮进行数值运算, 或者利用左边的类型树查 找其它数量等。

原书P82

图3-23 用表达式构造器建立队列长度表达式 “处于忙态的钻床数量”散点图与队列长度散点图类似,只有两点不同于输入界面3-4, 并且都是在“散点图表达式”二级对话框内。第一,构造表达式NR (Drill Press),打开表达 式构造器, “表达式类型” 在 (Expression Type) 树中选择以下路径Basic Process Variables → Resource → Usage → Current Number Busy,在Resource Name下拉列表里找到Drill Press;第 二,既然我们知道图中曲线高度是0或1,因此直接在y轴“最大值”栏内填2。 为了使两个散点图在视觉上和谐,应绘制相同的大小的图形,并在垂直方向上对齐。

3.4.11 装饰窗口
模型3-1的流程图视图中有几处文本标注,用于帮助记录信息,也可指明在动画中某个 元素代表什么,这些文本标注可以通过绘图工具栏的本文按钮( )来实现,打开的文本

编辑对话框如图3-24所示,在其中输入文本信息(使用Ctrl+回车换行),使用Font按钮改变 字体(Times Roman、 Arial等)、字形(斜体、粗体等)和大小,单击OK后鼠标指针变成 十字线,在流程图视图中点击确定本文的西北角点。可以拖动文本标注改变其位置,也可以

选中文本并拖动它的下划线来调整文本的大小与方向 (调整方向时按住shift键能够限制方向 为水平、 垂直或45°)若要改变文本的颜色, 。 首先选中文本, 然后使用文本颜色按钮 ( 选择下划线的颜色(单击 )或者选择另一种颜色(单击 )

,从调色板中选出),选中新

颜色后,这种颜色将变为新的下划线颜色。 模型标识文字后面的黄色背景框和阴影是通过绘图工具栏的矩形按钮绘出的, 单击矩形 按钮,鼠标指针变为十字线,点击一次确定矩形的一个角点,再次点击确定矩形对角线上的 另一个角点。选中矩形并单击填充颜色按钮( 颜色按钮( )可以改变矩形的填充颜色;单击线条

)可以改变边框的颜色。为了创造像阴影一样的人为三维效果,可以使用

排列(Arrange)工具栏或菜单中的诸如Send to Back等功能来调整图形位置(例如将黑框放 置在黄框后面稍微右下一点,以产生阴影效果)。

原书P83

图3-24 文本编辑对话框 如果想在流程图视图放置图形文件(.gif、.jpg等),可使用Edit>Insert New Object,选 择Create from File,然后浏览选择你想导入的图形文件,单击Insert后点击OK,最后用鼠标 (十字线)放置图形。 很明显,你可能会花费很多时间在这种装饰事情上。我们不想强加于人任何观点,但通 过经验观察确实发现, 如果你想向组织中更高层次的管理人员提供仿真结果, 你越应在图形 上花费更多的功夫。

3.4.12 运行参数的设置
使用菜单命令Run>Setup来设立运行条件,进入菜单后会发现几个带标签的页面,这些 页面控制模型的运行,不过这里只需要编辑其中的两页。 第一个页面是“项目参数”(Project Parameters)选项卡,在这里输入项目标题、分析 员姓名和项目描述。也可以根据需要修改在输出报告中收集哪些统计数据,这可通过在

Tools >Options>Project Parameters菜单中设置默认选项来实现。完成后的对话框如图3-15所 示。 另外一个需要编辑的选项卡是“重复仿真运行参数”(Replication Parameters),这些 内容在3.3.11节已讨论过,编辑后的对话框如图3-16所示。

3.4.13 为视图命名
可以为模型设立各种命名的视图(Named View),首先通过场景缩放将当前视图调整 成你想保存的场景,然后选择View> Named View菜单(或按?键),单击添加(Add),挑 选一个名称和热键(此处是区分大小写的)定义此视图。如果以后想改变这个视图定义,则 将场景缩放到新的视图效果,在Named View菜单中单击编辑(Edit)来完成;要想从列表中 删除已定义的某个视图,只需选中该视图名并单击删除(Delet)即可。至于如何使用命名 的视图,我们在3.2.3节已经讨论过了。 乍一看,设立命名的视图似乎也只是一种装饰,但是请相信,随着模型规模的扩大,这 是非常有用的手段。

3.5 关于菜单、工具栏、绘图和打印的更多知识
本节将简要的介绍一些关于菜单和工具栏的其它各种信息, 以及一些关于绘图和打印 , 的功能。在后面章节的例子里,必要时还会对这些内容给予更加详细的说明。

3.5.1 菜单
这里首先对Arena菜单内容做一个简要的概述。如果在某种情况或状态下菜单里的一些 选项不能用, 则这些选项是暗淡的(意味着你不能选择)。要想知道菜单条目的更多信息, 可单击 , 然后点击任何菜单项目 (无论暗淡与否) 来获得完整的信息及相关的主题链接。

文件菜单(File Menu):在文件菜单里可以创建新的模型文件(New)、打开已有的 模型(Open)、关闭窗口(Close)和保存模型(Save),也可以向项目栏内添加和删除面 板(Attach/Detach),还可以从AutoCAD(或者其它DXF格式的CAD程序)中导入CAD图 形用做Arena “背景” 在某种情况下允许使用现成的设备图形和元素 , (如线导车辆的路径) , 另外一种可导入的图形文件是.vsd格式的Microsoft Visio图形文件。如果想改变Arena使用的 颜色,可以把它们保存为一种调色板,同样也可以打开以前保存过的调色板。通过文件菜单

还可以进行文件打印、 从Arena内部发送邮件 (可以把当前的模型添加到发送信息内) Arena 。 能够记住最近打开的文件,并可以快速地再次打开它们。退出(Exit)命令是结束Arena的 方法之一。

原书P85

(第一幅图,无图名) 编辑菜单(Edit Menu):在编辑菜单里能够找到对象操作的许多常用选项。能够取消 前面的操作(Undo)或重做取消的操作(Redo);剪切(Cut)或复制(Copy)选中的对 象到剪切板,以将其放置到当前模型中的其它地方或其它模型中去,在某些情况下还可以 放到其它应用软件中去;粘贴(Paste)能够把剪切板中的内容插入到模型中去,粘贴为超 级链接 (Paste Link) 可以为当前处在剪切板中的源文件创建OLE链接; 制作副本 (Duplicate) 是复制选中的对象并放置在源目标的附近;删除(Delete)能够永久清除选中的对象,当然 也可以选中模型中的部分或所有对象,同时删除它们;使用实体图形(Entity Picture)可以 改变实体数据模块中的图形列表和列表中图形的外观, 而且还可以从Arena图形库中复制图 形到列表中去;时间进度表(Calendar Schedule)可以描述复杂的递阶时间模式(星期由天 组成,天由班组组成等)、定义例外情况(如假日和休假),同时以复合的形式显示其效 果;查找(Find)功能是搜索当前模型中所有模块和动画对象以寻找文本串,并且可以控 制全字匹配和区分大小写(这个功能经常用于查找你认为没有但在报告错误信息中存在的 条目);属性(Property)选项能够显示附加的对象属性,例如对象的唯一标识;如果有链 接到其它类似于电子表格或音频文件的链接,则链接(Link)功能能够显示该链接并允许 你修改链接;插入新对象(Insert New Object)用来放置来自其它应用程序的图形和多媒体 文件等;对象(Object)让你能够编辑从其它应用程序放到模型中去的对象。

原书P85

(第二幅图,无图名) 视图菜单(View Menu):在视图菜单里能够控制模型在屏幕上的显示形式以及窗口中 显示何种工具栏。缩放(Zoom)可以让你从不同的高度看模型,以便你既能够看大模型也 可以看细节的小部分,缩放因子(Zoom Factor)控制每次缩放的比例,视图提供了模型的 多种“固定”视图,命名的视图让你能够定义、改变和使用自己的视图;网格(Grid)与对 齐(Snap)在调整对象时很有用,网格设置(Grid Settings)可以控制网格与对齐的间隔; 分页显示模型(Page Break)指明了页面是如何分割的;数据提示(Data Tips)用于控制当 鼠标停留在对象上方时是否显示对象属性;层次(Layers)用于控制模型编辑或运行时显示 何种对象;如果分割屏幕(Split Screen)被选择为打开,则模型窗口将同时显示流程图视图 和电子数据表格视图; 工具栏 (Toolbars) 用于指定在屏幕上显示哪些工具集, 项目栏 (Project Bar)是开关键,用于控制是否显示工具栏;类似地,状态栏(Status Bar)让你决定是否想 看到屏幕最下方的水平状态栏, 状态栏能够告诉你正在进行什么, 同时指出了图形建模空间 里鼠标指针的坐标。

原书P86

(第一幅图,无图名) 工具菜单(Tools Menu):Arena不仅有强大的建模能力,而且还带有一整套相关的工 具,至于有那些工具取决于你的注册信息。Arena符号库(Arena Symbol Factory)提供了大 量的分类图形,从中可以为实体和资源等动画创建图形符号;输入分析器(Input Analyzer) 用于根据所观察到的真实数据来拟合模型输入数据的概率分布(参看4.5.4节);过程分析器 (Process Analyzer)可组织有效的方法进行多次仿真运行,每次运行代表不同的模型配置, 同时跟踪结果, 它也可以帮助对仿真结果进行正确的统计分析, 从不同的模型配置中选择最 好的配置;具有额外统计能力的另一个应用程序叫做输出分析器(Output Analyzer),它是 Arena所带的工具,但必须单独启动,在6.5和6.4节分别介绍如何使用过程分析器和输出分析 器;工厂分析器(Factory Analyzer)有利于对生产操作能力建模,利用它的子菜单可以实现

与FactoryTalk交换数据,FactoryTalk是生产企业的中央资料库;联络中心(ContactCenter) 提供了特殊的功能去对联络/呼叫中心建模;模型文件报告(Model Documentation Report) 可以生成一套简洁但完整的资料,包括运行条件、使用的模块和子模型等。输出模型到数据 库(Export Model to Database)可以把模型的细节保存到Access或Excel数据库中,从数据库 输入模型(Import Model from Database)可以从这样的数据库中输入模型的细节信息从而快 速的构造或更新模型;OptQuest是与Arena配套的一种应用软件,它能够改变模型输入,然 后进行一系列的仿真运行,寻找使输出性能指标最优的一组输入数据组合,在6.6节给出了 一个关于OptQuest应用的例子;宏(Macro)选项提供了记录和运行宏命令的工具,也提供 了使用VB编辑器编写用户逻辑的工具, 关于VB的话题将在10.2节讨论; 最后的选项 (Option) 条目允许你改变和自定义有关Arena运行和外观的各种选项,以符合你的需要。

原书P86

(第二幅图,无图名) 排列菜单(Arrange Menu):排列菜单的条目都与模型中的模块和图形对象有关(有 些只能用于图形对象)。使用送到前面(Bring to Front)和送到后面(Send to Back)可以 在一堆重叠的对象中把被选择的对象分别送到最顶层和最底层;组合(Group)和取消组合 (Ungroup)表示在逻辑上把多个对象整合成一个或拆开,但不改变对象的物理性质,在移 动或复制由多个个体对象构成的复杂图形时组合功能非常有用;翻转(Flip)是把选中的对 象沿指定的方向绕轴翻转,旋转(Rotate)则是把选中的对象沿顺时针方向旋转90°;对齐 (Align)是把选中的对象沿它们的上面、下面、左边或右边对齐,分布(Distribute)是在 水平或垂直方向上平均安排所选中的对象;流程图分布(Flowchart Alignment)是把选中的 流程模块在水平或垂直方向上平均排列;按网格点对齐(Snap to Grid)强制所选中的对象 对齐下面的网格点;改变对齐点(Change Snap Point)可以改变用于所选对象所对齐的网格 点的确切位置。

原书P87

(第一幅图,无图名) 对象菜单(Object Menu):对象菜单中的条目与模型的逻辑结构、流程模块和逻辑块 间的连接线有关。单击连接(Connect),鼠标指针变为十字线,此时可在实体流经的模块 之间建立连接;自动连接(Auto-Connect)是一个开关键,能够自动把新放入的模块与已经 选中的模块相连接;智能连接(Smart Connect)使新增加的连接线以水平或垂直线段绘制, 而不是用可能的对角线绘制,除非用手工绘制连接线过程中进行了中间点击;动画连接线 (Animate Connectors)用于在仿真中显示实体沿流程模块之间的连接线移动的过程(即使 实体在仿真中的移动是瞬时发生);子模型(Submodel)用于定义和管理分层的子模型, 将在第五章讨论。

原书P87

(第二幅图,无图名) 运行菜单 (Run Menu) 运行菜单中包括在3.3.11和3.4.12节讨论过的运行设置 : (Setup) 对话框,它控制当前模型运行的方式(包括运行时间长度等),还包括以不同方式运行仿 真的项目,还有观察执行情况、检查模型错误(Check)并查看错误信息(Review Errors)、 设置及控制如何运行模型以及在屏幕上如何显示等,对于这些功能本书将在3.7节进一步描 述。通过此菜单也可访问由Arena生成的用SIMAN仿真语言编写的代码。

原书P88

(第一幅图,无图名)

窗口菜单(Window Menu):如果同时打开了几个模型,则可以用相互重叠的层叠方 式(Cascade)或非重叠的平铺方式(Tile)排列模型;如果最小化了几个模型,还可以选择 排列图标(Arrange Icons)来组织它们;使用系统背景颜色(Use System Bachground Color) 指的是让模型使用当前Windows操作系统层次所选的颜色,而不是Arena内部设置的颜色, 再次选择该条目可以使模型返回Arena的内部颜色(每次选择这个条目,就会在“系统”与 “用户”之间切换);最后,可以选中菜单底部已经打开的模型来激活该模型。

原书P88

(第二幅图,无图名) 帮助菜单(Help Menu):帮助菜单是访问Arena在线帮助系统的几条途径之一(具体 参见3.6节) 进入Arena Help子菜单后, 。 可以按目录 (Content) 索引 、 (Index) 搜索 、 (Search) 等方式查找所需信息;“What’s This ?”子菜单将鼠标指针改变为 ,此时在菜单条目

或工具栏按钮上单击即可得到相关帮助;版本注释(Release Notes)提供了最近的改进和系 统需求等信息;Arena技巧文件(Arena SMART Files)为两百个小模型建立了基于主题的索 引, 这些小模型阐明了许多特殊的建模技术; 接下来是关于当前模型中所添加的面板的帮助 主题;产品手册介绍了关于Arena构件及其相关产品的信息,Arena在线帮助直接带你登录含 最新帮助和软件信息的网站 (当然必须在线完成) 菜单中最后三项提供了支持和培训信息, ; Arena用于商业、研究和实验版本的复制保护,以及详细的版本信息。

原书P88

(第三幅图,无图名)

3.5.2 工具栏
Arena有几个工具栏(Toolbar),工具栏上面带有按钮和下拉列表框,这些工具栏便于 快速访问常用的活动。这些按钮中,一些可以更快地实现菜单功能,还有一些是做某种事情 的唯一途径。 选择菜单View>Toolbars(或在工具栏里右击)可选择当前显示哪些工具栏。像许多其 它应用软件一样, 可以把工具栏拖下来, 让它悬浮在窗口内部, 或者让它停放在窗口两侧 (如 果你只是想让工具栏悬浮在侧边但不停放在侧边上, 在拖动工具栏接近侧边时按住Ctrl键) 。 不用每次使用Arena时都设置工具栏选项,因为Arena将记住最后一次的配置,另外,在不同 的阶段也可以有不同的配置,例如,编辑模型的时候、仿真运行过程中、其它的各种窗口处 于活动状态的时候等,Arena将会记住每种配置。 通过View>Toolbars>Customize菜单或在工具栏内右击选择Customize,可以自定义如何 显示工具栏, 下面将按顺序介绍每种工具栏, 但是通过自定义功能你可以选择去重新安排哪 些按钮在哪种工具栏上。  尽管可以选择隐藏标准(Standard)工具栏,但是你会发现没有它会很不方便。

原书P89 (第一幅图,无图名)

标准工具栏开始是创建新模型、打开已有模型和保存当前模型这些按钮,就像文件菜 单里一样,同样与文件菜单对应的还有添加面板、删除面板、打印和打印预览按钮。 剪切、复制、粘贴、取消和重做按钮的功能来自编辑菜单。接下来的是分割屏幕的开 关键,放大镜是用于最可能近地放大查看在流程图视图里选中的区域,也可以从下拉 列表里选择缩放比例。层按钮让你能够控制模型在编辑和运行模式下何种类型的对象 能够被看到,接下来是添加子模型和连接流程模块。随后是编辑时间模式和编辑例外 情况,分别用来创建和管理事件的时间模式和例外情况,再后面是显示复合视图,是 用来管理特定系统元素的能力与效率的数据。接下来六个按钮是用于运行控制的,将 在3.7节讨论。 最后一个按钮是关联帮助按钮, 单击此按钮后, 再点击工具栏中的按钮、 菜单命令或项目栏模块能够了解与此有关的帮助信息。

 绘图(Draw)工具栏中的按钮没有相对应的菜单选项,因此只能访问工具栏。

原书P89 (第二幅图,无图名)

使用绘图工具栏可以绘制静态的线段、折线、弧、贝塞尔曲线、矩形、多边形和椭圆 等用于装饰模型,还可以为模型添加文本注释。有一些按钮控制线段颜色、填充颜色、 文本颜色和窗体背景颜色,也能够改变线型和图形填充模式。如果你在其它应用软件 中使用过绘图功能, 就会熟悉Arena的绘图能力, 最好的熟悉这些功能的办法就是打开 一个模型窗口试试这些操作,具体参见3.5.3节的绘图功能。  动画(Animate)工具栏用于制作模型动画,并改进一些模块自带动画的显示效果。

原书P90 (第一幅图,无图名)

一般说来,其操作都是单击某个按钮,根据需要填写对话框,然后放置到模型中去。 这些按钮的功能各不相同,在以后章节的建模中将具体讲解(我们目前已使用过Plot 和Resource按钮)。现在可以把鼠标指针停留在每个按钮上查看其提示信息。  集成(Integration)工具栏中包括了有关模块数据传输向导和VBA(VB编辑器和VBA 设计模式)功能的按钮。

原书P90 (第二幅图,无图名)

第十章将讨论VBA的使用,VBA能够通过一个完整的VB程序接口扩充Arena标准建模 功能。  视图(View)工具栏的按钮控制如何观察建模窗口中的流程图视图。

原书P90 (第三幅图,无图名)

在此可以管理命名的视图、放大和缩小、观看整个视图或观看前一视图,还可以让视 图显示网格背景,使新放入的或所选中的对象对齐网格  排列(Arrange)工具栏基本上对应于Arrange菜单。

原书P90 (第四幅图,无图名)

包括把选中的对象送到前面或送到后面,把选中的多个对象组合在一起,也可以再取 消组合;把绘制对象沿过中点的水平线或垂直线翻转, 90°旋转;按选中对象的上 边、下边、左边或右边对齐它们;在水平或垂直方向上平均布置它们。  运行交互(Run Interaction)工具栏有几个按钮对应于运行菜单,分别用于检查模型 错误、输入命令、设置断点、监视运行过程、和中断模块运行,工具栏的最后一个按 钮对应于Object菜单中的动画连接线。

原书P91 (第一幅图,无图名)

 录制宏(Record Macro)工具栏有开“始/暂停/恢复运行”按钮,以及“停止录制VB 宏”按钮,一个宏是存储在VB模块子程序中的一系列VB语句(将在第十章讨论)。

原书P91 (第二幅图,无图名)

 动画传送(Animate Transfer)工具栏提供向模型中添加动画对象的工具。

原书P91 (第三幅图,无图名)

工具栏里的按钮包括暂存处、占用、停车、运送设备、站、交叉点、路径、路段、距 离、网络和导入路径,本书将在随后的章节中讨论这些功能。

3.5.3 绘图
3.5.2节提到的绘图工具栏有多种图形、 文本工具和控制功能, 使你能够通过放置静态对 象(不参与仿真和动画)来改善模型,这些静态对象可以帮助记录信息或使动画看起来更逼 真,例如添加墙壁、走廊和盆栽。Arena并不是想提供一种CAD或者艺术功能,但是这些基 本绘图能力还是很有用的,当然也可以像3.4.11节提到的那样从其它软件包导入图形。Arena 的绘图工具用起来跟其它绘图程序差不多, 因此此处仅仅指出有哪些绘图工具以及让你尝试 使用一下来熟悉它们。  线段(Line), :在这个按钮上点击一次,鼠标指针变为十字线,单击线段起点,

再次单击得到线段终点,如果想限制线段为水平、垂直或45°方向,鼠标指针移向线 段末端时按住Shift键不放。  折线(Polyline), :使用这个按钮能够绘制锯齿状折线(中间的折点数不限)。

选中按钮后,单击确定起点,然后在每个中间折点处单击一次,最后双击确定终点, 绘制过程中可以按住Shift键不放以使线段为水平、垂直或45°方向。  弧(Arc), :弧就是绘制椭圆的部分边缘。首先单击确定椭圆的中心,然后移动

鼠标追随边缘轮廓, 再次单击确定弧的大小与形状 (按住Shift键不放可使椭圆成为圆) , 这时鼠标指针变为从椭圆中心点发射出来的线段的末端,单击确定弧的一个端点,再 次单击确定弧的另外一个端点。如果以后想再次编辑这段弧,首先选中弧,使用线段 改变弧长,使用所显示的标记点改变椭圆的大小和形状。  贝塞尔曲线(Bézier Curve), :贝塞尔曲线也是一种常用曲线,它们能够适应很

多不同的形状而仍能维持其光滑度和美观。 单击确定一个端点, 然后进行中间点击 (最 多30次)确定内部吸引点,双击确定另外一个端点,当鼠标移向下一个点过程中按住

Shift键可以限制连接两点的线段为水平、垂直或45°方向。如果想要改变曲率,选中 曲线,拖动内部吸引点或端点到不同地方。要想移动曲线的话,用鼠标直接拖动即可。  矩形(Box), :首先单击确定一个角点,然后再次单击确定另外一个对角点。

按住Shift键可以限制矩形为正方形。这个对象和下面的多边形及椭圆一样都有边界, 边界也可以被认为是线段,因此可以选择颜色和线形,同样边界内部还可以选择填充 颜色和填充模式。  多边形(Polygon), :单击确定第一个点,然后鼠标移到其它位置单击确定其它

点,双击确定最后一个点,最后一个点自动被连接回第一个点。按住Shift键可以强迫 线段为水平、垂直或45°方向。这个对象和矩形一样有线边界和填充区域。  椭圆(Ellipse), :首先单击确定中心点,移动鼠标追随边界轮廓直到想要的大

小和形状,最后再次单击。按住Shift键限制椭圆为圆。这个对象和矩形一样有线边界 和填充区域。  文本(Text), :使用文本功能可以在模型中添加注解作为标注或提供信息。单

击这个按钮调出对话框,在对话框内键入文本信息,在输入过程中使用Ctrl+回车开始 新的一行,使用Ctrl+Tab向前跳格,利用对话框上的字体(Font)按钮可以改变字形、 字体和大小。关闭对话框后鼠标指针变为十字线,单击确定文本信息的西北角点。使 用文本的下划线可以移动文本、调整其大小或改变其方向(按住Shift键可以限制方向 为水平、垂直或45°)。  线段颜色(Line Color), :如果选中线对象(线段、折线、弧、贝塞尔曲线或

其它图形的边界),单击此按钮的画笔部分可以将对象的颜色改变为画笔的下划线颜 色,单击下拉箭头可以将对象的颜色改变为调色板中选择的颜色,另外新添加的线也 自动取为下划线颜色。 Arena不仅会为当前窗口中即将添加的线 “记住” 这种线段颜色, 而且还会为新开的窗口“记住”这种线段颜色,直到你再次改变颜色为止。  填充颜色(Fill Color), 框、多边形或椭圆)的内部。  文本颜色(Text Color), 形对象上。 :与线段颜色类似,只不过这个命令作用在文本图 :与线段颜色类似,只不过这个命令作用在图形(方

 窗体背景颜色(Windows Background Color), 景颜色设置为从调色板中选取的颜色。  线形(Line Style),

:这个按钮将流程图窗口的背

:这个命令用于设置线的宽度和形状。None选项使线段不

显示,但事实上它仍旧存在(这个选项同样对图形的边界起作用)。  填充模式(Fill Pattern), :这个命令设置图形内部的填充形式。

3.5.4 打印
从Arena可以 直接打印 当 前活动窗 口 中流程图 窗 口的全部 或 部分。使 用 File>Print Preview(或 )可以预览即将打印的内容;使用File>Print(或 或Ctrl+P)进行打印;

使用File>Print Setup可以选择打印驱动或设置打印机。 如果模型很大,打印可能需要几个页面,而且如果模型中有命名的视图,可以得到当前 视图的打印件以及每个命名视图的单独打印件, 但如果你不想要全部这些, 可以使用打印预 览查看每页上显示的内容,然后有选择地打印你想要的页面。使用View>Page Break可以在 流程图视图内显示页面的起止位置。 除了直接打印外,还有一种可供选择的方法。如果你见到自己喜欢的视图,可单击Prnt Scrn键将其复制进剪贴板,然后切换到正在处理的文档中,把这个“快照”粘贴到你需要的 地方,如果喜欢的话还可以打印这个文档。也可以把这个复制的图象粘贴到绘图程序中,然 后加以修剪或整理(实际上本书中的Arena窗口片段就是这么得到的)。

3.6 帮助系统
Arena有完整而详细的帮助系统,可以作为重要参考,也可以指导你学习各种操作,还 可以提供建模示例和完整的项目示例。 帮助系统是精心集成的, 为快速简单地帮你找出所需 要的信息, 它还提供了其它一些领域的超级链接。 本节将简单介绍几种访问帮助系统的方式, 可是你会发现学习帮助系统的最好办法就是自己深入进去开始探索。 任何时候进入帮助(Help)菜单都能够访问完整的帮助系统,帮助菜单的内容已在3.5.1 节介绍过。

按钮能够调用关联帮助(context-sensitive help),单击按钮,然后单击你感觉好奇 的工具栏按钮、菜单命令、项目栏模块等,便可通过可视化的途径得到所需要的信息。 大多数Arena对话框都有帮助按钮可以单击,这是一条获得直接信息的很好的途径,例 如,那部分软件是做什么的、有哪些可选项、相关内容是如何定义的、相关的概念(高级链 接到帮助系统的其它部分) 和示例等。 也可以使用对话框右上方的?按钮来访问 “这是什么?” 帮助信息,单击?按钮,然后单击对话框中的个别项目即可。 万一你忘记了某个按钮是做什么的, 可以将鼠标指针停留在这个按钮上一两秒钟, 会出 现一个小盒状的提示信息告诉你这个按钮是什么。 在Arena 7.0文件夹内的Examples文件夹里有几个详细的示例模型,你可以打开、浏览、 复制、编辑(为安全起见,最好编辑复制品)和运行这些模型。如果你使用的是教学版本或 其它受限制版本的Arena,由于同时存在于系统中的实体数量受到限制,你可能无法把模型 运行完。如果你打开了一个大模型(超过了教学版本的限制),Arena会进入到运行时间模 式(Runtime mode),在这种模式下只允许你进行微小的改动然后运行模型,不允许做诸如 添加和删除模块这样的显著改动。 这些示例模型显示了构建和研究仿真模型的方方面面, 在 “示例模型”(Example Models)帮助主题里,对每个示例模型都作出了描述。

3.7 关于运行模型的更多信息
通常开始建立模型的时候只是想把模型运行完,但有时候你可能想控制运行如何进行, Run菜单中的条目以及标准工具栏和运行交互工具栏中的相应按钮能够实现这些功能。  Run>Setup能够为当前模型设置各种运行选项,例如决定是否显示动画和是否以全屏 模式运行等,这些选择和说明被保存在当前模型中,而不是变成全局效果。单击运行 设置对话框中的帮助按钮,通过浏览这些高级链接主题可以熟悉这些选项。  Run>Go (或标准工具栏中的 按钮或F5功能键) 开始运行模型 (或暂停后重新开始) ,

如果在上次模型错误检查后又对模型进行了改动,在运行前系统会先检查模型。  Run>Step(或 按钮或F10功能键)每次执行模型的一个动作,以便能仔细看到模型

的运行情况,这确实很烦人,但作为调试和演示工具来说相当有用。像使用开始运行 (Go) 按钮一样, 如果在上次运行模型后Arena检测到了改动, 则使用此单步运行 (Step) 前将首先检查模型。

 Run>Fast-Forward(或

按钮)以更快的速度运行模型,不再显示动画,但也可以暂

停运行过程来观看动画。 在上次运行模型后若Arena检测到了改动, 则使用此快进功能 前将首先检查模型。  Run>Pause(或 新启动运行。  Run>Start Over(或 或Shift+F5)返回到仿真的初始状态重新运行模型。如果在上次 按钮或Esc键)暂停仿真运行,以便查看运行情况,再按该按钮重

运行模型后Arena检测到了改动,系统在重新开始运行前将首先检查模型。  当Arena运行模型的时候,系统处于运行模式,大多数建模工具被禁用,因此当运行 结束后,需选择Run>End(或 或Alt+F5)退出运行模式,使建模工具恢复到可操作

状态。如果在运行终止前仿真被暂停,使用结束按钮也将取消暂停状态。  Run>Check Model(或 或F4)用于“编译”模型,如果在这个阶段Arena检测到错

误,就会在错误/警告窗口给出提示,窗口底部的按钮将帮助你找到问题所在(例如, 在流程图窗口指出出错的模块)。  Run>Review Errors能够再次调用最近的错误/警告窗口,窗口中包含了上次检查所发 现的错误信息。  Run>Run Control>Command(或 )带你进入一个交互式的命令行窗口,在这里可

以控制运行,例如中断运行并改变参数,如有必要,也可以检查模型并开始运行仿真。  Run>Run Control>Break(或 时检查或说明某些事情。  Run>Run Control>Watch(或 )建立了一个窗口,用以在运行过程中观察变量或表 )用于设置断点,即中断运行的时间或条件,以便届

达式的值,Run>Setup>Run Control让你决定是否监视过程与仿真运行并行进行,还是仅在监 视窗口处于活动状态时进行(后者速度更快)。  Run>Run Control>Break on Module(或 )可以在选中模块中设置中断或将其清除,

模块上的中断是指实体在开始或恢复在该模块上的逻辑操作时被暂停执行。  Run>Run Control>Highlight Active Module使正在执行的流程模块突出显示,这样在动 画显示中能清晰地看见活动模块。

 Run>Run Control>Batch Run (No Animation)若被选中,模型在运行过程中不会有任何 动画显示,这种运行方式比快进(Fast-Forward)方式运行得更快,通常适用于项目处 于正式运行阶段、为精确分析需要大量统计数据的时候。  Run>SIMAN 使你能够查看SIMAN模型文件(.mod)和实验文件(.exp)的源代码, 并把它们写到一个文件中去,这些源代码是模型用最基本的SIMAN仿真语言编写的, 为加深理解, 可阅读一些关于SIMAN的知识 (参见Pegden, Shannon和adowski, 1995) 。

3.8 小结
快速浏览了一遍Arena后,你现在应该对它有所了解了,在接下来的第四章到第九章, 本书将让你自己加以探索,但会给你提供一张详细的行进路线图。在这些章节里,你将建立 一系列愈加复杂的模型, 在这些模型中阐述了很多建模技术, 有时候也需要你表现一些有创 造性的建模技巧。在第四章的最后部分、整个第六章、第七章的最后部分和第十二章中,将 从输入和输出两个方面着手,系统介绍如何用Arena进行仿真研究所需的统计分析。

3.9 习题
3-1 通过Run>Setup>Replication Parameters设置模型3-1重复仿真运行5次,查看输出结果, 注意多次重复仿真运行性能指标的变化,确认表2-4中的数据。打开“按重复仿真运行分类 显示”的报告,可以单独查看每次重复仿真运行的报告,但置信区间的半长只能在汇总报告 中才能看到。(在做多次重复仿真运行时参看6.3节关于记数型输出统计数据平均值的格式 编排的说明;也可参看在.3.13节讨论的.out文件,如图3-19所示。) 3-2 打开Create模块,把指数分布的到达时间间隔平均值由5改为2.5(点击OK完成修改), 这样模型3-1的实体到达速率加倍,这些在2.6.3节讨论过。设置重复仿真运行5次,把得到的 结果与手工仿真结果(图2-4)相对比,打开“按重复仿真运行分类显示”的报告,单独查 看每次重复仿真运行的报告。(在做多次重复仿真运行时参看6.3节的说明,是关于记数型 输出统计数据平均值的格式编排的;也可参看在.3.13节讨论的.out文件,如图3-19所示。) 3-3 把模型3-1的运行周期延长到12小时来观看一个有趣的现象。打开散点图,延长时间范 围(注意时间单位),增大散点图y轴队长(Number in the Queue)最大值,此外,还可能 需要增大 # history 栏中的数据点数。然后设置一次重复仿真运行。

3-4 按习题2-4所述修改模型3-1,打开Process模块,把延时类型改为Expression,输入合适的 表达式(需要的话可以使用“表达式构造器”)。运行模型20分钟,与手工仿真结果对比, 如果结果不同(假定你的操作完全正确),如何解释? 然后,试运行模型24小时,观看队长散点图(将两个散点图的时间范围改变为1440,# history 改为1000,另外对队长散点图,y轴最大值改为50)。为了队长动画能有更多的空间, 单击队列线段,拖动左端点向左移动。看看会发生什么?为什么? 3-5 按习题2-1所述实现附加的收集统计数据的功能, 同时添加能够追踪系统中零件总数 (即 在制品 work in progress,缩写为WIP)的散点图。注意,在仿真运行期间任何给定的时间 点,在WIP数量等于排队等待零件数量与正在加工零件的数量之和,也可以用“表达式构造 器”来检查帮助主题“Entities WIP Variable”。 3-6 在模型3-1中做如下变动:  添加第二台机器,所有零件离开第一台机器后马上进入第二台机器,第二台机器可 以进行另外一种加工操作(例如,第一台是钻床,第二台是铣床)。第二台机器上 的处理时间与第一台机器相同,像以前一样收集统计数据,外加第二台机器的排队 等待时间、队长和利用率等统计数据。  零件离开第二台机器后, 有一个 “通过/失败” 的检测, 进行检测花费5分钟 (常数) , 通过概率为80%,检测时有可能会发生排队,排队以“先进先出”为规则。不论零 件是否通过检测,所有零件都会离开系统。分别清点“失败” 和“通过”零件的 数量,同时收集检测中心的排队等待时间、队长和利用率等统计数据(提示:尝试 使用Decide流程模块)。   绘制这三个站的队长和设备繁忙数量的散点图。 运行仿真480分钟,而不是20分钟。

3-7 在习题3-6中,假设铣后没有通过审查的零件必须被送回重铣,而不能离开;对重铣后 的零件进行相同的检测,失败概率相同,不限制零件被送回铣床的次数,在习题3-6的条件 下运行模型,对比检测中心排队等待时间、队长和利用率的结果,当然没有必要分别统计通 过和没通过检测的零件数量,因为最终所有零件都将通过检测(会吗?),同时必须保证队 列动画的线段和散点图的y轴有足够的空间。

3-8 在习题3-7中,假设经过检测中心能够导致三种结果:通过(概率0.8,如前)、失败(概 率0.09)和重铣(概率0.11),失败的零件立即离开系统,重铣的零件返回洗床。不论零件 过去的加工经历, 上面的概率对于每个经过检测中心的零件是固定。 分别统计最终失败和最 终通过的零件数量, 同时收集在检测中心队列等待时间、 队长和利用率的统计数据。 (提示: 利用Decide流程模块并设想翻转一枚多维硬币。) 3-9 在模型3-1中,假设不是只有一种零件资源,而是有三种到达的资源,每种到达的不同 资源分别为:蓝色(如前)、绿色和红色,对于每种颜色的到达零件,到达时间间隔是均值 15分钟的指数分布。运行模型480分钟,计算和模型3-1相同的性能指标。一旦这些零件进入 系统,它们保持各自的颜色不变(动画中),不同颜色零件的队列等待时间、队长和利用率 等统计数据是不区分的, 可是系统逗留时间的统计数据是按零件颜色分别收集的。 在钻孔中 心的加工时间与模型3-1相同,并且各种颜色零件的加工时间是一样的。 3-10 在科技博物馆里,经常会看到概率板(probability board)(也叫作“五点梅花形排法” (quincunx)):

原书P98 (插图,无图号) 概率板像一个大的倾斜烘烤面板, 在上部边缘中点有一个狭槽, 从面板外面的储存器里 通过狭槽一次滚进一个弹球,假定储存器里有k个弹球,紧挨着狭槽下面有个固定的木桩, 每个进入的弹球都会撞击木桩引起弹球向左或向右滚落, 假设倾斜的面板使弹球向左或向右 滚落的概率相等。在这个木桩下面有两根木桩,它们平行于面板顶面,水平方向上与第一根 木桩偏移了一些距离,第二排木桩是按对角排列的,如下图所示。假设面板的倾斜角度、木 桩间距、 弹球质量和重力场正好可以使每个弹球都能击中第二排的其中一根木桩 (哪个木桩 被击中取决于击中第一根木桩后是向左还是向右滚落) ,弹球击中第二排木桩后右会向左或 向又滚落(向左和向右滚落的概率都是50%) 。接下来一排平行木桩有三根,水平方向上与 第二排木桩也有一定偏移, 以便使每个弹球能够击中其中一根木桩。 这种情况一直持续到最 后一排,假设有n排,则最后一排有n个木桩(本图中n=6,记最上面一根单独为一排) 。最 后一排木桩下面有n+1个按对角布置的收集器,从最后一排木桩滚落的弹球将落到其中一个

收集器里。创建一个Arena仿真模型模拟一个6排木桩和1000个弹球的概率板。制作弹球在面 板上弹落的动画,用动画工具栏的“水平”(level)动画对象制作落入收集器中弹球数量的 动画, 另外统计每个收集器中的弹球数量。 根据落入每个收集器中弹球的比例来估计符合哪 种概率分布?如果有人打开了左面的窗口,风进来把弹球向右吹,这样对于每个木桩,弹球 向右滚落的概率为75%(而不是50%),情况又会怎么样?

第四章

建立基本操作及输入模型

上两章介绍了一种简单加工系统(模型 3-1) ,其中第二章介绍了一个手工完成的仿真, 第三章检验了这一 Arena 模型。 本章将开始介绍如何建立与实际系统更加接近的 Arena 模型, 包括如何在简单模型的基础上, 通过增加复杂度和引入一些新概念, 来建立几种不同版本的 模型。本章还讨论了怎样为实际系统确定合理的输入概率分布。 4.1 节对电子器件装配与测试系统进行了描述,在此基础上介绍了如何对简单模型进行 扩展,引入了一些新的 Arena 概念,建立了新模型,并展示了如何运行所建立的模型以及观 察输出结果。现在,读者应该开始着重留意建模技巧了。4.2 节对上述模型进行了扩展:在 模型中增加了调度、故障、资源状态等要素,并且介绍了不同的结果分析方法。4.3 节讲解 了如何进一步完善动画效果。4.4 节概述了实体如何运动,并介绍了“站”(Stations)、非零 传送时间的实现以及传送过程的动画表示。最后,4.5 节介绍了如何确定输入数据,包括如 何选择驱动仿真的随机数概率分布模型。 完成本章学习之后, 读者应能自己建立具有一定细 致程度的模型,并能合理确定与符合实际的随机数作为模型输入。

4.1 模型 4-1:电子装配与测试系统
这里描述的电子装配与测试系统(如图 4-1 所示) ,表示的是两种需要封装的电子产品 的最后一道工序。到达产品需进行预处理,然后再装配。 第一种产品(即 Part A)是由模型之外的另一临近部门生产的,它按照均值为 5 的指数 分布时间间隔到达(所有时间单位为分钟) 。产品达到后,它们被立即送往产品 A 的预处理 区域,并在这一区域内完成保证封装作业的匹配及产品清理工作,产品 A 的预处理操作时 间满足三角分布 TRIA(1, 4, 8)。之后,产品被立即送往封装台。 第二种产品(即 Part B)是由本模型外的另一工厂生产,它以每批 4 件的方式成批输送 进入模型。批量的到达间隔时间服从均值为 30 的指数分布。产品到达产品 B 的的预处理区 域时,被分解为四个单件产品后分别进行处理。在产品 B 的预处理区域的操作与产品 A 类 似,处理时间服从三角分布 TRIA(3, 5, 10)。之后,产品被送往封装台。

1

原书 P104 图 4-1 电子装配与测试系统

在封装操作中,首先将电子产品插入箱盒,再进行箱体组装与封装,然后对封装后产品 进行检测。 所有这些操作的处理时间因产品不同而异: 对产品 A 的操作服从三角分布 TRIA(1, 3, 4),而对产品 B 的操作服从威布尔分布 WEIB(2.5, 5.3)的 (其中,比例参数  形状参数 

 2.5 ,

 5.3 ,其含义参见附录 D)。91%的产品能顺利通过检测,并被立即运送;产

品能否通过检测与其他产品通过与否无关。 未通过检测产品被送往返工区域进行拆卸、 修理、 清理、组装及重新检测。80%的返工产品能通过检测,并作为返工合格产品发运,其余不合 格产品则被送往废品区。 无论返工产品最终合格与否, 每件产品返工花费的时间服从均值为 45 的指数分布。 我们希望通过仿真获得每个工作区域的资源利用率、队长、排队时间,以及产品的系统 逗留时间等统计数据。仿真开始时,设置模型的终止运行条件为连续运行 8 小时(即 1920 分 钟)。

4.1.1 建模方法的扩展
搭建仿真模型仅仅是一个完整仿真项目的一个组成部分, 仿真项目的两个首要问题为设 定研究目标及系统定义,本书将在第 13 章专门讲述仿真项目整体方面的内容。本书将教你 学会如何使用 Arena 来建立自己的仿真模型。尽管上面已经给出了系统定义,但在实际问题 中, 需要扩展这种定义, 并且还需要收集和分析那些与指定输入参数及其分布 (参见 4.5 节) 相关的数据。下面将介绍模型扩展的方法。对于实际问题,首先需要定义数据结构,系统的 模型分解,或者控制逻辑的扩展。这里我们仅需选择哪个 Arena 模块能够提供我们所需要的 功能,并确定系统的细致程度。此外,我们还需要确定不同零件封装操作的不同操作时间。 为简化这一操作,可以将模型分解为如下几部分:到达部分,预处理区域,封装操作,返工, 离开及动画部分。并且,我们可以假设所有系统中的实体代表了正在被加工的产品。 因为模型中存在两类到达实体, 每种产品的到达服从不同时间分布, 所以分别采用两个 独立的 Create 模块来生成到达的产品。 各类产品的封装操作时间因产品不同而异,因此我们使用两个“赋值”模块来定义“封 装时间” (Sealer Time)属性,这一属性在 Create 模块生成零件的同时给封装操作时间赋以

2

相应的值。当产品接受封装操作时,就可以使用与 Sealer Time 属性关联的时间值,而不像 模型 3-1 中那样在操作时刻才生成这个时间值。 与模型 3-1 类似,两个预处理区域和封装操作都有各自的 Process 模块。封装操作完成 后要实施检查,通过“投币”选择来决定产品下一步进入哪个区域。这里使用一个基于投币 原理的“决策” (Decide)模块,因此返工区域拥有 Process 和 Decide 两个模块,以及“通 过”和“未通过”等选项。模型中使用三个单独的“记录” (Record)和“处理”模块(装 运、返工合格、废料处理) ,这样就可以按照装运、返工合格以及废品处理等几部分进行分 类统计。所有这些模块都包含在“基本操作”面板中。

4.1.2 建立模型
建立模型时, 首先打开一个新的模型窗口, 将需要建立的模块放置于屏幕上: 两个 Create 模块、两个 Assign 模块、四个 Process 模块、两个 Decide 模块、三个 Record 模块以及三个 Dispose 模块。 当你将这些模块按照一定顺序放置好之后,如果你建立了连接或选择了“自动连接” (Object 菜单中) ,则建立的模型窗口应与图 4-2 相似。不同模块的内部编号根据你放置模 块的先后顺序不同而异,因为这时所有模块的连接关系是“空白” ,因此不影响模型的最终 连接关系。完成之后,点击 File>Save 将模型保存到你选择的目录下。 完成上述工作后,分别打开每个模块,输入模型所需的信息。首先是产品 A 的实体到 达模块 Create 1。输入界面 4-1 提供了完成这一模块需要的信息(关于“输入界面”的介绍 详见 3.4.4 节的描述) 。这一步骤与模型 3-1 的 Create 模块非常相似。

原书 P106 图 4-2 建立模块的视图

我们给这个模块命名,并指定实体类型为 Part A。设置到达间隔时间为均值 5 的随机数 (即服从指数分布) ,单位设置为分钟(Minutes) ,其余项采用默认值,完成后点击 OK 键 接受模块设定。

3

原书 P106

输入界面 4-1 完成后的产品 A Create 模块对话框

原书 P106

输入界面 4-2 完成后的产品 B Create 模块对话框

产品 B 到达的 Create 模块设置与产品 A 类似,如输入界面 4-2(由于步骤几乎相同, 因此不再敖述) 。由于产品 B 是以每 4 个为单位成批到达,因此需要填充一个附加字段(每 批到达的实体) 来体现批量数为 4, 这一项将使得每次到达的是 4 个单独实体而非 1 个实体。

原书 P107

输入界面 4-3 指定产品 A 的封装时间和到达时间

创建了到达产品之后,紧接着给它定义一个 Sealer Time 属性,并给封装操作时间赋值, 操作时间因产品类型不同而异。我们在先前放置的 Assign 1 和 Assign 2 模块中进行赋值。 产品 A 的赋值如输入界面 4-3 所示, 我们定义一个新的属性并给它赋值为 TRIA(1, 3, 4)的三 角分布函数。我们还需定义 Arrive Time 属性,这个属性用来记录实体的到达时间。Arena 的 TNOW 变量用来提供仿真时钟当前值,这个时间就是产品到达的时间。 (TNOW 又称当 前仿真时钟,观察 TNOW 值的方法是:鼠标右键点击 Assign 模块 Assignment 对话框中的 New Value 域,选择 Build Expression,点击 Date and Time Functions,它在列表中被描述为 Current Simulation Time。 ) 为产品 B 的 Sealer Time 和 Arrive Time 属性赋值的过程如输入界面 4-4 所示。尽管前述 模块为产品到达创建了四个实体,但每个实体都在赋值模块中的 Sealer Time 分布属性中分 别赋予不同(相互独立)的值。
4

原书 P107

输入界面 4-4 确定产品 B 的封装时间和到达时间

创建了两种产品到达模块并给封装时间赋值之后,接下来可以利用先前放置的两个 Process 模块来建立两个预处理区域的模型了。Prep A Process 区域的完成对话框如输入界面 4-5 所示。 Process 模块有四个可能的活动类型选项:Delay,Seize Delay,Seize Delay Release 以及 Delay Release。Delay 会产生一个经历指定时间延迟的活动,这个活动不需要占用资源。由 于预处理区域需要占用机器或资源, 因此需要一个活动来实现排队等待, 直到获得预处理区 的资源,然后延迟至操作时间完成为止。Seize Delay 活动提供了等待和延迟功能,但它在 操作完成后并不释放资源给下一实体使用, 使用这个活动的前提是, 资源必须在下游的某一 个模块中能得到释放。Seize Delay Release 选项提供了准确建立预处理区域的各种活动的组 合。Delay Release 活动假设实体先前占用了一种资源,在此处经历一段延迟后,释放了这种 资源。

原书 P109

输入界面 4-5 产品 A 的预处理操作对话框

当选择最后三个选项之一时, 会在活动 (Action) 选择框下面的空白处出现一个列表框。 单击 Add 按扭来输入资源信息。 在输入数据时,希望尽可能使用下拉式列表功能。因为当你输入一个名称时,必须与先 前输入的名称完全一致。Arena 中的名称不区分大小写,而是根据名称拼写或插入空格来区 分的。 因此从下拉式列表中选取名称可以保证你所使用的名称和先前输入名称的一致性。 如 果在输入名称中稍微出错,则 Arena 会在首次运行模型时给出错误信息(更糟糕的情况是,
5

尽管模型可以运行,但结果却是错误的) 。 当新建一个模块时,Arena 会自动为这个模块赋上默认名和默认值。这些默认名是带有 附加序号的对象名称 (如模块、 资源等) 同一对象名称的附加序号是依次递增的, Progress 。 如 1,Progress 2,…。这样做是基于以下两个原因:其一是方便起见  你既可以接受默认资 源名称,也可以修改它;其二是因为 Arena 中无论对象类型一致与否,所有的对象名称都必 须是确定唯一的。 为帮助使用,Arena 做了许多自动命名工作,而其中的大多数读者都不必理会。例如, 当你单击查看队列数据模块就会发现,Arena 将零件 A 预处理区域的队列命名为 Prep A Precess.Queue。大多数情况下,你可以自己命名,而不必使用默认的名称。 当你选择两个包含 Seize 活动中的任意一个,并确认接受时,Arena 会在相关 Process 模块附近自动弹出一个动画队列(一个在右端带有小竖线的水平线) 。这种功能可以使你在 仿真运行时动画显示队列中等待的实体。如果单击此队列,就可以显示出该队列的名称。 第二个 Process 模块除了名称(Prep B Process) 、资源名(Prep B)和操作时间参数(3, 5, 10)外,建立过程都与前一模块一样。因此没有给出其输入界面。 下一步工作是给封装操作输入数据,这是我们放置的第三个模块。输入的对话框如输入 界面 4-6 所示。由于我们在上游的赋值模块中创建到达产品时,给它定义了 Sealer Time 属 性,因此当实体占用(Seizes)资源时,就会产生一个数值上等于 Sealer Time 属性值的时间 延迟。

输入界面 4-6. 封装对话框

我们利用第一个 Decide 模块实现封装操作之后的检测。由于只有“通过”或“未通过” 两个选择, 因此我们选用默认的类型 — 2-way by Chance。 这里需要在对话框中输入一个逻 辑为“真” (True)值的百分比,通过它来决定离开模块实体的去向。这个例子中,我们将 真值百分比输入为 9,这样就会有 9%的实体流向真值对应的分枝(这里的“真”值对应的 是未通过检测的产品) ,其余的 91%流向逻辑“假” (False)值对应的分支(即通过检查的

6

产品)1。通过检查的产品直接送去装运,而未通过的产品则被送去返工。Decide 模块的数 据输入如输入界面 4-7 所示。

原书 P111

输入界面 4-7. 封装检查对话框 接下来是建立返工活动的 Process 模块,Process 模块的数据输入如输入界面 4-8 所示。 这个模块除名称、资源名和表达式外,其余部分都与产品 A 和产品 B 的 Process 模块相似。

输入界面 4-8. 返工操作对话框

输入界面 4-9. 返工产品检查对话框

第二个 Decide 模块是用来分离返工合格产品与废品, 模块中的数据输入如输入界面 4-9 所示。我们用“真”值表示废品(20%)“假”值表示返工合格产品。 , 在定义了上述操作模块之后,接下来应该完成 Record 和 Dispose 模块了。我们仿真的 目的之一是获取资源利用率、队长、排队时间等统计数据。这三个统计数据可以利用每个需 要资源的带有活动选项的 Process 模块来实现(假设模块中的 Report Statistics 框被选中,这 可在 Run>Setup>Project Parameter 菜单中定义) 。我们还需要获得直接合格产品、返工后合 格产品以及废品的系统逗留时间 (cyclic time)Record 模块可通过累加器完成这些量的统计。 , 从下拉菜单中选择 Time Interval 类型,累加器默认名称与模块名称相同,这样 Arena 就会自
1

我们在本例中采用 True 表示未通过,而 False 表示通过。同样我们也可以将模型中的真值百分比设为 91 (再将模块的名称改为 Passed Sealer Inspection 就可以实现 True 表示通过、False 表示不通过的设定了) 。 7

动进行累加统计:统计产品到达时间(Arrive Time)属性值与它到达 Record 模块的时间之 差(即实体在系统中的时间) 。完成输入后的废品累加器对话框如输入界面 4-10 所示。 剩下的两个模块分别是 Record Salvaged Parts 和 Record Shipped Parts。由于它们几乎与 输入界面 4-10 中的 Record Scrapped Parts 模块完全相似,此处不再敖述。

原书 P112

输入界面 4-10. 废品记数对话框

最后的三个模块是对实体离开系统时做后续处理的模块。 当我们建立这个模块时, 可以 将所有实体都指向同一个后续处理模块(Dispose) 。后续处理模块的特征之一是在模块的右 下脚处有动画变量, 动画变量将显示仿真运行中通过这个模块的实体数量, 并且还可以显示 通过这个模块的实体在整个系统实体中所占的比例。 Scrapped 后处理模块的数据输入如输入界面 4-11 所示。我们默认选中 Record Entity Statistics 框,但当我们仅需要保留装运产品(包括返工后合格品)的实体流统计数据时,就 必须清除这个框的选项(选中保留其它两个后处理模块相应选项) 。这样操作后就可以只选 中需要进行自动统计的产品。只有确保 Entity 框是按照 Run>Setup>Project 参数进行选择的 前提下,才能获得这些统计结果数据。

原书 P113

输入界面 4-11. 废品 Dispose 对话框

可按照类似方法完成其他两个 Dispose 模块 Salvaged 和 Shipped 的设置。 你可能已经准备好运行这个模型了吧,尽管你已经完成了不少工作,但等你习惯 Arena 的使用后就会明白,在运行模型之前还必须花些时间完成其他一些准备工作。 这时候的模型的确可以运行,但开始运行后,Arena 不知道何时停止仿真!你必须通过
8

Run>Setup 为模型设定运行参数。Run Setup 对话框用五个表页的参数来控制仿真的运行。 第一个表是 Project Parameters(如输入界面 4-12 所示) 。在这个表中输入项目标题和分析员 姓名后,在 Project Description 部分可输入简要的项目描述。在 Statistics Collection 区,去掉 Entities 选项,因为在我们的分析中不需要这些数据(我们不需要按照实体类型对系统进行 统计) 。你也可以选中这个框来观察选择前后输出报告的差异。

原书 P114

输入界面 4-12. 项目运行参数的设置

设置仿真运行长度是在 Replication Parameters 表中完成的,这里我们将 Replication Length 设为 32 小时(4 个连续的 8 小时轮班) ,Base Time Units 选取 Minutes,其他域使用 默认值,设置完成后的结果如输入界面 4-13 所示。对 Run>Setup 中的其它三个参数表则使 用默认值:Run Speed,Run Control 和 Reports。你可以打开这些参数表来了解其中的参数选 项。 在运行新模型前,还必须进行最后的调整。由于我们有两种不同类型的产品,因此如果 在动画显示中能加以区别则效果就更好了。在基本操作面板中的 Entity 数据模块中,你会发 现两类产品的初始图像都定义为 Picture.Report 上,因此当我们运行模型时,所有产品在实 体的动画显示中都会出现同样的图标。

原书 P115

输入界面 4-13. 重复运行的参数表设置

单击产品 A 的初始图像单元格(Initial Picture),从列表中选择一个别的图片。这里我们 给产品 A 选择是蓝色球,而产品 B 选择的是红色球,以便在动画显示时可以方便地分辨出 两种产品,完成后的效果如输入界面 4-14 所示。如果你还想进一步了解这些图标的形状,
9

从屏幕上面的主菜单中选择 Edit>Entity Pictures 选项来打开实体的图形窗口, 这样就可以从 当前屏幕的左下栏中观察到图标的形状。我们在后续章节中还将对这一功能作进一步介绍。 最终建立的模型如图 4-3 所示。

原书 P115

输入界面 4-14. 实体模块

原书 P116 图 4-3 模型 4-1 的最终形式

4.1.3 运行模型
在运行模型之前,必须进行对模型加以检验,单击运行交互工具栏中 Check 按扭(√) , 或选择 Run>Check 命令,或用键盘上的 F4 键都可以对模型进行检验。如果庆幸的话,检验 完毕后会弹出一个小的消息窗口显示“模型中无错误或警告”(“No errors or warnings in model”);否则会弹出一个描述错误的消息窗口,这时你就需要选择 Find 选项(如果它可选 的话) 。这些功能将提示你 Arena“认为”可能出错的地方。建议读者有意往模型中加入一 个错误来验证这些功能。对这些功能的使用会随你所建立模型复杂程度的提升而增多。 如果模型检验无错,现在就可以准备开始运行仿真了。运行仿真的方式有四种,但我们 只讲解其中的三种。 第一种是动画仿真, 点击标准工具条中的 “运行” ( 按扭 ) 或 Run>Go ,

命令,或使用 F5 键都可以启动动画仿真。如果你还未检验模型,或是在检验之后又做了修 改,Arena 会首先检验模型,然后使用你的数据对模型进行初始化,再开始运行模型。为使 你的注意力集中于动画显示,Arena 在运行过程中隐藏了一些图形。不过没关系,这些图形 在运行结束前会重新出现(或者你可以在仿真过程中通过 View>Layers 命令来查看这些图 形) 。

10

如果你激活了屏幕底部的状态栏,就可以观察 Arena 当前的执行操作了。状态栏中主要 包含以下三方面信息:重复仿真次数,当前仿真时钟以及仿真状态。 仿真运行开始后,如果你想改变仿真运行速度,可以按“”键来加快仿真运行速度。 如果你按了其中一个按键的话,在状态栏左端就会 出现当前动画速度因子值。你还可以通过 Run Setup 对话框中的 Run Speed 表来控制动画速 度因子(Animation Speed Factor) :在这个表的选项中键入精确的速度因子数值。 在仿真运行过程中,可以使用运行工具条中的“暂停”按扭( )来暂停运行,或者

使用 Run>Pause 命令,或者直接用 Esc 键来暂停。这样可以暂时中断仿真运行,同时状态 栏中会显示“用户中断”(User interrupted)的消息。 在暂停模式下,可以双击一个实体动画打开一个 Entity Summery 对话框,这个框中罗 列着每个实体的属性值,因此暂停功能对于调试模型来说非常有用。此外,你还可以使用运 行工具栏中的“单步运行”按扭(>|)来实现实体在系统中的单步运行(即每步只运行一个 时间单位) 。如果想恢复仿真的“正常”运行,只需按下“运行”按扭即可。 上述的这种仿真手段尽管提供的信息量非常巨大, 但却需要较长的仿真时间, 而仿真运 行时间取决于动画速度因子。可以选择暂停并按下运行工具栏中的“快进”按扭( )加

快仿真速度,或者通过 Run>Fast-Forward 命令来实现这一功能,这样做可以使仿真在不更 新动画图象的情况下大大提高运行速度。 还可以在按下暂停按扭后, 重新返回到动画模式的 运行。 使用快进模式可以大大缩短仿真运行时间, 但如果你仅仅对仿真结果的数值感兴趣, 那 么可以干脆连动画效果一起关掉,选择 Run>Run Control>Batch Run(No Animation)命令就可 以实现这个功能。 通过 Run>Run Control 选项还可以设置其它一些运行时间选项。当选择 Batch Run(No Animation)选项并重新观察上级选项时, 你会发现在左侧多了个复选项: 选中此项并点击 Run 键,仿真运行速度会非常快。这种设置的唯一不足之处是当你想要恢复动画显示时,必须终 止仿真运行,重新设置动画显示后才能恢复。如果你的模型比较大且仿真运行时间较长,并 且你仅对数值结果感兴趣的话, 选用这个功能就非常合宜了: 这种模式比快进模式的运行速 度更快。 当你建立模型时, 可能希望多数的工具栏在窗口中方便可见, 但当你运行模型进行仿真 时,这些工具栏就会白白占用空间:因为仿真运行时并不激活这些工具栏。为此,Arena 专
11

门附带了组织工具栏:它会记录你建立每个模型时对工具栏的设置,因此当你开始运行后, 可以暂停运行后移去这些工具栏,仿真运行结束后,它们会重新出现在原先的位置上。

4.1.4 观察结果
如果选择 Run>Go 菜单(或者点“运行”按扭 ) ,你会发现仿真运行中,系统中除

了蓝球和红球(分别代表产品 A 和产品 B)之外,还会出现几个不断变化的计数器。每个 Create 模块、Process 模块和 Dispose 模块都各有一个计数器,而每个 Decide 模块会有两个 计数器。Create 模块、Dispose 模块以及 Decide 模块的计数器在实体离开该模块时自动增加 一个单位;而 Process 模块的计数器则代表了当前模块中的实体数,包括排队等待资源的实 体数与当前接受操作的实体数之和。如果你选择的是 Run>Fast-Forward 模式(或者使用 Fast-Forward 按扭 ) ,这些计数器就不再更新,直至仿真运行结束或你暂停并改变模型

运行的观察模式时才会更新。本模型计数器的最终运行结果如图 4-4 所示。 模型运行结束时,Arena 会“询问”你是否想查看结果。如果你选择 Yes,系统会弹出 一个总结报告的窗口(默认报告) 。当报告的首页出现时,你会发现一条内容为“无法获得 总结统计”(No Summary Statistics Are Available)的奇怪消息。这是因为在 Arena 系统中,系 统总结统计的是实体,而我们在“运行设置”对话框(输入界面 4-12)中的“项目参数” 表中没有选择 Entity 选择,也就自动放弃收集这些统计数据。因此,当你改变这些选项时, 请留意输出报告内容的改变。

原书 P118 图 4-4 模型 4-1 的动画结果

当你需要浏览报告内容时,可以通过左侧的“报告”窗口查看表内的树形列表,或是通 过报告窗口左上角的方向按扭( )来实现。这个报告提供了 Run Setup 对

话框选项中的分类统计量(在“项目参数表”“统计收集区”中定义) , 。在我们所建模型中, 你可以找到操作、排队、资源和用户指定等选项区域,之所以会出现用户指定区,是因为我 们的模型中包含了用于离开类型的 Record 模块的缘故。

12

同第三章一样,我们的统计报告中出现了三种类型的统计量:tally,time-persistent 和 counter 类型。当多次重复仿真时会出现第四个统计量(outputs) ,第六章讲解多次重复仿真 时再对这部分进行详细介绍。这里的记数型统计量包括我们 Record 模块所收集到的几个操 作时间、排队时间和间隔时间。时间持续型统计量包括队长,资源利用率等。计数统计量包 括累计次数,进入系统数,离开系统数以及总占用数量。 记数型统计量与时间持续型统计量提供了均值、置信度为 95%的区间半长、最小值和 最大值。正如前两章所介绍那样,除了区间半长外,上述这几项都一目了然。 在每次重复仿真结束时,Arena 都会用一种批平均(batch means) (详见 7.2 节)方法为 每个观测统计量的稳态期望值计算出一个 95%的置信区间。 Arena 首先检查是否收集了足够 多的数据,以判别能否满足使用批平均值法的临界统计假设(批量无关性) 。结果中会偶尔 出现这种情况:如果不满足该假设,则报告中会出现“不足(Insufficient)”的提示,且不会 产生置信区间半长;结果中还会出现几次这样的情况:如果检验批量无关性的数据足够多, 但未通过检验,则会出现“相关(Correlated)”的提示,同样也不会计算区间半长;此外,还 可能出现的情况是:如果有足够多的数据进行批量无关性检验,且通过了检验,则会产生一 个长期(稳态)期望值统计量的置信度为 95%的区间半长。如上所述,即便从纯计算角度 出发,可以计算出结果,但 Arena 会拒绝报告不可靠的区间半长值。这些检验的细节和重要 性将在 7.2.3 节作进一步的深入介绍。 如果通过这样的单次短时间的运行就想得出结论的话, 未免会出现偏差, 因为我们还没 有考虑类似运行长度、重复运行次数、甚至长时间稳态结果的合理性等问题(这部分内容将 在 7.2 节介绍) 。如果观察排队等待时间、排队等待数等结果的话就不难发现,返工操作因 等待时间和队长比其它操作时间过长而拖后 (你可以通过观察总结报告中操作和资源部分的 拥挤情况来证实这一失调现象) 。这就意味着,要么返工区没有能力处理它应完成的工作, 要么这个操作存在大量的可变性,我们将在下面的 4.2 节中考虑这个问题。顺便提一下,请 注意图 4-5,当多于一种类型的实体进入模型时(本例中的进入类型就不止一个) ,总结报 告给出的是一个平均值的图。

原书 P120 图 4-5 模型 4-1 的排队总结报告

13

4.2 Model 4-2: 改进的电子装配与检测系统
建立和运行模型后,接下来应该对“代码” (Arena 文件)进行验证以确保无 bug2,并 且对概念模型是否真实代表了我们研究的系统进行确认(见 2.7 节和 13.6 节) 。本例中模型 的验证和确认还算比较容易, 通过检查使用模块中的逻辑结构, 将他们与问题定义进行比较 即可;而对于大型复杂系统,这项工作就非常具有挑战性了。动画演示在模型验证和确认阶 段往往非常有用, 因为当它运行时, 你可以综观整个系统的构建情况。 运行我们建立的模型, 观察动画可以发现它呈现给我们的运行情况与我们希望描述的系统极为相似。 但如果模型验 证很困难的话,对它的完全确认(下一步骤)就会非常困难(甚至不可能进行确认) ,这是 因为“确认”暗含着仿真可以完全表现真实系统的运作行为,而如果真实系统不存在的话, 当然无法进行确认了。即便真实系统存在,你也必须从其中获取输出性能数据,以此来说服 那些和你一样持怀疑态度的人: 你所建立的模型是来源于真实系统, 它能对真实系统进行预 测。我们将在第 13 章对验证和确认两个步骤作更为详细的介绍。 现在, 当你把辛苦建立的模型及其运行结果交给产品部经理的时候, 她首先看到的是你 还没有给系统如何运作给出一个全面的定义。当初给出问题定义时仅考虑了单班操作的情 形,但现在的系统却是每天两班制,且第二班的时候会有两个操作员被分配给返工操作。这 也验证了我们当初预计返工操作能力不足的想法。 产品部经理清楚, 因为封装机器会时常出 现故障停顿,所以在封装操作中会出现故障情况(failure) 。工程师不久前检查了这个问题, 收集数据后确定了封装操作对系统的影响。 由于他们认为封装操作不是一个瓶颈操作, 因此 对它的故障改进不会对整个问题的解决带来明显的改善, 但他们还是记录了所观测的结果以 供其他人参考。假设两次故障间的平均间隔时间为 120 分钟,时间分布服从指数分布(顺便 提一句,如果故障在整个期间运行按照均匀概率发生,则通常使用实际的故障间隔时间模 型) 。修理时间同样服从均值为 4 分钟的指数分布。 另外,产品部经理暗示她考虑购买特殊的货架来放置那些在返工区域等待处理的产品。 假设每个货架上能放置 10 套产品的话,经理想知道应该购买多少货架比较合适。下面对模 型进行修改:增加使用三个 Arena 附加功能。 为了能将这些修改加入到已有模型中, 我们需要引入一些新的概念。 由单班运转改为两

2

当然,你可能对“bug”一词在计算机程序中指代错误的意思非常熟悉,但你确切知道这个来源于昆虫学 词源的词汇吗?自瓦萨大学著名的 Grace Murray Hopper 是最先在计算机中使用“bug”一词的学者,他用 这个词指代那些早期计算机继电器盘面板上触电而死的飞蛾,因为飞蛾的触电常常导致计算机短路。飞蛾 触电后的残骸图片见 http://www.cs.vassar.edu/images/Bug.GIF。 14

班运转非常容易,在模型 4-1 中,我们将运行长度设置为每班 8 小时,并且未对运行过程中 的每天轮班交接进行跟踪, 这是因为我们假设第一班末交接时的当前系统状态与紧接的下一 班初始系统状态完全相同, 并且假设交接不需要花费时间。 而我们现在需要建立明确的换班 模型,因为第一个返工班次中只有一个操作员,而第二班则增加为两个操作员。 我们通过给返工资源引入资源调度 (Resource Schedule) 的方式完成上述模型的改进。 资源调度通过调整资源能力来自动改变整个运行过程中的返工资源数量。 当我们做这些改变 时,还应该增加仿真运行长度,这样我们就可以完成两天以上的双班操作模型的仿真了。我 们使用资源故障(Resource Failure)来建立封装台故障的模型,这样我们就可以改变资源的可 用能力(与资源调度类似) ,同时还有另外表示设备故障的特殊功能。最后,通过频率统计 (Frequencies statistic)所获取的信息来决定需要购买的货架数量。

4.2.1 资源表示的扩展:调度与状态
到目前为止,我们建立的所有资源模型都是固定能力为 1 的单资源模型(预处理区域, 封装和返工) 。我们对资源模块中的这些信息采用的都是默认值。我们可以通过将返工资源 能力设置为 2 来实现增加的返工操作, 但这样的话我们就总有两个可用的操作员。 我们需要 做的是在第一个班次安排一个返工操作员(假设每班次为 8 小时) ,而在第二个班次安排两 个返工操作员。Arena 通过内部的调度结构可以实现这个功能,调度功能允许你在一段时间 内根据设定好的方式改变资源的可用能力。资源调度是与时间相关的资源能力改变序列。 我们还需要在模型中描述封装台的周期性随机故障情形。 同样可以使用调度 (schedule) 实现这个功能: 定义正常运转期间的可用资源能力为 1, 定义修理期间的可用资源能力为 0。 此外,Arena 还设计了专门的内部结构来描述故障。首先,我们先来介绍资源状态的概念。 Arena 自动定义了四个资源状态: (Idle) 忙 闲 , (Busy) 不可用 , (Inactive) 和故障 (Failed) , 为了作统计报告,Arena 对资源处于四个状态的时刻进行了全程跟踪。如果资源未被实体占 用,则称资源状态为空闲;一旦它被实体占用,则状态改变为忙;如果 Arena 使资源的分配 状态变为不可用, 则资源状态改变为不可用, 通过调度将能力改变为非 0 来结束资源的不可 用状态;如果资源不能被分配,则它会被 Arena 置为故障状态。 当出现故障时,Arena 使整个资源都变得不能使用,假若资源能力是 2,则在修理期间, 两个能力单元都会被置为故障状态。

15

4.2.2 资源调度
在将返工操作资源调度加入模型前,先来定义新的 16 小时工作日。在 Run>Setup 选项 中的“重复参数表”中将每天小时数(Hours Per Day)的值从 24 改为 16 即可(此处忽略了 关于日期的警告) 。在这个对话框中,还需将仿真运行长度时间单位(Time Units)改为天 (Days) ,再将仿真运行长度(Replication Length)设为 10 天。 可以在资源(Resource)或调度(Schedule)数据模块中定义资源调度,这里我们在 Resource 数据模块中进行定义。当你点击基本操作面板中的 Resource 数据模块时,屏幕底 部模型窗口中的电子数据表中会显示模块的当前资源信息。 点击返工资源栏的类型列, 从列 表中选择 Based on Schedule 后,Arena 会在电子数据表中自动增加两列:调度名称和调度规 则。因为能力由调度来确定,因此返工资源的能力单元格为暗灰色(不可设置) ;其它三种 资源由于能力固定,所以这两列单元格也为暗灰色。接下来,需要在返工资源的调度名称单 元输入调度名称(如 Rework Schedule) 。 最后,还需要选择调度规则(Schedule Rule),通过它来实施调度。调度规则有 Wait(等 待,默认选项) 、Ignore(忽略)和 Preempt(优先占用)三个选项。如果需要将能力减少 x 单位,且当前至少有 x 单位的资源处于空闲状态,则所有三种选项下都会立刻将 x 单位的资 源状态变为不可用状态;但如果当前空闲的资源不足 x 单位, 则调度规则将视选项情况而定 (图 4-6 对三种情况做了图示说明) : ■ Ignore 选项会立刻减少资源能力, 但正在进行的服务仍然继续 (不受资源减少的 影响) ,直到当实体释放资源单位后,这些单位的资源才会被置为不可用状态。 但若实体释放资源单位前,资源能力又已重新增加,则这一选项不会产生任何 作用。这个选项的效果是使实际资源能力调度的时间缩短了。 ■ Wait 选项在实际资源开始减少前,一直处于等待状态,直到操作中的实体释放 资源单位为止,因此资源能力减少的时间总是等于调度规定的时间,但两次时 间减少的间隔可能会增加。 ■ Preempt 选项优先从最近占用资源的实体手中将资源抢占过来。如果优先占用成 功,且一个单位的能力足够满足需要,则能力减少立即开始。被抢占资源的实 体将在 Arena 内部等待至资源重新可用,届时实体将被重新分配资源并继续剩 余的操作。这种方式提供了一种正确的调度和故障建模方式,因为在许多实际 情况下,当交接班或资源出现故障时,操作产品往往需要暂停等待处理。如果
16

优先抢占不成功或需要的资源单位多余一个, 则剩余的能力将使用忽略 (Ignore) 准则。

原书 P123 图 4-6 Ignore, Preempt 与 Wait 的说明

何时使用这些准则呢?我们推荐你仔细观察实际操作并选择最能资源能力下降或故障 真实情况的选项。 如果你所考虑的资源是系统的瓶颈资源, 则你的选择会显著影响系统得到 的结果。但当你不清楚实际情况,又没有严格指导方针时,本书推荐一些可能会有所帮助的 准则:首先,若能力减少的时段相对操作时间而言非常大,选用忽略(Ignore)选项比较合 适;若能力减少的时间间隔相对减少的时间段而言较大,建议选用等待(Wait)选项;本模 型中,我们选用的是 Ignore 选项,因为在多数情况下,操作员在离开前会完成他的工作。 电子数据表中的前四行如输入界面 4-15 所示(实际上右边还有一栏附加项,此处未显 示) 。还可以用对话框形式输入数据,该对话框可以通过鼠标右击 Name 栏中的返工单元后, 选择 Edit via Dialog 选项打开。

原书 P124

输入界面 4-15 Resource 数据模型:选择一种资源调度

在给调度命名、 指定了调度规则后, 还必须定义资源实际遵循的调度信息, 点击 “调度” (Schedule)数据模块,输入电子数据表的调度信息可以实现这一功能。表中会新增一行反 映我们新定义的返工调度(Rework Schedule)的内容。点击持续时间(Durations)栏可以打 开“图形调度编辑器” (Graphical Schedule Editor) ,它是一个输入调度数据的图形界面。横 坐标表示日历时间或仿真时钟(请注意,我们在运行设置(Run Setup)对话框中设置一天 工作长度为 16 小时) ;纵坐标表示资源能力。可以点击 x-y(坐标)位置来输入表示为天、 小时和资源能力值的数据。 这时会弹出一个代表此小时内期望能力的兰色实心条; 你可以使

17

用重复点击、保持或拖拽来完成前 8 小时数据项的输入,将第 9-16 小时段内的调度数据能 力值输入为 2。第二天的数据输入不是必须的,因为第一天的数据会自动在剩余的仿真运行 中重复使用。完成的调度如图 4-7 所示。可使用 Options 按扭将纵坐标最大值(能力)从 10 减小到 4;其它参数可用选项(Options)对话框来更改,这些参数有单位时间条(slot)的 宽度、时间条的数目以及调度是否从头开始重复或自始至终保持一固定能力水平等。

原书 P125 图 4-7 图形调度编辑器:返工调度

也可以使用鼠标右键选中 Schedule 模块电子数据表中的“时段”栏后,选择 Edit via Dialog 选项手动输入这些数据。选择这个选项后,首先输入调度名称,然后点击 Add 按扭 打开持续时间(Durations)窗口,定义组成调度(能力,持续时间)的数据对。本例中的两 组数据分别是(1,8)和(2,8) (参见输入界面 4-16) ,即在仿真开始的前 480 分钟能力 为 1,而其后的 480 分钟能力为 2,如此交替变化,直至整个仿真结束。还可以用多个(能 力,持续时间)数据对来准确描述系统,如可以在调度中添加操作中断和午饭时间等。一个 需要特别留意的警告或功能 3 是,如果实体未被赋予持续时间长度,则系统默认持续时间为 无限长。 这个功能可以让资源在整个仿真运行期间保持这个能力。 如果你已使用图形调度编 辑器来创建调度,然后打开对话框,你会发现系统已自动输入了数据。当模型中有非整数的 持续时间值或需要使用表达式输入的项目(如由随机变量生成的持续时间值)时,你就不能 使用图形调度编辑器了。

原书 P126

输入界面 4-16

Schedule 数据模块对话框

3

如果你有意利用这个特性,就称它为功能;如不小心出错,则称它为错误。 18

4.2.3 资源故障
调度根据换班、故障、休假、会议等因素有计划地改变资源的可用属性,而故障主要是 建立随机事件导致的资源不可用模型。 可以在资源或故障数据模块中给出故障的定义, 故障 (Failure)数据模块可以在高级操作面板中找到(如果项目栏中的这一项还没有的话,就需 要通过按扭 障数据模型。 在项目栏中选中“高级操作面板” ,从中选择 Failure 数据模块,双击鼠标来添加一行。 选择名称列中的故障名称,用一个有意义的故障名称替换它(如 Sealer Failure) 。接着在类 型单元(Type cell)中选择故障类型为基于记数型的故障(Count-based),或基于时间型故障 (Time-based)。基于记数型故障是当系统中有一定数量的实体使用过资源后触发故障发生, 这个触发数量是给定的数, 或者由表达式来确定。 基于记数型的活动在实际的工业模型中非 常普遍。例如,工具复位、清洁以及机器调整等活动都是基于操作产品的数量,而不是基于 过程时间。尽管人们通常不认为这些活动是“故障” ,但它们确实是周期性的,并且阻止了 产品占用资源。另一方面,我们也常常建立基于时间的故障模型,因为我们通常是按照时间 类型收集故障数据的。在我们的模型中,故障类型采用基于时间的类型,点击类型单元并选 择 Time 选项可以完成这项设置。这时,电子数据表右侧列中的内容会发生变化,以此来显 示两种选项之间数据要求的差异。 我们的正常运行时间 (Up time) 和停机时间 (Down Time) 分别服从均值为 120 分钟和 4 分钟的指数分布, 此外, 还需将正常运行时间单位和停机时间 单位从 Hours 转换为 Minutes。 下面介绍最后一个域,我们可以借助“指定状态” (State Only)中的正常运行时间定义 那些“计入”正常运行时间的资源状态。如果这个域采用默认设置,则所有状态都会被认为 是“正常运行时间” ,这个功能的使用依赖于建立模型的数据收集方式及日期选择方式。多 数故障数据是简单的日志数据,假如仅标识故障时间,则节假日、午餐休息时间和空闲时间 统统都计入故障时间, 此时用缺省值即可。 只有当故障间隔内的时间可以被直接与特定的状 态关联时, 你才需要选择这个选项。 许多时间设备供应商会提供基于实际操作时间的故障数 据,在这种情况下,你就需要选择这个选项,并将它指定为“忙” (Busy)状态。但提醒你 注意的是:如果你选择了这个选项,就必须用高级操作面板中的状态设定(StateSet)数据 模块来定义忙状态。 最终得到的封装台故障电子数据表如输入界面 4-17 所示。
19

或 File>Template Panel>Attach 菜单将其加入) 。我们首先为封装故障建立故

原书 P127

输入界面 4-17. 封装台故障电子数据表

完成了封装台故障的定义之后, 接下来需要将它关联到封装台资源上。 返回到基本操作 面板,打开 Resource 数据模块后,点击封装台资源行的故障栏,打开“故障”电子数据表 的另一个窗口。双击鼠标添加一行,从故障名称单元的列表中选择 Sealer Failure,然后从 Ignore、Wait 或 Preempt 三种准则中选择故障准则。这些选项与调度中的准则相同,你只需 做同样的选择即可。 接着返回到对故障规则选项的处理, 因为我们期望的正常运行时间 (120 分钟)远大于故障持续时间(4 分钟) ,因此我们选择等待(Wait)准则。最终的电子数据 表如输入界面 4-18 所示。如果你用同一个故障描述关联了多个资源,则它们可以使用同一 个故障名称。 尽管使用了相同的描述, 但它们在仿真运行过程中还是使用各自独立的随机抽 样。

原书 P128

输入界面 4-18 封装台资源数据模块:故障电子数据表

4.2.4 频率统计
频率是用来记录 Arena 中变量、表达式或资源状态随时间离散变化的发生频度。我们可 以利用频率(Frequencies)类型统计量来获取返工区域需要的货架数目信息。由于我们对等待 返工队列的状况特别感兴趣  需要购买多少个容量为 10 的货架来满足产品存放要求,因 此,我们关注各种情况下的队长值:队长为 0(即不需要货架) 、队长大于 0 小于 10(需要 一个货架) 、队长大于 10 小于 20(需要两个货架)等。 频率统计是由“高级操作面板”中的“统计” (Statistic)数据模块来完成的,单击这个 数据模块可以打开其电子数据表,初始表格是空白的,双击鼠标来添加一行。首先输入名称 Rework Queue Stats; 接着从类型列表中选择 Frequency, 默认缺省频率类型为数值型 (Value) 。

20

当选择类型时,报告表单元会自动给出与名称单元相同的名字:Rework Queue Stats,我们 在最后的报告中会得到到这个数据报表。 现在,还需要添加一个表示等待返工队列的表达式。为收集这些信息,我们需要了解表 示队长的 Arena 变量名称: NQ。我们可以从“基本操作面板”的“队列” (Queue)数据模 块中获知,队列的名称为 Rework Process.Queue,因此,我们输入的表达式为 NQ(Rework Process.Queue) 。此时你可能会问: “你想让我知道所有这些吗?”对于一个熟悉 SIMAN 仿 真语言的用户而言, 了解这些很简单; 然而对于新用户来说却未必需要全部了解。 庆幸的是, Arena 提供了一种你不必了解这些神秘词汇(如 NQ)就能建立三种类型表达式的简单方法。 将光标指到空白表达式单元,点击鼠标右键选择“建立表达式” 。这样就会打开一个如输入 界面 4-19 的 Arena“表达式构造器”窗口。 “表达式类型”的“基本操作变量”底下有“队 列” 子类。 “+” 点击 号打开扩展选项后选择 “当前排队等待数目” (Current Number in Queue) 。 完成此操作后会产生两个结果: 其一是在窗口右边出现队列名称, 其二是在窗口底部的当前 表达式显示出相应的队长表达式。在本例中,当前表达式是 NQ(Prep A Process.Queue) , 然而这还不是我们所想要的队列。从“队列名称”的下拉列表中查找并选择 Rework Process.Queue,点击 OK 后,表达式构造器所建立的表达式就会被自动输入该区域。 还可以用鼠标右键点击可输入表达式的区域来打开表达式构造器。 例如, 我们使用表达 式查询当前仿真时钟 (TNOW) 时, 可以使用表达式构造器中的函数按扭 (或使用键盘输入) 在窗口底部的当前表达式域内构造更复杂的表达式。 关于这一点的电子数据表如输入界面 4-20 所示。

原书 P129 输入界面 4-19 构建表达式对话框

原书 P130 输入界面 4-20 Statistic 数据模块

返工排队等待统计量的最后一步工作是构建我们希望显示值的类型, 这步操作是在窗口
21

最右端的类型(categories)栏中完成(点击“0 Rows”按扭打开电子数据表格,在该表格 中为每个类型添加一行) 。输入界面 4-21 显示了前三个数据项的类型信息。第一项为常值 0 (需要 0 个货架的情形) ;后续项分别表示一个货架、两个货架等。这里我们仅收集最多为 四个货架的信息,如果队列长度超过 40 的话,Arena 会在输出报告中创建一个越界类型。 在区间范围的描述中,请注意 Value 中的值不包含在此区间内,但上限值(High Value)包 含在此区间。例如,Value 为 10,High Value 为 20 的区间信息定义了一个严格大于 10、且 小于等于 20 的区间,即(10,20 ) 。

原书 P130

输入界面 4-21. 返工队列状态频率统计种类

在离开 Statistic 数据模块前,我们还需要收集有关封装台的信息。在运行当前模型后, 报告中还会包含封装台的利用率信息, 但它不会专门报告资源处于故障状态的时间长度。 我 们可以象输入界面 4-22 那样, Statistic 数据模块中增加一行来收集该信息。 在 此统计量的名 称和类型分别为 Sealer States 和 Frequency,选择其频率类型为 State。最后从资源名称单元 列表中选择 Sealer 资源,这样统计量就会统计出封装台的繁忙、空闲和故障三种状态。

原书 P131

输入界面 4-22. 封装台的状态统计数据模块

在运行模型前,我们推荐选择 Run>Run Control>Batch Run (No Animation)选项,这样会 极大地减少模型运行时间。 尽管选择 Run>Fast-Forward ( )模式会比上述模式速度稍微慢

一些, 但它也可以为你节省不少运行时间, 而且它的另外一个优点就是你可以随时暂停运行 来查看仿真运行情况。

22

4.2.5 模型 4-2 的仿真结果
表 4-1 给出了这个模型输出报告中的部分结果(最右列) ,以便与模型 4-1 进行比较。 除了两种利用率结果保留小数点后四位有效数字外(为使他们满足一定的精度要求) ,其余 数据均保留了小数点后两位有效数字。 本模型结果与 4-1 模型结果的差异,可以归结为以下几个原因:首先,本模型仿真运行 了 10 天,每天 16 小时(共 160 小时) ,而模型 4-1 运行了 32 小时;其次,本模型在封装及 返工资源的建模过程中,做了与模型 4-1 不同的假设;所有这些导致了内部随机数流的不同 (12 章将介绍更多这方面内容) 。 模型 4-1 与 4-2 中,产品 A 和产品 B 预处理部分的模型完全相同,而不同之处仅在于 仿真运行时间长度或随机性的差异。产品 B 的预处理排队结果相差显著,究竟是排队随仿 真时间推移变得拥挤,还是其他不确定因素,我们尚不得知(我们这里不探讨那些需要对输 出结果进行统计分析才能获知的原因) 。 表 4-1 模型 4-1 和 4-2 的输出结果 输出结果 平均排队等待时间 Prep A Prep B Sealer Rework 平均队长 Prep A Prep B Sealer Rework 平均系统逗留时间 Shipped Parts Salvaged Parts Scrapped Parts 资源瞬态利用率 Prep A Prep B Sealer Rework 资源均态利用率 Prep A Prep B Sealer
23

模型 4-1 14.62 29.90 2.52 456.35 3.17 3.50 0.86 12.95 28.76 503.85 737.19 0.9038 0.7575 0.8595 0.9495 0.9038 0.7575 0.8595

模型 4-2 19.20 51.42 7.83 116.25 3.89 6.89 2.63 3.63 47.36 203.83 211.96 0.8869 0.8011 0.8425 0.8641 0.8869 0.8011 0.8425

Rework

0.9495

0.8567

对于封装台来说,模型 4-2 的排队等待统计量(平均等待时间和平均队长)显示的结果 更为拥挤。 这是因为我们在模型中增加了封装台故障的缘故, 该故障模块使封装台不时退出 工作,因此导致了队长的增加。两个模型中的封装台利用率统计量无太大差异,尽管封装台 在故障状态时不可用,但计算封装台利用率时不考虑这个时段(故障状态) ,因此两个模型 的利用率统计结果相近。 与封装台不同,返工操作在模型 4-2 中看起来更平稳一些。因为我们在这个模型中给每 天的第二个 8 小时班次里安排了两个单位的返工资源, 这使得整个仿真时间内的返工操作能 力平均增加了 50%,而由 1 提高到 1.5。因此返工操作的利用率统计量呈明显下降态势(下 面会对这几种不同类型的利用率做更为详细的介绍) 。 观察三种离开形式的产品在系统内的平均逗留时间不难发现, 封装和返工操作的改变都 有各自的效果。 所有产品都必须忍受立即减慢的封装操作, 这也说明了为何直接装运产品在 系统内平均逗留时间产生了增加。 返工后合格品及废品则更快地通过返工操作 (或许未通过 检测会使它们感觉更良好) ,最终效果就是它们的系统逗留时间有显著下降。 现在我们讨论利用率的更多优点: 对每种资源而言, Arena 都会报告两种利用率统计量, 分别称为瞬态利用率(Instantaneous Utilization)和均态利用率(Scheduled Utilization) 。 ■ 瞬态利用率指在某个特定时刻点上的利用率(即,[该时刻点上处于繁忙状态

的资源数]/[该时候点上可用的资源数量]) ;然后计算整个运行时间内的时间加权平 均值,从而得到报告显示的值。如果在某时刻没有可用资源,则该时刻这个比率就 定义为 0。这是一个跟踪整个周期内各时刻利用率的统计量,但由于它在一定条件 下可能产生混淆的结果,因此必须小心使用。如果你喜欢数学,我们可以用如下表 达式来表示:设 B(t)是 t 时刻处于繁忙状态的资源数量,M(t)是 t 时刻可用的 资源数量(此处“可用”的含义是指不处于“不可用” (Inactive)状态,不论忙或 闲) 。令 U(t)= B(t)/ M(t) ,其中 M(t)>0。若 M(t)=0,则定义该时刻的 U (t)=0。如果仿真运行是从时刻 0 至时刻 T,则所得到的瞬态利用率为:


上式即为 U(t)函数的时间平均值。 ■

T

0

U (t )dt T

均态利用率是指在整个运行过程中平均处于繁忙状态的资源单位数相对于平

均可用资源单位个数的比率,均态利用率的计算公式为:

24

 
好在模型中时) 。

T

0 T

0

  M (t ) dt T 
B (t )dt T

T

0 T

B(t )dt M (t )dt

0

若资源根本不可用,上式分子被分母零除也没关系(唯一有意义的情况就是资源恰

在不同条件下, 这些利用率会提供不同程度的有用信息。 如果资源能力在整个仿真运行 期间保持为常值(资源不会出现不可用或故障状态) ,则上述两个利用率会保持相同(作业 4-19 要求你证明这一点,你也可以从表 4-1 中固定资源能力情况的数据验证这一点) 。如果 资源能力可变,且可用能力为零或一个正常数(如 1)时,瞬态利用率可以反映资源在整个 运行过程中的繁忙程度(能力为零的阶段被算作利用率为零的阶段) U(t)曲线可以反映 ; 出资源调度对资源请求的吻合程度, 因此它对评价参考计划非常有用。 报告中的均态利用率 则反映了资源在整个可用时间(即资源能力非零时间)内的繁忙程度。 例如,按照资源调度,资源在整个运行时间的 2/3 内可用(资源能力为 1) ,另外 1/3 时 间不可用(资源能力为 0) ,同时,假设在资源可用的时间内,它有一半时间处于繁忙状态。 在这个例子中,报告中的瞬态利用率为 0.3333,而均态利用率为 0.5000。这就反映了在整个 运行过程中资源在 1/3 时间内处于被利用状态,而在它可用时段内,有 1/2 时间处于繁忙状 态。因此,瞬态利用率小于或等于均态利用率。 我们有必要从其它方面来考察上述观点。如果你选择了 Wait 准则以外的调度准则,则 有可能得到一个大于 1 的均态利用率。例如,当你选择 Ignore 准则时,如果按照调度,资 源处于不可用状态; 而实际上资源处于被占用状态, 即资源能力变为 0, 但资源仍然被占用, 直到它被释放为止。比如你运行 10 小时仿真,按照调度资源仅在前 5 个小时可用,假如资 源在 0 时刻被分配到一个持续时间为 6 小时的活动。在时刻为 5 小时时,资源能力降为 0, 但资源仍然被占用,直到第 6 小时时才被释放。因此,报告中的瞬态利用率为 0.6(在运行 的 10 小时中有 6 小时处于被繁忙状态) ,均态利用率为 1.2(尽管按照调度只有 5 小时资源 可用,但它却被占用了 6 小时) 。 最后一种情况是,当资源被调度可变时,调度能力不仅仅只取 0 和另外一个正常数,而 。在这种情况下,即便报告中给出 是在整个运行时间内可以有多个取值(如 1、7、4,等) 了瞬态利用率,建议你最好不要使用它。因为受能力、持续时间和使用情况的限制,瞬态利 用率有可能小于、 等于或大于均态利用率 (作业 4-20 要求你对此进行证明) 在这种情况下, 。 我们建议使用频率统计量, 该统计量会给出关于资源使用情况的详细精确信息, 帮助主题 “资
25

源统计:瞬态利用率和均态利用率的比较”(Resource Statistics : Instantaneous Utilization Vs. Scheduled Utilization) 对此做了更多的说明。对于模型 4-2 的返工资源而言,建议采用 4-1 表中值为 0.8567 的均态利用率,而不要采用值为 0.8641 的瞬态利用率。 频率统计不属于通常总结报告的内容,你必须点击项目栏 “报告面板”中的“频率报 告”选项来获得这些信息。统计结果如图 4-8 所示。

原书 P135 图 4-8 Arena 频率报告:4-2 模型

第一部分表明,我们收集的统计量决定了返工操作需要的货架数量。在单次运行中,返 工队列长度均不超过 20(即需要三个或四个货架的数据列为空) ,队长超过 10 个的情况仅 占整个运行时间的 5.35%。这也就是说购买一个货架就足够了,至多需要买两个。封装状态 统计量给出了封装台分别处于繁忙、故障和空闲状态的百分比。 最后再提一下频率统计,即我们观察结果中的后两列。 “标准”和“受限”列的百分比 相同。 “受限”的含义是只统计某些指定状态的频率,例如如果不考虑封装台的故障状态, 则标准百分比会保持不变; 而受限百分比的值仅包含繁忙和空闲, 且它们之和也等于 100%。

4.3 模型 4-3:增强动画效果
这一章到现在为止, 我们仅仅使用了模块中默认的动画设置。 虽然这些基本的动画设置 对于决定所建立的模型是否能正确运行来说已经足够了, 但是实际中, 我们往往希望让决策 者所看到的模型更加接近实际的生产系统。 让模型更加真实其实很简单, 也不需要花费太多 的时间。从更深层次的角度来讲,你所花费的时间多少取决于你所建模型的详细程度,以及 你的模型的读者的类型。通常的统计表明,如果只是为了介绍的目的,你所陈述的对象在组 织中层次越高, 那么你应该在动画上所花费的时间就越多。 而且, 通过制作精美的动画效果, 你会发现许多乐趣甚至沉溺于其中。基于这种看法,让我们一起来看看我们能干些什么。 我们将从模型 4-2 中现有的动画开始,逐步增强其效果,修改之后的模型我们称之为模 型 4-3。现有的动画包括三个部分:实体,队列和变量。当一个实体从一个模块传送到另外 一个模块,或者在队列中等待的过程中,我们都可以通过实体数据模块来选择它。对于我们 设置的每一个操作模块,Arena 会自动生成一个动画队列,以显示运行过程中处于等待状态 的实体。对于我们设置的每一个操作模块,Arena 会自动设置变量,以显示处于模块内部或 者已经退出模块的实体的数量。
26

动画是伴随着模型中的模块生成的, 由于动画与模块的连带关系, 这里对动画的结构作 两点说明:第一,动画的名称,或者标识符,取自模块对话框的值,不能在动画对话框中直 接改变它。第二,如果移动模块,动画对象会伴随着一起被移动,如果你想在移动模块的时 候让动画对象保持原来的位置,只要按住 Shift 键即可。 有时候, 直接把动画对象从模型窗口中的逻辑区域里移到别的位置会非常有用。 如果这 样做的话,你可以考虑设置“命名视图”(Named Views)(见 3.4.13) ,以方便来回往返。如 果你想让一个动画结构与其最开始的伴随模块完全断开连接, 可以先将它剪切到剪贴板, 然 后再粘贴到原来的模块里。通过此操作,该动画结构会保持原来的所有特征,但是和模块之 间却不再有任何关联。 通过如下操作也可以实现上述功能: 先删除原来伴随着模块产生的动 画结构,然后从动画工具栏里再重新建立一个。 你可能想把一些自动生成的动画结构从其伴随模块中分离开来, 将它复制到别的动画对 象中。这里有一些规则:任何提供信息的动画结构(如变量和散点图)都可以被复制;在动 画中,显示实体活动的动画结构(如队列和资源)不要复制。原因很简单,如果两个动画队 列的名称相同,Arena 将无法判断应该是哪个动画队列来指示等待实体。虽然 Arena 允许你 复制动画队列,但是这样做的结果一般是在你最后设置的动画队列中会显示所有的等待实 体。 下面我们将分步讲述如何制作更完善的动画。首先介绍画面缩小功能。依次点击菜单 View>Zoon Out(或 按钮,或快捷健“-”,可以缩小模型的尺寸。现在点击一个队列, ) ,或快捷键 Ctrl+X) ,将其从所在模型中剪切出来,然后依 ,或快捷键 Ctrl+V) ,将其粘贴你想建立动画的区域(点击

依次点击菜单 Edit>Cut(或 次点击菜单 Edit> Paste(或

放置到相应位置) 。对其它的队列重复上述操作,并且让它们在建立动画的区域里大体按照 原来模型中的式样放置。现在,你可以对这个新的区域进行缩小操作,并开始制作动画。下 一步,我们将首先调整队列图形;然后给实体创建新的图形,并加入资源图形;最后,将加 入一些散点图和变量。

4.3.1 调整队列动画
如果你仔细观察一下整个动画, 你可能会发现, 在任何队列中可见的实体数量从来不超 过 14 个,即使实际上不止这些。这是因为在任何动画队列中,Arena 软件限制了其显示的 活动实体的数量,这个数量是在动画队列的绘图窗口里设定的。也许整个仿真的队列中有 30 个或者更多的实体,但是如果动画队列的绘图窗口里设定可显示的实体数量为 14 个,那 么刚一开始,在动画中只有前面的 14 个能显示出来,随着前面的实体移出动画队列,后面 没被显示的实体逐个显示出来。当队列规模相当大的时候,由于实体显示数目的限制,你很 可能会认为仿真系统没有正确运行,但是,最终的输出产品统计结果还是正确的。有三种比
27

较简单的途径可以避免这个问题: 第一是跟踪表示队列中实体数目的变量; 第二是增加动画 队列的规模(也就是增加了可显示的实体数量) ;第三是缩小实体图形的尺寸,当然前提是 能保证实体图形的准确外观。 首先,让我们增大队列动画的规模。图 4-9 显示了当我们修改队列动画时,进行此操作 的具体步骤。第一步单击需要修改的加工队列 Rework Process . Queue(视图 1) 。注意到这 时会在队列的首尾各出现一个长度调节符号。现在,你可以把光标放在最右端,这时候它变 成十字形。可以将其朝左右方向拖至你所需要的长度(视图 2) 。经过这个操作,当你再运 行仿真时,你就有机会看到一些的处于等待状态的实体。

P137

视图 1:修改的加工队列 视图 2:修改的加工队列 视图 3:修改的加工队列 视图 4:修改的加工队列

图 4-9

队列动画的修改

我们还可以改变队列中代表实体的实际位置的点的结构形状。 双击选定的队列, 会出现 队列对话框,如输入界面 4-23 所示。

P137 输入界面 4-23 首先需要选择队列中点的类型,点击其中的 Points 按钮。接着点击 Add 按钮增加相应 的点。 我们也可以改变实体在每个点的旋转角度, 但是目前还是用缺省值。 完成这些操作后, 队列将会显示成图 4-9 中的视图 3 所示的状态。可以看到,这时候队列的前沿(右端)会变 成被 2 个同心圆环绕的点。现在,你可以拖动这些点进行任意编队(见视图 4) 。如果你想 让所有的点排列整齐,你需要用到网格对齐选项(在第三章中讨论过) 。Arena 现在可以在 运行动画时将实体放在各个点上并向前移动,就跟真正的队列一样。 对于本例,我们只是将队列延长(如图 4-9 中视图 2 所示) ,从 Prep A 和 Prep B 一直延
28

长到封装区。我们还对队列动画作了一点花样变动。首先将队列的形式改成点状,然后加入 38 个点。最后,将所有的点排列成 4 排,就像 4 个传送带,如图 4-10 所示(如果打开网格 对齐功能这点不难做到) 。

P138 图 4-10 40 个点的动画队列

4.3.2 改变实体图形
现在,我们把注意力集中在动画中的实体上。在我们目前的动画中,先粗略地选择蓝球 和红球作为两种实体。我们想让这两个实体看上去很像真的球,而且里面还显示“A”和“B” 两种标签。依次点击菜单 Edit>Entity Picture,会出现图 4-11 所示的“实体图形设置”窗口, 你可以利用它来创建新的图形。 窗口的左半部分包括目前模型中的可用的实体图形, 显示形 式为一系列的包含图片和相应名称的按钮组成的列表。窗口的右半部分用来访问图形库 (picture libraries),图形库为存储了大量图形的文件。Arena 软件提供好几种图形库(文件名 后缀为.plb) ;在设置动画的时候,你可能会用到这些图形库中的内容。 有好几种方法可以给动画增加新的图形。你可以使用 Add 按钮(窗口左边) ,直接在现 有的图形列表中添加新的图形,或者也可以使用 Copy 按钮(窗口左边)在现有的图形列表 中复制一张图形。如果你使用“添加”功能,你添加的新条目既没有图片也没有名称,你可 以自己绘制一张图片,然后再在上面的赋值框里确定其名称。如果你使用“复制”功能,那 么新条目的图片和名称与其母体完全一样。 要想从图形库中选择一个图形添加到现有的实体图形列表中, 先点击左边图形列表中你 想替换的图形使其变亮, 再点击右边图形库中的新的图形使其变亮, 接下来点击 “左向箭头” 按钮( ) ,新的图形便从图形库中被复制到当前图形表中。你也可以创建你自己的图形

库:点击 New 按钮,绘制你自己的图形并保存,以备将来使用;或者使用基本的复制和粘 贴功能,从已有的图形中筛选一部分来创建你自己的图形库。

P139 图 4-11 实体图形设置窗口

29

同本书所讲的大多数其它例子一样,在这个例子中,我们选择的实体图形尽量简单,但 是你可以按照你自己的意愿决定实体图形的精美程度。 确定了蓝球和红球的尺寸之后, 让它 们作为这个例子的起点。点击已有图形列表中的 Picture. Blue Ball 图标,然后点击 Copy 按 钮,图形列表中便有了两个 Picture. Blue Ball 图标,选择其中的一个,在 Value 栏中将其命 名为 Picture. Part A。注意到当你在键入新的名称时,图表中的名称会同步改变。要想改变 图片,双击该图形图标,会激活图片编辑窗口,你可以在其中绘制修改图片。在修改图片之 前,注意到在图片编辑窗口的中心位置会有一个小的灰色圆圈,它是实体参考点(entity reference point),决定了选用该图形的实体与动画中其它对象的位置关系。在实体运动的过 程中,这个参考点基本上会与运动路径吻合,当实体占用某项资源时,它也会停留在占用点 的位置。 我们将对该图形作如下修改:在球的中心位置插入字母“A”,并选择一个较亮的填充色 填充,使得字母可见。现在如果关闭图形编辑窗口,新的图片将显示在其名称 Picture.Part A 的旁边。接下来按照上述步骤给 Part B 制作一张新的图片。最后的图形如图 4-12 中所示

P 139 图 4-12 最终实体图形 在关闭图形编辑窗口之前,你可能会注意到字母“A”和“B”并没有在图形名称中显示, 原因是图标上的空间不够。 不过如果你点击一个图形的图标, 其全称会在上部的赋值栏里显 示。另外,在图 4-11 所示的窗口的左下角,会看到一个尺寸因子(Size Factor)定义框。通 过改变尺寸因子定义框里的值,可以改变实体图形的大小。在本例中,我们将尺寸因子从 1 增加到 1.3。 最后一步是将这些新的实体图形分配到各自的实体对象上去, 以便于在动画中显示。 打 开 Entity 数据模块,在“初始图形”单元中分别输入新名称即可。你可能会注意到你输入的 新名称在下拉的图形列表中并没有显示, 所以你需要键入。 键入了新名称, 并输入数据之后, 它们将会显示在图形列表中。

4.3.3 添加资源图形
到目前为止,我们已经完成了队列动画和实体动画,下一步添加动画中的资源图形。在 动画工具栏中找到 Resource 按钮( )并点击,会打开“资源图形设置”窗口,外观看上

去跟“实体图形设置”窗口非常相似。这两个窗口除了进入方式的区别外,二者之间差别很

30

小。 实体获得图形是通过在模型中分配一个图形的名称; 而资源获得图形则依赖于它们的状 态。在 4.2.1 节,我们讨论过四种自动的资源状态(空闲,繁忙,故障和不可用) 。当你双击 资源图形符号打开一个资源图形设置窗口时,你可以注意到,对四种缺省资源状态,系统都 给定了缺省的资源图形。 同前一节里对实体图形的编辑方法一样, 你也可以打开缺省资源图 形的图形编辑窗口对其进行修改。 第一步我们需要确定制作哪一个资源图形。可在“标识符” (Identifier)栏的下拉列表 来选择一种资源(例如 Prep A)。现在,我们替换掉这些图形,采用的方法与实体图形一 样。双击“空闲”状态图形,可以打开图片编辑窗口。在其中的绘图工具栏里设置背景填充 色,将线条粗细设为 3,并改变线条颜色。需要注意的是要进行这些修改时,相应的设置框 必须点击变亮才行。图片编辑窗口中间的带十字交叉的小圆圈是“资源参考点”,跟实体图 形的图形编辑窗口一样, 它可以标识该资源与其它对像的相对排列位置。 将参考点拖到窗口 的中心位置,确认这张图片(直接关闭图形编辑窗口),回到资源图形设置窗口。现在来扩 充我们的图形库。点击资源图形设置窗口中的 New 按钮打开一个新的空图形库,选择刚才 创建的新图标,点击当前图形库区域(Current Library)下面的 Add 按钮,在按下“右向箭头” 按钮,最后点击“保存”按钮,输入名称,你的新图形库便被保存下来(名称如 Book.plb)。 我们现在以这张图形为基础来创建剩下的资源图形。 分别点击资源图形设置窗口左边的 “繁忙”状态图形的图标,以及右边的新图形库里的图形图标,使它们变亮,按下“左向箭 头”按钮,让繁忙状态图形和闲置状态图形一样。当动画运行的时候,其图形会处于该框的 正中间位置, 由此我们我可以知道他处于繁忙状态。 然后, 选择窗体下方的 “占用区域” (Seize Area),接下来将同样的图形复制到“不可用”状态和“故障”状态。打开这些图形的编辑 窗口,选择不同的填充色,以便动画运行时区分资源处于哪种状态(例如,用红色表示故障 状态,灰色表示不可用状态)。然后将这两个图形复制并保存在图形库中。经过这些操作, 最终的资源图形如图 4-13 中所示。最后,同样将尺寸因子设置为 1.3,这样资源就和实体保 持同样的尺寸。

P141 图 4-13 资源图形设置窗口

完成资源图形设置,返回到主模型窗口,屏幕上的指示光标会变成十字交叉线。将光标 放到你想放置资源的位置, 便可以在动画中放置新的资源 (顺便说一下, 记住保存模型文件) 。 你放置的新资源的图标可能比你想要的大, 拖动其一角作适当的调节便可。 资源图形同样包 含着一个对象——一个双重圆圈, 有一虚线与图形左下方的占用区域相连。 该占用区域是当
31

一个实体占用该资源时在资源中所处的位置; 如果需要, 可以将其拖到资源图形的中心位置。 现在运行一下动画, 检查一下实体图形和资源图形是不是你处在你想要的相对位置。 如果不 是 , 暂 停 动画 运 行 , 调整 占 实 体 在资 源 的 占 用区 域 : 先 显示 占 用 区 域层 ( 点 击 菜单 View>Layer),再将占用区域拖到想要的位置。调整好位置之后,关闭占用区域层,继续运 行动画。 如果你对资源 Prep A 的图形设置满意的话,接下来可以对其它的资源图形进行设置。 可以对余下的每项资源按照上述步骤逐项设置,或者直接将资源 Prep A 的图形复制并粘贴 到资源 Prep B 和封装器(Sealer)。只是如果采用后者,粘贴之后需要双击来打开资源图形 设置窗口,从标识赋值区域的下拉列表里选择相应的名称。 返工资源的图形也必须进行修改,因为在进行第二个轮班时其容量为 2。同样采用上面 的复制粘贴方法,只是在打开资源图形设置窗口的时候,需要编辑空闲状态图形,并在第一 个图形旁边或下面加入另外一个方块(依次点击菜单 Edit>Duplicate>copy, Edit>Paste)。 这样返工资源在第二个轮班时, 才有能让 2 个实体同时占用的空间。 将新的图形复制到你的 图形库中,以备创建其它返工资源图形时使用。最后重新命名返工资源,关闭窗口。 在初始资源动画里,占用区域只有一个,所以双击占用区域(Seize Area),点击 Point 按 钮,增加了第二个占用区域。跟点状队列一样,占用区域可以有任何数量的点,尽管点的数 量依赖于资源的容量。而且,占用区域也可以像队列一样进行排列。关闭该窗口,在两个资 源框中分别设置两个占用区域的位置。 现在的动画可能更接近于你印象中的生产系统的样子。你可以重新设置资源、队列、站 等的位置,直到复合你的要求。如果你是在模型 4-2 的基础上建立该动画的,现在你需要点 击菜单 Run>Run Control> Batch Run (No Animation)以取消该选项,从而可欣赏你精美的作 品。当然,你还可以在对象上添加文本标签,加入线条或框来指示队列或者围墙,甚至还可 加一些盆栽植物达到美化效果。

4.3.4 添加变量和散点图
我们需要完成的最后一个操作是给动画添加一些附加的动画变量和散点图。 这些变量用 来表示每项工序中的产品数量, 以及完工的数量。 这些变量我们可以从流程图模块中直接复 制粘贴过来。首先复制粘贴伴随 Process 模块的 4 个变量;将它们放到我们刚才制作的资源 图形下面即可。接下来重新定义它们的尺寸:点击一个变量使其变亮,拖动调节手柄调节变 量尺寸到满意大小。当然,你还可以双击变量打开变量窗口(图 4-14),重新定义变量的 格式,改变字体,变换颜色等等。

32

P142 图 4-14 变量窗口 接下来我们需要对其它 3 个变量进行同样的操作。 最后, 使用动画工具栏里的文本工具 来标识这些变量的名称。 现在让我们在返工队列中添加一个散点图来表示实体数量。 点击动画工具栏里的 “绘图” 按钮( ),打开绘图窗口。使用 Add 按钮输入返工处理队长表达式 NQ(Rework Process.

Queue)。回想一下在前面所介绍的创建频率信息的时候,我们采用过同样的方法。同样, 对其它的实体数量作相应定义,如输入界面 4-24 所示。

P143 输入界面 4-24 绘图窗口

P144 图 4-15 仿真时间为 5453.9644 分钟时的动画:模型 4-3 完成上述设置之后, 接下来你可能需要增大模型窗口中散点图的尺寸, 并将它移动到动 画窗口中别的地方。 现在动画才算是完成了,看上去如图 4-15 所示,该图是在仿真时间 5453.9644 分钟时 刻截取的。当然,最终仿真的数值结果应该跟模型 4-2 一样,因为模型 4-3 是以模型 4-2 为 基础,仅仅在动画方面作了修改得出的。

4.4 模型 4-4:含传输过程的电子产品装配与测试系统
本章到目前为止, 我们已经成功地研究了电子产品装配与测试系统, 但是假设了所有的 零件在各道工序之间的传输是瞬间完成的。现在,让我们放宽这个假设条件,认为在现在的 模型中, 所有的零件在各道工序之间的传输时间都是 2 分钟, 不考虑传输的方向 (来还是去) 。 而且,对于其它传输,如到达的零件传输到准备区,从封装台或者返工处出来的零件被传输 到别处去拆毁、 回收或者运走, 传输时间也是 2 分钟。 我们现在修改模型 4-3, 建立模型 4-4。

33

4.4.1 一些新的 Arena 概念:站和传送
为了在模型中考虑 2 分钟传输时间, 以及显示零件的运动, 我们需要了解两个新的 Arena 概念:站(Stations)和站间传送(Station Transfers)。建模时 Arena 以站来标识实际生产系统中 的特定区域。站可以理解为进行某道工序的特定场所。在本例的模型中,各种站包括零件到 达位置,4 个制造单元以及最终产品离开位置。每一个站都定义一个唯一的名称。站与站之 间的连接通过站间传送实现。 站间传送使得我们能够将一个实体从一个站直接送到另一站。Arena 提供了好几种不同 的站间传送方式, 对运动的限制来自于物料输送装置, 以及由实体类型决定的灵活的传输路 线。我们在这里使用的站间传送称作路径(Route),路径允许实体从一个站运动到另一个 站。我们在路径中假设站间传送需要时间,但是没有别的延迟(例如由于路径封闭或者物料 输送装置的故障等) 所有路径的传输时间都定义为常数、 。 随机变量、 或者更复杂的表达式。 一般认为站代表生产系统中的一个实际位置;然而在 Arena 中,站还可以包括模型中很 多其它的对象。我们先把这个问题放一边,来试试在 Arena 中当一个实体被传输到一个站时 会发生什么情况。 首先, 我们看看模型的逻辑部分——运行时将实体从一个模块移动到另一 个模块。正如我们在第二章中所介绍的,仿真的运行是通过实体来驱动的——创建实体,按 照一定的逻辑移动实体,当发生时间延迟时触发相应的事件,直到最后消除实体。从这个角 度来说,站间传输(路径)仅仅是导致时间延迟的另外一种方式。 当一个实体按照指定的路径和传输机制离开一个模块时,Arena 会在事件表上记录这个 实体,包括事件发生时间,以及路径上的传输持续时间(类似于一个延迟模块)。随后,实 体又会移出事件表,Arena 又让实体回到模型的逻辑流程中:寻找定义实体到达站的模块。 例如, 我们假设一个路径模块是用于将一个实体送至封装台的。 当实体离开事件表时, Arena 找到定义封装台的模块, 实体便被直接送入该模块。 这与我们目前为止所接触过的直接模块 连接有点微小的差别: 当实体从一个模块传输到另一个模块的时候, 实体并没有进入事件表, 两个模块之间只是从绘图上用线连接, 也就是实体在模块之间的传输是瞬间完成的, 没有路 径引起的延迟。 这种连接使得模型看上去像一个流程图, 实体在模块之间的传输路径很清晰。 而站间传送则是一种更强更灵活的手段来描述实体怎样在模型中传输,这部分功能将在第 7.1 节详细介绍。 站和站间传送也为模型动画的一个重要部分提供驱动力——当模型运行时, 显示实体在 站间的运动情况。对站定义标识符号后,站本身就可以看作模型的一种流程图模块。在模型 的绘图中, 设置站的位置也就代表着站间传送开始或者结束的地方。 实体在站之间的传输是 通过路径对象来定义的, 路径清晰的描述了站间的连接关系, 确定了实体进行站间传送的运 动路线。 你会很快能看到站点标记怎样定义一个到达站(一条路径的终点站)以及始发站(一条

34

路径的起点站)。可以使用动画传送工具栏(Animation Transfer toolbar)里的站对象(Station object)在动画里添加一个站。使用动画传送工具栏里的路径对象可以添加路径:画一条折线 代表实体沿着它们的路径运动时遵循的图上轨迹。 当仿真运行的时候, 你可以看见实体图形 流畅地沿着它们的路径移动。这样,一个新的问题产生了:怎样将这些路径与后台逻辑部分 对应起来?我们刚刚介绍过,当一个实体在路径上传输时(也就是处于路径延迟时间),实 体进入事件表。答案是,Arena 的动画“引擎”与后台逻辑“引擎”协调一致;当一个实体 在逻辑中遇到一条路径并进入事件表时, 动画里会显示实体的图形在站间的路径里移动。 两 个引擎互相协调一致,当实体结束动画里的路径移动时,实体同时推出事件日表,这样协调 一致的结果是逻辑里的任何时刻,动画里都有相对应的显示。

4.4.2 添加路径逻辑
由于加入了站这个对象,站间传送影响的不仅仅是模型,动画也需要作相应的改动。我 们从模型 4-3 开始。打开该模型,点击菜单 File>Save As,将其保存为模型 04-04.doe。先从 零件的到达开始。删除两个 Assign 模块与两个 Process 模块 Part A Prep 和 Part B Prep 之间 的所有连接。将两个 Create/Assign 模块一起往左移动,为添加路径相关的模块留出空间。 为了给读者一个预览,图 4-16 给出了我们的模型中这部分的最终修改结果,中间包含了新 添加的模块。

P146 图 4-16 零件到达的逻辑模块

Create/Assign 模块中的 Part A 和 Part B 到达部分保持原来不变。为了添加站和站间传 送,我们首先需要定义实体目前所处的站,然后确定实体至到达站之间的路径。先从 Part A 开始,设置一个“站”(Station)模块(从“高等运送”面板中添加)来定义 Part A 的位置; 如输入界面 4-25 所示, 输入站的名称为 Part A Arrival Station; 站的类型设为缺省值 (Station) ; 定义第一个站为 Part A Station。 通过这个模块定义了新站, 指定了零件到达的位置。 注意到, 站模块窗口中的“名称”(Name)定义框中的名称只是在模型窗口里显示,并不是对站本 身的名称进行定义。只有“站名”(Station Name)定义框里的名称才是定义站在模型中使 用的名称——Part A Station.

35

P147 输入界面 4-25 站模块 下一步我们来添加“路径”(Route)模块(从“高等运送”面板中添加),该模块将 到达的零件传输到 Prep A 区域, 传输时间为 2 分钟。 我们将定义模块名称为 Route to Prep A; 输入路径时间为 2,计时单位为分钟;站的类型设置为缺省值(Station);输入目标站名为 Prep A Station,如输入界面 4-26 所示。经过这样设置,结果是 Part A Arrival 中的任何零件 都会被送至我们即将创建的 Prep A Station(我们刚刚定义了该名称)。

P147

输入界面 4-26 路径模块

P148

图 4-17 预处理逻辑模块 对 Part B 的到达分支,我们作类似的设置。需要输入的数据项本质上跟前面一样,只 是在所有 Part A 出现的地方改用 Part B 代替 Part A(聪明的设计人员会直接运用复制功能, 并作一些必要的改动)。你可能注意到了,在两个路径模块之间没有直接的联系。前面已经 说过,Arena 将会很准确地按定义的信息将实体送入它们自己的路径。 现在,我们把注意力转移到预处理区域来做必要的修改,结果见图 4-17(几乎对所有 的数据项都作了小改动)。预处理区域中两个 Process 模块之前是两个站模块,这两个站模 块确定了新站的位置:Prep A Station 和 Prep B Station。除了模块名称和站名称,其数据项 与前面所讲的站模块基本上一样(见输入界面 4-25)。从零件到达区域沿着路径传送过来 的零件进入这两个站中的一个。接下来的两个 Process 模块保持原来状态不变。我们在后面 添加一个 Route 模块,两个预处理区域都连接到该模块。虽然两个预处理区域处于不同的位 置,从里面出来的零件都会被传送到同一个站——封装台。Arena 很清楚零件来自于哪个预 处理区域,Prep A 还是 Prep B。同样地,对于这里的 Route 模块,与前面设置的 Route 模 块相比仅改动了模块名称(Route to Sealer),以及目标站名称(Sealer Station)。 到现在为止, 你应该可以看出我们的模型修改还有哪些没有完成。 剩下的工作仅仅需要 我们改变一下模型的布局,在需要的地方添加站和路径模块。图 4-18 显示了模型的封装区
36

和返工区逻辑结构。我们采用与前面相同的名称来命名这里的站,包括封装站(Sealer Station)、返工站(Rework Station)、废品站(Scrapped Station),返工合格品站(Salvaged Station)、以及直接装运品站(Shipped Station)。 模型的废品区,返工合格品区以及直接装运品区的逻辑结构见图 4-19。

P148 图 4-18 封装区和返工区逻辑模块

P149 图 4-19 废品,返工合格品和直接装运品逻辑模块 此时,这一模型应该可以正确运行了。当然,你可能没有注意到现在的动画与以前有什 么不同,除了 Part B Prep 队列和返工队列比以前的模型长一些之外。如果你看一下仿真的 结果,你会发现零件的系统逗留时间与模型 4-2 和 4-3 相比都增长了,这是由于我们考虑了 运送时间。 你可能想知道一种简单一点的方法来建立非零运送时间的仿真模型——而不是像刚才 的模型中到处都是站模块或者路径模块,为什么不使用 Process 模块中,在 Action 栏选择 Delay,并且将延迟时间定为常数 2 分钟?实际上,这种方法是可行的,能够得出有效的输 出结果。然而,这种建模方法不能在动画中显示实体的运动,而动画恰恰是我们的一个要求 (简要地说,动画效果能够更生动)。所以,下面我们还是沿着原来的建模思路,在动画里 加入路径模块。

4.4.3 修改动画
在修改动画的过程中, 我们移动了模型中很多的对象。 如果你想让你的动画跟我们的相 似,你可以先看一看本书后面的图 4-20(当然,你还可以直接打开模型 04-04) 现在,我们来在动画里添加站和路径。先从添加动画里几个站的标记开始。从“动画传 送”工具栏里找到 Station 按钮( ),点击之后会打开如输入界面 4-27 所示的站对话框。

如 果 你 的 Arena 软 件 窗 口 里 还 没 有 打 开 “ 动 画 传 送 ” 工 具 栏 , 可 以 依 次 点 击 菜 单 View>Toolbars(或者在任何的工具栏区域里点击鼠标右键)来选择打开它。现在使用下拉 列表从已经定义的站中间选择我们修改的第一个站:Part A Station。当你接受了对话框的数 据后,鼠标指针变成十字光标。将十字光标放置于 Prep A 队列的左边,并点击添加站标记。 重复上述操作,将 Prep A Station 的标记放置于 Prep A 队列的上方。现在我们已经设置

37

了最开始的两个站,下一步添加路径。点击“动画传送”工具栏里的 Route 按钮(

),

会打开如输入界面 4-28 所示的路径对话框。对于本例的动画,对话框里条目的设置都用缺 省值,当然,你也可以点击不同的按钮选项来选择路径的特征。如果想知道别的路径选项的 含义,点击“帮助”按钮,选择感兴趣的条目,会显示简短的说明。完成路径对话框的设置 后,鼠标指针也会变成十字光标。将十字光标置于站标记内(Part A Station)的路径起点并 点击,路径便从这点开始。移动光标完成路径剩下的部分。当你再次将十字光标点击在另外 一个站标记内时(Prep A Station),路径会自动终止。

P150 输入界面 4-27 站对话框 如果这是你第一次设置动画路径, 你可能很急切地想运行模型, 看看到达的零件怎样从 Part A Station 移动到 Prep A Station 的。如果你对路径的设置不满意,可以很容易地修改。 例如,如果你点击 Prep A 队列上方的站标(或者,如果你选择菜单 View>Data Tips 中的选 项,仅仅需要在站标上晃动一下鼠标),站的名称(Prep A Station)会显示在站标的下方。 你可以将站标拖到你想要的任何地方(当然,不可能超出模型窗口)。注意到,当你拖动站 标的时候,路径会跟站连在一起移动。满足了你的好奇心之后,接下来设置 Part B 到达站 和到达 Prep B Station 的传输路径。

P150 输入界面 4-28 路径对话框 如果你添加完剩下的站和路径,你的动画就完成了。然而,从视觉的角度来看,你的动 回想一下我们将预处理站 (Prep A Station 和 Prep 画可能并没有准确的描述零件的流程路线。 B Station)放在处于预处理区域左半部分的预处理队列(Prep A Queue 和 Prep B Queue)的 上方。我们假设一下,在实际生产中,零件是从该区域的右边出去的。如果还用现在的预处 理站的话, 零件将从该区域的左边开始传送。 这个问题的解决方法很简单——只要在预处理 区的右边添加一个具有相同标识的逻辑站即可。当 Arena 需要给一个实体确定路径时,实体 会寻找路径的轨迹,而不只是寻找站。所以在创建剩下的路径时,对于每一个预处理区、封 装区以及返工区,你需要放置两个同样名称的站标。你最终的动画应该如图 4-20 所示。

38

P151 图 4-20 模型 4-4 的最终动画 最后,还有一个小地方你可能还没注意到。运行动画时,观察一下 Part B 的实体从到达 移动到 Part B 预处理区。需要注意的是,我们一次创建了 4 个实体,但是只看见一个实体在 路径上移动。现在注意一下当它们到达队列的时候会发生什么情况——它们突然又变回了 4 个实体。当它们出发的时候,它们确实是 4 个实体,只是在传输的过程中重叠在一起——它 们按照完全相同的速度被传输, 因为所有的实体的传输时间都是一个相同的常数。 你可以检 查一下:打开到达 Prep B 的路径模块,将路径时间由常数 2 改为 EXPO(2)分布,让实体的 传输时间不同。现在,当你再运行动画的时候,你会发现 4 个实体重叠在一起出发,然后分 开朝着队列移动。 你还可以通过大幅度增长路径来放大这个效果。 虽然这样能看到 4 个实体 的运动状态,但是却不正确,因为我们模型的假设是所有实体的传输时间都是常数 2(不过 你的老板可能不知道这个)。 这里有一个小技巧,既能遵守模型的假设,又能让动画看起来真实。如果我们将到达 Part B 的实体的图形设置为一个“批量”图形,就可以得到期望的效果。这样还是有 4 个实 体通过 Prep B Station,但是只有最上面的一个会显示。当一个实体进入准备区域的队列时, 我们只需要其图形还原成单个实体就行。为了达到这个目的,我们需要制作一个“批量”图 形,并在模型中作两处改动。 首先点击菜单 Edit>Entity Pictures,打开“实体图形设置”窗口。然后复制图形 Picture. Part B 将其另存为 Picture. Batch B。双击图形列表中该图形的图标,重新编辑图片。在编辑 图片时,使用复制粘贴功能,让图形成为图 4-21 中的形状;移动实体参考点到图形的中心 位置。然后关闭图片编辑窗口,点 OK 回到模型窗口。

P152 图 4-21 B 实体批量图形 现在我们有了批量图形, 需要告诉 Arena 什么时候应该使用它。 打开 Assign 模块 Assign Part Sealer and Arrive Time,添加另外一条赋值语句(因为这些赋值语句之间是相互独立的, 所以具体在什么位置添加语句没有关系)。这条赋值语句定义 Entity Picture 为 Picture. Batch B(因为这是该图形第一次使用,所以需要键入)。这样当实体从 Part B arrival 传输到 Prep B Station 时,Arena 会让实体显示批量图形。下面需要在站 Prep B Station,Prep B Arrival Station 和处理模块 Prep B Process 之间插入一个新的 Assign 模块(Assign Picture)。赋值语 句定义 Entity Picture 为 Picture. Part B(会在实体图形的下拉列表中)。这样,当实体进入 队列或者在 Prep B Process 中加工时,它们会显示成单个零件。 如果现在运行仿真(动画打开),你会发现一批实体被传输到 Prep B 区域,当批量进
39

入队列时, 又会变成单个实体。 定义不同的图形可以让你看到不同类型的零件在系统里移动。 虽然还是 4 张图形重叠在一起,但是新的批量 B 图形给我们展示了实体以 4 个为批量进入 系统。 现在你已经了解了有关路径的概念,我们将在第 7 章中更为复杂的系统中使用它们。

4.5 输入分析:确定模型参数及分布
我们已经有所体会,要创建一个仿真模型,需要设定大量的具体参数。可能刚开始你所 考虑到的只是模型的逻辑方面,如什么实体和资源,实体怎样进入及离开模型,它们需要哪 些资源,传输的路径怎样等等。这些活动称作结构建模(Structural modeling),因为它们只确 定你的模型是什么样子,以及用来做什么。 你也可能已经注意到, 在实际中设定一个模型时还需要考虑很多其它的关于数据或者数 学方面的东西(这样可能更具有普遍性)。例如在建立模型 4-2 时,我们将 Part A 的到达 时间间隔定义为均值为 5 分钟指数分布; Part B 预处理的时间为参数 (3, 5, 10) 的三角分布; 封装台的正常工作时间为均值 120 的指数分布; 返工操作处有不同数量的操作人员。 这种类 型的设定称为数量建模(quantitative modeling),对于仿真的来说与结构建模具有同样的重要 性。 那么对于模型 4-2(实际上也对于本书所有的模型),怎样获取这些数据和分布呢?这 需要观察实际生产系统 (如果存在的话) 或者使用相应的规格说明 (如果实际系统不存在) , 收集与模型输入有关的数据, 并分析这些数据或有关系统应如何运行的说明。 例如对于模型 4-2,需要收集实际中 Part A 的到达时间间隔,Part B 的预处理时间,封装时间,以及返工 区的实际员工安排(以及其它所有的定量输入)。然后通过观察这些数据,做一些分析,给 模型设定相对准确的、符合实际并且有效的输入。 在这一部分将主要讲述这个过程,教读者如何使用 Arena 输入分析器(Input Analyzer) 来进行数据拟合,分析数据服从什么概率分布。

4.5.1 确定型输入和随机输入
数量建模一个基本的方法是将输入数据设定为确定量 (常量) 或者服从某种概率分布的 随机变量,如返工区操作人员数量。当然,可能还需要反复运行仿真,以分析其对系统性能 的影响。 但是有时候情况并不是很明了, 我们只能建议如何尽可能与实际接近且有效。 本书 4.5.2 节将讨论怎样对模型进行敏感性分析(sensitivity analysis),以评价一个特定的输入对输出 结果的影响。敏感性分析可能使你不得不斟酌一下究竟是选择确定型输入还是选择随机输 入。 读者可能会被误导,认为确定型输入比较好,因为它看上去比较简单,而且优点是输出

40

结果也是确定的。这种观点是非常危险的,因为从模型的有效性角度来看,实际中的输入往 往都具有随机性,而且对于仿真模型来说,随机输入会导致一些很重要的系统行为。比如, 在一个单服务器队列中,可能会假设到达时间间隔刚好是 1 分钟,所有的处理时间恰好是 59 秒,这些数据可能与观察到的到达间隔和处理时间的数据平均值相吻合。如果模型开始 时服务台是空的,而且第一个到达时间是 0,这样永远都不会有顾客排队,因为每个顾客都 会在下一位顾客到达之前 1 秒钟完成服务离开。 但是, 如果实际中的到达时间间隔和服务时 间都服从指数分布,其平均值分别为 1 分钟和 59 秒(而不是前面所说的常数)。对于队列 长度会得出非常意外的结果(试着建一个小 Arena 模型并运行较长的时间)。实际上,经过 长时间运行, 处于队列中的顾客数目的平均值为 58.0167, 远大于 0。 这究竟是怎么回事呢? 在(正确的)随机模型中,有时候一些麻烦的顾客会需要很长的服务时间,或者好几个顾客 同时到达。正是由于这种随机事件的发生,使得队列长度急剧增大,而这些在确定型(不正 确的)模型中是永远都不会发生的。

4.5.2 收集数据
在建立仿真模型之前, 一个前期步骤是确定模型需要什么数据。 收集以及准备这些数据 是一件非常耗时而且昂贵的事情, 有时候会让人感到灰心丧气; 而且数据的可用性和品质会 影响建模方法和模型的所能达到细节水平。 此外, 还需要收集很多类型的数据。 大多数的模型都需要较为全面的关于时间推延的信 息:到达间隔时间,处理时间,传输时间,操作人员调度信息等。许多情况下,需要估计概 率,如某项操作的产出比、不同类型顾客的比例、以及一个打入电话者使用按键式电话的可 能性。如果所建模型中,实体的站间传送都是按照实际移动路线进行的,那么作业参数和物 料输送系统的实际布局也需要收集。 你可能会面对各种数据来源, 从电子数据库一直到与生产系统中的具体工人交谈。 总之, 为了给仿真模型收集各类数据,需要尝试各种方法,这也是一项挑战。 如果仿真所研究的实际系统存在(或者与其它某个实际系统相类似),读者可能会以为 收集数据的工作或许会轻松一点,因为有大量现成的可用数据。然而,最终可能会发现这些 数据并不是建模时所需要的。例如,一般认为从机器上收集加工时间(也就是一个零件从到 达机器一直到加工完成所需的时间) 对于仿真模型来说应该是一个很好的数据来源, 但是如 果观察收集的加工时间数据还包括排队时间和机器故障时间,这就与所建模型的逻辑不相 符,因为在本书的模型里,已经明确地将排队和机器故障同加工时间分开了。 另一方面,如果想对一个全新的系统建模,或者对现有的系统有比较大的改动,读者会 发现自己又处于另外一个极端状况,可能几乎没有任何数据可以使用。这种情况下,模型完 全依赖于设计者的粗略估计,以及设备商提供的数据等。对这个问题,本书将在 4.5.5 节中 给出一些建议。
41

不论是何种情况,都要决定需要收集哪些数据,下面几点提示对收集数据很重要:  敏感性分析: 进行仿真研究时往往容易忽视一个步骤, 就是对输入数据分析一下哪 些重要,哪些不重要。在一个项目的早期阶段,可以通过敏感性分析来评估输入数 据的变化对模型输出结果的影响。如果能较早获得系统某些方面的比较好的数据, 可以将不同范围的数据输入模型运行,看系统性能有没有显著改变。如果没有,就 不必花费大量精力去收集更多的数据, 而且对运行结果也应该抱有充分的信心。 如 果有显著性改变,要么想办法获得可靠的数据,要么最后的结论和建议粗略一点。  数据质量应与模型详细程度相匹配: 及早对输入数据的质量进行分析, 可以帮助决 定数据质量如何与模型逻辑的详细程度相匹配。 一个典型的例子是, 没有必要对系 统中数据不可靠的部分进行详细建模,除非你认为以后能获得更好的数据。  费用: 由于为模型收集和准备数据是一件非常昂贵的事情, 所以对某些数据可以做 一些大概估计。在进行估计时,敏感性分析非常有用,通过敏感性分析,可以大概 了解数据的取值对结果与建议有何种影响。  “如果进来的是垃圾,出去的将还是垃圾”:一定要记住,从模型得出的结果和建议 仅仅依赖于模型本身和输入模型的数据。 如果输入数据不是很准确, 那么对最终结 论也不应该有多少信心。当然,这并不是说如果没有“好”的数据,进行系统仿真 就完全没有价值。考察一个复杂系统的运行情况,分析系统因素之间的相互影响, 还是可以在一定水平上预测系统的运行情况。 但是必须要声明预测的可靠性依赖于 输入数据的质量。 最后需要提示一点,数据收集(以及对它们的一些分析)通常被认为是仿真研究中最困 难、代价最高、最耗时间和最乏味的工作,这得归咎于在收集数据的过程中可能会遇上的各 种各样的问题,而且收集数据也不可能像创建逻辑模型那样有乐趣。所以,在进行数据收集 时不要垂头丧气,要记住数据收集是仿真中非常重要的一个内容。

4.5.3 使用数据
即便拥有历史数据(如一台机器的故障修理时间纪录),或者知道系统的某部分是怎么 工作的(操作人员的调度计划),我们仍面临着怎样将数据应用到模型中去的问题。首先需 要选择的是, 直接使用所收集的数据还是先将它们拟合成概率分布。 究竟采用哪种方式取决 于理论分析和实际考虑。 从理论的观点来说, 所收集到的数据是过去发生的历史事件, 利用它们对未来发生的事 件作预测, 有没有偏差还很难说。 如果历史事件发生时的外部条件在现在或将来不再适用 (或 者随着时间的推移发生了改变),那么使用历史数据可能会产生偏差,或者会遗漏过程中某 些非常重要的方面。例如,如果历史数据来自于过去 12 个月的产品订单数据库,但是 4 个 月之前引进了一个新产品, 那么前面 8 个月的订单数据就没有什么用处了, 因为其中不包含
42

新产品。需要权衡的是:如果直接使用历史数据,仿真的结果可能除了重现一下历史之外没 有任何有价值的东西; 但如果从拟合的概率分布中抽取数据, 则有可能得到在实际中根本不 可能的数据 (例如, 从一个无界分布的尾段得到的值) 或者遗漏掉重要的特征 (如双峰数据, 序贯模式等)。 再从实际的角度分析, 可能没有足够的历史数据来让仿真模型运行足够长的时间, 以便 进行分析。这里需要考虑一下仿真运行时文件的存取对运行速度的影响,仿真运行过程中, 从一个文件读取大量的数据很明显要比直接使用一个概率分布慢得多, 所以使用历史数据可 能会减慢模型运行的速度。 不管做出什么选择,当模型使用历史数据时,Arena 会提供相应的内置工具。如果决定 将数据拟合成一个概率分布, 利用 Arena 的输入分析工具可以得到能直接在模型中使用的概 率分布表达式,这部分内容将在 4.5.4 节中介绍。如果想直接使用历史数据,可以一次将数 据转化为模型的数据结构,或者在仿真运行时动态读取数据,这部分内容将在 10.1 节中讨 论。

4.5.4 使用输入分析器拟合输入分布
如果要通过拟合概率分布来处理现有数据, 则既可以自主选择分布形式, 然后通过输入 分析器来提供相应的参数估计值; 也可以对数据拟合尝试很多种分布, 最后选择最适当的一 种。不论采用哪种方法,输入分析器都会提供参数估计值,以及一个现成的表达式,可以直 接复制粘贴到模型中使用。 当利用输入分析器对数据进行拟合时,它会估计该分布的参数(包括任何平移或偏移, 以便给出有效的表达式),并计算出一个测度值来反映该分布与数据的拟合程度。可以利用 这些信息来选择在模型中使用哪种分布。下面将对此进行介绍。 概率分布可以分为两大类:理论的(theoretical)和经验的(empirical)。理论分布(如 指数分布和伽马分布)基于数学公式产生样本,而经验分布是先将实际数据分组,再计算各 组中数值比例,为了更精确通常会进行插值处理。 每种分布都可以进一步分为连续(continuous)和离散(discrete)两种类型。Arena 提 供的连续理论分布包括: 指数分布、 三角分布、 以及前面提到的威布尔分布、 还有贝塔分布、 爱尔朗分布、伽马分布、对数正态分布、均匀分布和正态分布。这些分布都可以返回任何实 数值(在各自的定义域内)。在仿真模型中,它们通常被用来描述时间。泊松分布是一种离 散分布,它只能返回整数值。泊松分布通常用来描述一段时间间隔内发生的事件数量,或者 随机变化的产品批量大小。 经验分布同样也有两种: 连续经验分布和离散经验分布。 每种经验分布都表示成一系列 的概率/数值对,将所返回的数据表示成直方图形式。离散经验分布只能通过一定的概率返 回数据对中所包含的数值, 它们通常被用来分配实体类型。 连续经验分布根据概率返回实数
43

值。 当数据具有比较特殊的特征或者所有理论分布都不能很好拟合时, 此时只能采用连续经 验分布。 Arena 的输入分析器可以将数据拟合成上述的任何类型。然而,用户必须选择采用理论 分布还是经验分布, 不幸的是, 做这个选择没有任何标准的规则。 通常, 当数据的直方图 (输 入分析器会自动绘制)非常均匀或者只有“单峰”,并且没有任何大的缺口(在某个地方没 有值)时,就可能很好地拟合一种理论分布。但是,如果数据有很多的数值组都具有不同的 样式, 或者有很多数值组与其它的数值组的差别太大, 这时候选择经验分布可能会取得更好 的效果;如果不采用经验分布,一个替代办法是对数据分类,这个将在本节的最后讨论。 输入分析器是 Arena 所附带的一个标准工具,专门用来拟合观测数据,提供分布的参数 估计值,并评价拟合程度。使用输入分析器对输入数据进行拟合有 4 个步骤:     创建一个包含数据资料的文本文件 对数据拟合一个或者多个分布 选择合适使用的分布 将输入分析器生成的表达式复制到 Arena 模型中适当的区域

准备文本文件时,只需创建一个自由格式的包含数据的 ASCII 文本文件即可。任何文 本编辑器,如 word,spreadsheet 都可以使用。数值之间必须用至少一个“白色间隔符号” (空格,制表符或者换行符)隔开,除此之外,没有别的格式要求。每一行都可以输入任意 多个数据,而且每行的数据个数可以不同。使用 word 或者 spreadsheet 软件时,注意文件一 定要保存为“纯文本”格式。这样能消除任何可能会被包含进文件的特征,如章节格式等。 图 4-22 显示了一个名为 partbprp.dst(输入分析器默认的文件扩展名为.dst)的 ASCII 文本文 件,包含了 187 个零件 B 的预处理时间的观测值;注意到这些数值都是用空格或者换行符 隔开的,每一行的观测值的数目都不一定相同,而且数据的排列没有什么特别的次序。

P158 图 4-22 ASCII 文本文件 partbprp.dst 在对这些数据进行拟合时, 运行输入分析器 (选择 Arena 的菜单 Tools>Input Analyzer) 。 在输入分析器中,创建一个新窗口(File>New 或者 (点击菜单 File>Data File>Use Existing 或者 按钮),将数据文件加载到拟合窗口

按钮)。输入分析器会在窗口上半部显示数

据的直方图,在下半部显示所有数据的特征概要,如图 4-23 所示。

44

P158 图 4-23 partbprp.dst 的直方图和概要 通过拖动窗口中央的分割线可以调整窗口的相对大小。 如果想看更多的数据概要, 可以 向下拉滚动条。别的选项,如改变直方图的特征,在在线帮助里有详细说明。 通过输入分析器中相应的菜单选项,可以将数据拟合成某个的概率分布(也就是说,对 于给定分布来估计相应的参数)。完成拟合之后,分布的概率密度函数曲线会显示在直方图 的上方,其特征概要会显示在窗口的文本部分。(这些信息也被写入了名为 DISTRIBUTION.OUT 的 ASCII 文本文件,这里的文件名 DISTRIBUTION 是用户选择的分 布的名称,比如选择三角分布则是 TRIANGLE)。文本窗口中也给出了描述数据的表达式。 可以将表达式直接引入 Arena,选择输入分析器菜单 Edit> Copy Expression,打开 Arena 中 适当的对话框,将其粘贴(Ctrl+V)到希望的位置即可。图 4-24 显示了将文件 partbprp.dst 中的数据拟合成三角分布的结果。从图 4-24 的外观上看,用三角分布来拟合这批数据效果 不是很好,下一步我们将讨论拟合优度这个话题。

P159 图 4-24 partbprp.dst 的三角分布拟合 如果想在模型中采用理论概率分布,可以选择菜单 Fit>Fit All,它将对数据尝试所有可 用分布的拟合,计算每个分布拟合的检验统计量(下面会讨论),并显示具有最小均方误差 (一个衡量分布与数据拟合程度的量)的分布。图 4-25 显示了对于零件 B 的预处理时间的 Fit All 选项的结果,表明以最小均方误差来衡量,

  0.775,  4.29 ,向右平移 3 的伽

马分布的拟合效果最好。将该图与图 4-24 相比,很明显伽马分布的拟合效果比三角分布好 得多。下面将讨论究竟选择哪种理论分布的其它一些方面的考虑。

P160 图 4-25 partbprp.dst 的 Fit All 结果 如果想采用离散或者连续经验分布,则选择 Fit 菜单里的 Empirical 选项。首先需要调 整直方图的单元数量,它决定着拟合经验分布时,计算多少个概率/数值对。这可在菜单 Options>Parameters>Histogram 中选择时间间隔数来实现。 除了“目测”直方图顶端所拟合的密度函数曲线外,输入分析器提供了 3 个测度值来衡 量分布与数据的拟合程度, 以便于做出选择。 第一个量, 也是最容易理解的, 是均方误差(mean

45

square error),它是每个直方图单元均方误差的平均值。一个单元的均方误差是指观测数据 中该单元的相对频率, 与拟合的概率分布函数在该单元区间内的相对频率的差值的平方。 均 方误差值越大,表明拟合的概率分布与实际数据偏离得越远(也就是拟合程度越差)。如果 将数据对所有可用的分布都进行拟合, 所有分布拟合结果会按照均方误差从小到大的顺序列 出(选择菜单 Window>Fit All Summary),见图 4-26 中对 partbprp.dst 的所有拟合结果。可 以看出,伽马分布的拟合效果最好,紧接着的是威布尔分布,贝塔分布和爱尔朗分布,这几 种分布的任何一种作为输入应用到模型中,其精度都与伽马分布不相上下。 另外两个衡量分布与数据拟合效果的量是对拟合优度的  检验和 K-S 检验。二者都是
2

标准的统计假设检验, 用以评价一个理论分布与给定数据的拟合效果。 输入分析器会在文本 窗口显示检验的信息(见图 4-24 和 4-25 的底部) 。其中需要特别注意的是相应的 p 值 (Corresponding p-value) ,其取值范围在 0 和 1 之间 4。p 值越大,说明拟合优度越高。如果 p 值小于 0.05,就说明分布与数据得拟合程度很差。当然,同任何统计假设检验一样,光凭 一个较高的 p 值并不能说明拟合程度很好——这只说明没有足够的证据拒绝这一拟合。

P161 图 4-26 partbprp.dst 的所有拟合结果 在选择分布的时候,一般没有严格的、普适的方法可以帮助选择“最好”的分布。不同 的统计检验方法(如 K-S 检验和  检验)会导致不同的拟合评价结果,或者数据准备的形
2

式不同(如直方图的单元数量不同)也会得出不同的拟和评价结果。 首先需要选择的是采用理论分布还是经验分布, 利用 K-S 检验和  检验会有一定帮助。
2

如果一个或者更多的拟合分布的 p 值非常高 (比如 0.10 或更高) 那么就可以采用理论分布, , 并且应该有充分的自信认为理论分布可以很好地表示数据样本 (除非样本太少, 这种情况下 假设检验对拟合程度的辨识能力很差) ;如果 p 值都比较低,那么最好使用经验分布,以便 能更好地拟合数据的特征。 如果采用理论分布,通常会有几个分布的拟合优度很相近。这种情况下,需要使用别的 方式来决定究竟选择何种分布。  首先,根据对数据在模型中使用情况的了解,可以考虑有界分布或者无界分布。例 如, 对于加工时间数据, 有界的三角分布和无界的正态分布通常会有同样的拟合效 果。经过长时间的仿真运行,它们可能会得出相似的结果,但是在仿真运行的过程 中,正态分布会周期性地返回很大的数值,这在实际生产系统中是不可能发生的。
4

相应 p 值更准确定义:如果将拟合的分布作为“正确”的参照,相应 p 值是能够得到比现有数据集合与 所拟合的分布更加不一致的另一个数据集合的概率。 46

一个均值接近 0 的正态分布被用于一个非负的变量(如时间)时,可能会返回大量 的 0 值样本(当负值没有意义时,Arena 会自动将所有负值变成 0,如到达时间间 隔或者加工时间);这种情况下就不能使用正态分布来表示非负的变量。此时,采 用三角分布对边界进行限定, 可以完全将那些无关的数据样本排除在外, 可靠地表 示仿真模型中的变量。  另外一个考虑是从实际运用的角度。 也就是说, 有一些分布的参数调整要比其它分 布容易得多。如果计划对模型作一些改变,包括调整概率分布参数(例如为了进行 敏感性分析或者分析不同的场景),可能更倾向选择容易调整参数的分布。例如, 在表示到达时间间隔时, 威布尔分布和指数分布具有相似的拟合效果, 但是要想改 变到达时间间隔,对于指数分布,可以直接调整它的平均值;而威布尔分布的参数 却很难调整,因为它的平均值是一个复杂的函数。  如果担心自己的选择是否正确, 可将每一个选项都用在模型中运行一次, 看看结果 有没有很大的差异(当然,这样可能不得不等到模型快完成的时候才能进行,而这 时模型的结论几乎都已经出来了) 如果想进一步研究哪些因素影响分布的拟合效 。 果 (如拟合优度检验) 可以参考 Arena 的在线帮助或者别的资源, , 如文献 Pegden, Shannon, and Sadowski (1995)或者 Law and Kelton(2000)。否则,就按照上面 所讨论的两个方面来选择。 在结束对输入分析器的讨论之前, 再来回顾一下前面提到的一个问题: 如果数据包含有 多个峰值,或者有一些很极端的值,有时候称之为离群值(outlier),这时该怎么处理呢? 用任何标准的理论分布拟合这种类型的数据都很难有好的效果。 就如前面所提到过的, 一种 解决方法是采用经验分布, 只要数据的样本数目不是很少, 采用经验分布可能是最好的途经。 如果遇上有离群值的情况,首先应该做的是回去检查数据是否正确,而不是由于某种失误, 如排版或印刷错误造成的; 如果数据中得离群值看上去是错的, 而且又无法回去确认或者更 正,那么就直接删除。 不管是多峰还是离群值(正确的)的情况,都需要考虑在把数据读入输入分析器之前, 先将整个数据集合分解成两个(或更多)子集。例如,假设拥有机器停工时间的数据,并且 从直方图里注意到有两个明显的峰值,也就是说数据是双峰的(bimodal)。回去查看原始 记录,发现这些停工时间来自于两个不同的情况——故障和检修。则将数据分成两个子集, 可以发现由于故障导致的停工时间一般要比由于检修导致的停工时间长, 也就说明了两个峰 值存在的原因。于是在将数据导入输入分析器之前,可以先将其分成两部分,然后对两部分 数据各自拟合分布,最后需要对模型作一些修改,以解决这两种不同的机器停工。 当然,还可以采用别的方法分类,在输入分析器中纯粹按照数值的大小来分。装载了数 据文件之后, 选择菜单 Options>Parameters>Histogram, 定义低值和高值(Low Value and High Value)的分界线,这个分界线也就是整个数据集合分成子集后的边界。对于双峰数据,应该
47

将左边的峰值定义在低值子集里, 对应的右边的峰值定义在高值子集中, 两个子集的分界线 应该定义在两个峰值之间的最低谷。 然后分别对每一个数据子集拟合最适合的分布来代表那 段范围的数据(或者使用 Fit All 选项)。如果在对数据进行低/高值子集分割之前,已经拟 合了一个分布(或者使用 Fit All 选项),那么进行分割之后再来对两个子集分别拟合,很 可能会得出不同的结果;如果是使用 Fit All,最后结果会显示用两种分布结合在一起来代表 整个数据可以取得比较好的效果。 出于实际应用的考虑, 因为将整个数据分割成子集再进行 拟合这个过程很繁琐,所以在进行分割时,子集数目最好不要超过 2 到 3 个,而且最好的分 界线在哪里往往不是很明显。 进行子集分割以后, 如何在仿真模型里使用整个数据集合呢? 一个方法是随机选择一个数据子集, 子集的选择概率可以依据其相对大小来确定, 然后根据 所选子集对应的分布来返回一个数据值。例如,你的双峰数据集合一共有 200 个数据,包含 左峰的低值子集有 120 个数据,包含右峰的高值子集为 80 个数据,那么仿真模型在选择数 据的时候,选择低值子集对应的分布的概率为 0.6,选择高值子集对应的分布的概率为 0.4。 单个 Arena 模块无法自动实现这种操作,所以必须自己将某些对象融合在一起。如果数据是 活动时间,如实体引发的时间推延,一种途经是使用 Decide 模块,其类型可以是 2-路径选 择或者 N-路径选择,可选路径的数量也就是分割的数据子集的数量,利用 Decide 模块选择 了从某个子集获取数据后,再连接一个 Assign 模块将数据赋给实体,在模型后面的部分如 果有类似的问题也可以继续采用上述方法。 另外一种方法是对整个问题建立一个 Arena 表达 式。表达式将在 5.2.3 节介绍。

4.5.5 没有数据的情况
不管希望与否, 总有时候你无法得到模型输入所需要的可靠数据。 有好几种情形会导致 这种问题,如实际系统根本不存在,收集数据太昂贵或者数据支离破碎,还有一种可能是没 有相应的协作关系去收集数据。 面对这种情况, 你可能不得不依靠一些相当武断的假设或猜 测,我们将其堂而皇之称作“特别的数据”(ad hoc data)。在这里,我们没有任何重大结 论可以给你,但还是有些人提供了一些有用的建议。不管做什么,对于这些特别的输入数据 必须要在一定程度上进行输出的敏感性分析, 以便把握最终结果的可信度。 可以精选一些确 定性数据在模型中使用(或者用不同的输入值多次运行模型),还可以使用概率分布作为输 入。 如果输入数值是时间推延之外的其它量,如概率、操作参数或者物理布局特征,可以选 择常数、确定值、或者在某些情况下使用概率分布。如果给模型输入确定的常数(例如,故 障概率为 15%),就非常有利于进行敏感性分析,分析参数对模型的结果有什么影响。如 果参数的细微变化都能影响系统性能,就需要明确地分析参数在一个范围(可以包括小,中 和大)里的变化对系统的影响,而不是仅仅根据猜测。 如果数据是时间推延,那么几乎可以肯定,应该使用概率分布来反映活动的内在变化。
48

使用何种分布取决于活动的特性以及数据的类型。 选择了分布之后, 还需要给出适当的参数, 当然,只能凭借对整个过程的变化特性的估计。 当在没有经验数据的情况下选择分布时,可以先看看几种常用的分布:指数分布、三角 分布、正态分布和均匀分布。这几种分布的参数便于理解,并且可以反映比较广泛的数据特 征,见表 4-2 所示。 表 4-2 可能的无数据概率分布
分布 指数分布 参数 平均值 特征 变化幅度大 左边有界 右边无界 三角分布 最小值,众数,最大值 对称或非对称 两边都有界 均匀分布 最小值,最大值 所有数值等可能出现 两边都有界 对过程几乎不了解 可用实例 到达时间间隔 机器无故障时间 (故障率为常数) 活动时间

如果时间数据的变化是独立的(也就是一个数据值不影响下一个),平均值的估计不是 太大,并且时间数据的波动比较大,则指数分布可能是一个不错的选择。它通常用来表示到 达时间间隔:例如顾客进入餐厅,或者到达仓库的需求。 如果时间数据代表活动,而且存在一个“最可能出现”的时间,其它的时间在其上下波 动,则通常使用三角分布,因为它可以很好地反映数据小幅度或者大幅度地变化,而且它的 参数很容易理解。三角分布的参数有最小值,众数以及最大值,这三个参数可以很明了地估 计一项活动所需时间的变化特征。 三角分布的优点是允许数据在众数周围非对称分布, 这种 情况在实际中很普遍。 三角分布也是一个有界分布——没有数据可以小于最小值, 也没有数 据能大于最大值 读者可能会疑惑,为什么不谈最常用的正态分布,正态分布为“钟形曲线”,参数为平 均值和标准偏差。正态分布返回的数值在平均值两边对称分布,而且是没有界的,这就意味 着如果使用正态分布偶尔可能得到一个很小的数, 也可能得到一个很大的数。 当分布所代表 的变量不能为负值时(如时间延迟),Arena 会自动将正态分布返回的负值变为 0;如果拟 合的正态分布的平均值很接近 0,使用正态分布不是很合适,因为将近一半的返回值都会是 0。 当然,还有另外一种情况,平均值为正数,而且比标准偏差大很多,那么返回的数值为 负的可能性很小,比如可能只有百万分之一。虽然这个可能性看上去很小,但是如果仿真运 行很长时间的话,百万分之一的可能照样会发生,特别是现在的计算机运算速度越来越快, 而且由于变量如果不能为负时,Arena 会自动把返回的负值变成 0,这样可能会导致一个有 害的或者极端的活动, 从而最终使仿真结果无效。 4-27 显示了一个很小的 Arena 模型 图 (模
49

型 4-5),实体到达时间间隔为 1 小时,实体接着进入两个记录模块之一,具体进入哪个模 块这样确定:引进一个平均值   3 ,标准偏差   1 的正态分布,当正态分布的返回值为 负数时,实体进入一个记录模块;返回值非负时进入另一个记录模块,记录模块专门记录进 入各自的实体的数量, 也就是记录了正态分布返回值为负数和非负数的数量 (模型的分析留 给用户自己)。表 4-3 给出了标准偏差   1 ,平均值  取不同值时的运行结果。可以看出, 不管平均值是标准偏差(>0)的 3 倍还是 4 倍(或更高),正态分布还是会返回负值。使 用电子正态分布表, 可以计算出返回负值的精确概率, 还可以得出返回一个负值至少需要的 次数的平均值。表 4-3 中的每百万次计算,用普通的 2GHZ 的笔记本电脑大概需要 6 秒钟时 间,完成所有的计算总共花了不到 1 分钟。表中最后一行的  之所以那么取,是因为这时 刚好大概 1 百万次运算返回一个负值(试验中前 1 百万次运算没有返回一个负值,但是 1 千万次中出现 7 次与 1 百万次中出现 1 次已经相当接近了) 我们当然尊敬高斯这位伟大的 。 数学家(是他发现正态分布的),但是由于上述原因,当要表示非负变量(如加工时间)时, 一般不建议选择正态分布,尽管 Arena 允许使用它。如果数据集合跟正态分布吻合得相当好 (甚至是最好),可以使用别的分布以避免负值的出现,如威布尔分布、伽马分布、对数正 态分布、爱尔朗分布、贝塔分布,或者还有可能使用经验分布,同样能达到几乎差不多的拟 合效果,而且还可以避免产生负值的风险。

P166 图 4-27 模型 4-5:用于统计正态分布产生的负观测值 表 4-3 采用标准偏差 =1 的正态分布返回负值的统计
平均值 运算次数 返回负值数目 返回值为负数的准确概 率 3.0 3.5 4.0 4.5 4.753672 1,000,000 1,000,000 1,000,000 1,000,000 10,000,000 1,409 246 37 3 7 0. 001350 0.000233 0.000032 0.000003 0.000001 返回一个负值的最 少抽样次数 741 4,298 31,560 294,048 1,000,000

最后,如果对系统过程真的不怎么了解,但是可以猜测变量可能的最大值和最小值,就 可以选择均匀分布。

50

4.5.6 非平稳到达过程
非平稳到达过程是一种比较特殊的情况,但是很值得重视,因为实际中经常会发生,是 有效描述系统行为的非常重要的方式。许多系统都依赖于外部到达,如一些服务系统、电话 呼叫中心、以及有外部顾客需求的制造系统等,到达过程会随着时段的不同有很大差异。例 如午餐时间赶制各种汉堡包, 在下午的中间时段对技术支持热线的呼叫会更加繁重, 以及在 某些季节对生产制造系统存在大量产品需求。 对于这类问题, 非平稳泊松过程 (nonstationary Poisson process) 非常有用, 而且经常能够提供一种精确地反映随着时间而变化的到达模式。 此时需要处理两个问题:怎样估计或确定到达率函数,以及怎样在仿真中建立到达模式。 有很多方法可以从数据里估计或确定到达率函数, 有些方法可能比较复杂。 这里主要介 绍一种比较简单的方法,称之为分段定常速率函数(piecewise-constant rate function),它在 很多软件里都有很好的应用。首先,确定到达率比较平稳的时段长度,例如,一个呼叫中心 的到达情况在每半小时的时段内可能比较平稳, 但是在不同的时段会不一样。 累加每个时段 内的到达数量, 然后对每个时段计算不同的到达率。 例如, 假设呼叫中心在上午 8:00 到 10:00 这 4 个时段接进的呼叫数依次为 20, 35, 和 50, 45 那么每个时段的到达率如果以 “次/分钟” 来表示,就分别是 0.67,1.17,1.50,1.67。 一旦按照这种方式估计了到达率函数, 就需要确认一下 Arena 是否按照这种模式在模型 中产生到达。Create 模块可以实现这一点,只要将到达时间间隔的类型定义为 Schedule,然 后通过 Schedule 数据模块来安排到达率函数,类似于 4.2.2 节中对资源调度的设置。这里需 要注意一点:Arena 允许将任何时间单位混合和配合使用,所以必须小心定义时间单位,以 免出错。本书将在第 5 章建立这个模型。在第 12 章,还将进一步讨论对到达率函数的估计, 以及 Arena 中非平稳到达生成方法的基础。

4.5.7 多变量与相关输入数据
对绝大多数的时间数据,不管它们服从什么分布,我们都假设它们是独立生成的。有时 候在实际中,这种假设并不是最好的。例如,在模型 4-2 中,假如某些零件比较复杂,那么 对于这些零件的预处理时间就会比较长, 而后面紧接着的封装时间也相应地会较长, 也就是 说这两个时间肯定是相关的,忽视这些关系可能会导致模型无效或者得出有偏差的结果。 有很多建模方法可以考虑这种情况,如估计必要的参数(包括相关度),以及在仿真过 程中对随机变量作一些相关性约束。 有些方法需要将相关的随机变量组合成随机向量, 并采 用联合概率分布进行拟合。还可以通过公式来定义输入之间的关联关系,不过,这种方法相 对困难一些。如果想对这个问题作进一步了解,可以参考文献 Law and Kelton(2000)或者 Devroye(1986)。

51

4.6 小节
如果只是读完并理解了本章的内容,那么在使用 Arena 的时候还可能会碰上很多问题。 建议读者试着点击一下模型中使用过的模块中其它的按钮, 甚至试着使用一些还没用过的模 块。如果碰上疑问,试试在线帮助,它也许不能解答所有的问题,但可能会解答一些应该问 的问题。读者还可以试验一下别的动画特征,或者制作更精美的图形。这里最好的建议是亲 自去使用 Arena。第 5 章到第 12 章将会更深入讲述 Arena 的大部分的建模功能(以及一些 统计分析功能)。

4.7 习题
4-1 旅客进入机场入口的到达时间间隔服从均值为 1.6 的指数分布,首次到达时间为 0。旅 客从入口到登记处的行进时间服从 2 到 3 的均匀分布。在登记处柜台前,旅客需要排队,等 候 5 个代理的其中一个为其提供服务。登记时间(以分钟记)服从=7.76,=3.91 的威布 尔分布。完成登记之后,旅客可以自由离去。对此系统建立一个仿真模型,要求有动画(包 括从入口到登记处的行进时间)。运行仿真模型 16 个小时后,给出平均系统逗留时间,完 成登记旅客总数,以及等待登记的平均队长。 4-2 创建一个含两个串联加工单元的简单系统。 产品到达系统的时间间隔平均值为 10 分钟, 首次到达时间为 0。产品到达后,立即被送往单元 1 加工,平均加工时间为 9 分钟。产品在 单元 1 加工完成之后被送到单元 2 加工,在单元 2 的加工时间跟单元 1 一样。产品在单元 2 加工完之后离开。 我们感兴趣的系统性能指标是每个加工单元的平均队长, 以及产品的平均 系统逗留时间。 仿真时间长度设定为 10,000 分钟, 分别按下面 4 种情况运行并比较结果 (注 意模型结构不变,只有输入分布改变)。 运行 1:指数到达时间间隔和指数服务时间 运行 2:常数到达时间间隔和指数服务时间 运行 3:指数到达时间间隔和常数服务时间 运行 4:常数到达时间间隔和常数服务时间 4-3 在习题 4-1 中的登记问题里加入代理休息。将 16 小时分成 2 个 8 小时,代理的休息是 错开的,从 90 分钟开始进入轮班。每个代理休息 15 分钟。代理的午餐休息(30 分钟)同 样也错开,3.5 小时之后进入轮班。假设代理都很粗鲁,当轮到某代理休息时,就算他处于 繁忙状态,也会把正在登记的旅客丢在一边,休息完了之后再回来完成该旅客登记。比较一 下该模型修改前后的运行结果。 4-4 两种不同类型的零件到达工厂进行加工。零件 1 的到达时间间隔服从对数正态分布,分 布的对数平均值为 11.5 小时,对数标准偏差为 2.0 小时,首次到达时间为 0。到达的零件 1 在一个专门给零件 1 指定的队列中等待,直到有操作员来处理(工厂里只有一个这种操作 员),处理时间为 TRIA(5,6,8)小时;零件 2 的到达时间间隔服从均值为 15 小时的指
52

数分布,首次到达时间为 0。零件 2 在另外一个队列中等待(该队列中只有零件 2),直到 工厂唯一的操作员来处理,处理时间为 TRIA(3,7,8)小时。经过操作员的处理之后, 所有的零件都进入一套全自动机器(无人)进行加工,加工时间为 TRIA(4,6,8)小时, 等待机器加工的队列遵循“先到先服务”规则。零件在机器上加工完后退出系统。假设忽略 所有的零件传送时间。运行仿真模型 5,000 小时确定零件的平均系统逗留时间(不分类型, 所有的零件一起考虑),以及两种零件各自指定队列的平均队长。对模型动画进行设置,包 括对不同的零件类型使用不同的图形,资源的繁忙和闲置状态也用不同的图形。 4-5 习题 4-3 的模型中,在登记系统的证件检查过程中,发现旅客可以分成两种类型。第

一种类型的旅客的到达时间间隔服从平均值为 2.4 分钟的指数分布,登记时间(以分钟记) 服从=0.42,=14.4 的伽马分布。第二种类型的旅客到达时间间隔服从平均值为 4.4 分钟的 指数分布,登记时间服从爱尔朗分布,表达式为 3+ERLA(0.54,15)。两种旅客的首次到 达时间都是 0。按此修改习题 4-3 种的模型,并比较仿真结果。 4-6 零件进入一个单一工作站系统,到达时间间隔服从均值为 21 秒的指数分布,首次到达 时间为 0。到达之后,零件进行初始处理,加工时间分布为 TRIA(16,19,22)秒。通过 观察可以初步判断零件是否存在质量问题。有问题的零件占总数大约 10%,它们被送到一 个站进行彻底检查,剩下的零件认为是合格的,被运出系统。检查时间为 95+WEIB(48.5, 4.04)秒。送去彻底检查的零件中大约有 14%不能通过,被作为废品运走。通过彻底检查的 零件也认为是合格的,被运出系统。运行该仿真 10,000 秒,观察运出系统的合格零件的数 量、废品的数量、以及接受彻底检查的零件数量。对模型动画进行设置。 4-7 一个计划中的生产系统包括 5 个串联的自动工作站。每个工作站的加工时间都是常数, 分别为 11,10,11,11 和 12(本题所有时间单位都是分钟)。零件到达时间间隔为 UNIF (13,15)。在每个工作站前都有一个容量无限的缓冲区,并假设所有的传输时间都是 0。 该生产系统比较特别的地方是,从工作站 2 一直到工作站 5,零件都有可能需要被送到前一 个工作站重新加工。例如,一个零件在工作站 2 加工完以后,可能会被送到工作站 1 的队列 里。返工的概率都是相互独立的,也就是说,一个零件可能返工多次。目前对所有的工作站 来说, 零件的返工概率是 5%到 10%。 创建该仿真模型, 运行时间为 10,000 分钟, 运行 6 次, 每次的返工概率分别为 5%,6%,7%,8%,9%和 10%。根据运行结果,绘制平均系统逗留 时间与返工概率的关系图,在图形中标出每次运行的最大系统逗留时间。 4-8 一个生产系统包括有 4 个串联的自动工作站。假设所有的零件传送时间都为 0,所有的 加工时间都为常数。工作站的故障分为两种:大故障和小问题。该系统的信息都在下面的表 中列出(所有的时间单位都是分钟)。工作站正常运行时间服从指数分布,维修时间服从均 匀分布(如工作站 3 的小毛病维修时间为 UNIF(2.8,4.2))。运行仿真 10,000 分钟,确 定每个工作站故障时间百分比,以及每个工作站队列的结尾状态。
工作站编号 加工时间 大故障均值 小问题均值

53

正常 1 2 3 4 8.5 8.3 8.6 8.6 475 570 665 475

维修 20,30 24,36 28,42 20,30

正常 47.5 57.0 66.5 47.5

维修 2.0,3.0 2.4,3.6 2.8,4.2 2.0,3.0

4-9 一个发放汽车牌照的办公室通过将其顾客分类来调整工作量。根据居住地点,到达的顾 客会进入 3 条不同的队列中的一条。对该到达活动建模,3 个到达流互相独立,而且到达时 间间隔都服从平均值为 10 分钟的指数分布,首次到达时间都是 0。对每种类型的顾客都会 指派一个独立的工作人员处理申请表并收费, 种顾客的队列互相独立。 3 对所有类型的顾客, 服务时间都是 UNIF(8,10)分钟。完成这一步后,所有的顾客都会被送到一个唯一的工 作人员那里去检查表格和牌照(该工作人员为所有顾客提供服务,并且先到先服务),所有 顾客的服务时间都是 UNIF(2.66,3.33)分钟。对该系统建立一个仿真模型并运行 5,000 分 钟;观察每种类型的顾客的平均系统逗留时间和最大系统逗留时间。 一位顾问建议,这个办公室在第一阶段不要区分不同类型的顾客,将 3 条队列合并成 1 条, 并且 3 个工作人员同时给任何类型的顾客提供服务。 对这种安排方式也建立一个仿真模 型并运行 5,000 分钟,与前面的结果相比较。 首次到达时为 0。 4-10 顾客进入订货服务台的到达时间间隔服从均值为 10 分钟的指数分布, 一个工作人员接受并检查它们的订单,收取费用,总共花费时间为 UNIF(8,10)分钟。 完成这个步骤后,订单被随机送给两个仓库人员之一(每个仓库人员都有 50%的概率得到 一个顾客的订单),仓库人员帮顾客找到订购的货物,花费的时为 UNIF(16,20)分钟。 每个仓库人员只为持有分配给他的订单的顾客提供服务。 顾客拿到货物之后离开系统。 对此 系统建立仿真模型, 并运行 5,000 分钟, 观察顾客的平均系统逗留时间和最大系统逗留时间。 一位聪明年轻的工程师建议,不要为仓库人员指派其服务的顾客,而是让两位仓库人 员按照“先到先服务”的原则直接为任意一位前来的顾客服务。对此系统建立仿真模型,也 运行 5,000 分钟,将结果与前面的进行比较。 4-11 使用习题 4-2 中的模型, 将到达时间间隔设置成服从指数分布, 加工时间为 UNIF (9-h, 9+h),h 的值分别取 1.732,3.464 和 5.196,计算加工时间分布的(精确)方差,对 3 个 h 值均运行 10,000 分钟,并比较运行结果。注意到加工时间的平均值都是 9,加工时间都是均 匀分布,唯一不同的只有分布的方差。 4-12 使用习题 4-11 中的模型,假设加工时间平均值为 9,方差为 4。计算与此数据相符的 伽马分布的参数。运行一下模型,并与习题 4-11 中 h  3.464 的结果进行比较。注意到,这 里的平均值和方差都一样,但是分布形式不同。 4-13 零件到达一个单机系统,到达时间间隔服从均值为 20 分钟的指数分布,首次到达时间 为 0。零件到达系统后在机器上加工。加工时间为 TRIA(11,16,18)分钟。加工完成之
54

后零件接受检查,大约 25%的零件不合格需要返工(加工时间不变)。建立仿真模型运行 21,000 分钟,观察零件的平均加工时间和最大加工时间,零件的平均排队时间,以及零件的 平均系统逗留时间(零件从进入系统,到可能返工数次,直至合格退出系统)。 4-14 使用习题 4-13 中的模型,另外再运行 2 次,运行时间分别为 60,000 分钟和 100,000 分 钟,将结果与 4-13 比较。 4-15 产品来自于一个存货提取系统,到达时间间隔服从均值为 1.1(所有时间单位为分钟) 的指数分布,首次到达时间为 0。产品到达之后,被 4 位同样的打包工人中的一位打包,所 有产品排成一个队列,4 位打包工人同时提供服务。打包时间为 TRIA(2.75,3.3,4.0)。 产品打包之后按类型分开装运(20%国际,80%国内)。只有 1 个搬运工搬运国际包裹,有 2 个搬运工搬运国内包裹,国内包裹只有一个对列。国际包裹搬运时间为 TRIA(2.33,3.3, 4.8),国内包裹的搬运时间为 TRIA(1.7,2.0,2.7)。打包系统按照 3 班、每班 8 小时运 转,一周工作 5 天。所有的打包工人和搬运工人在上班 2 小时后休息 15 分钟,4 小时后午 餐休息 30 分钟,6 小时后再休息 15 分钟;使用“等待” (Wait)调度规则。运行仿真 2 周(10 个工作日),确定系统中 3 个队列的平均和最大队列长度。设置模型的动画,包括 产品被打包成包裹后外观上的改变。 4-16 使用习题 4-15 中的模型,改变打包工人和国内包裹搬运工人的休息方式为交错休息, 以保证至少有 3 个打包工人和 1 个国内包裹搬运工人在工作。打包工人的第一次 15 分钟休 息安排在上班后 1 小时,30 分钟的午餐休息安排在上班后 3 小时,第二次 15 分钟休息仍然 是上班后 6 小时。国内包裹搬运工的第一次 15 分钟休息安排在上班后 1.5 分钟,30 分钟的 午餐休息安排在上班后 3.5 小时,第二个 15 分钟休息也是上班后 6 小时。运行仿真模型, 将新旧结果进行比较。 4-17 使用输入分析器,打开一个新窗口并生成一个新的数据文件(使用菜单 File>Data File>Generate New),数据文件里含有 50 个点服从爱尔朗分布 5+ERLA(12,3)。完成数 据文件后,使用 Fit All 从可用分布中找到最好的分布。将数据规模依次扩大到 500,5,000 和 25,000 个,还是采用相同的分布参数,并重复 Fit All 操作,比较 4 种不同样本数目的 Fit All 结果。 4-18 Hungry's Fine Fast Foods 快餐店的工作人员在午餐时间的工作量会剧增,高峰期从上午 10 点一直到下午 2 点。来吃午餐的顾客大致可以分成 3 类,步行的,开车的,或者坐公共 汽车,具体如下:  步行——每次到达一位顾客,到达时间间隔服从均值为 3 分钟的指数分布,首次到达 为上午 10 点之后的 EXPO(3)分钟。  开车——每次到达 1,2,3 或者 4 位(同乘 1 辆车),相应的概率分别位 0.2,0.3,0.3, 0.2;到达时间间隔服从均值为 5 分钟的指数分布,首次到达时间为上午 10 点之后的 EXPO(5)分钟。
55



每天只有一辆公共汽车会在上午 11 点到下午 1 点之间到达(到达时间为在该区间内的 均匀分布),公共汽车上每天来的人都不一样,但是大概服从均值为 30 人的泊松分布。 一旦顾客到达,不管是一个人还是一群人,也不论是什么方式,他们接下来接受的服务

完全都是一样的。第一次是在订购/付费柜台前的一位服务员处,定购花费时间为 TRIA(1, 2,4)分钟,付费花费时间为 TRIA(1,2,3)分钟。这两个步骤是紧挨着的,先定购再 负费,都在同一位服务员那里完成。接下来顾客前去领取订购的食物,花费时间服从 30 秒 到 2 分钟的均匀分布。然后每位顾客进入餐厅(可能需要排队等待空位),餐厅有 30 个座 位 (顾客可以在任何地方就坐, 不一定要跟一起来的人在一起) 顾客吃饭所花时间为 TRIA , (10,20,30)分钟,顾客吃完后离开。在 3 个“服务台”(订购/付费,领取食物,餐厅 等位)都允许排队,都遵循“先入先出”规则。顾客在所有站点间的行走时间(除了最后出 门)都是 EXPO(30)秒——到达到订购/付费,订购/付费到获得食物,获得食物到餐厅。 吃完之后,顾客行走相当慢,所以从餐厅到出口的行走时间为 EXPO(1)分钟。 所有订购/付费柜台和提供食物柜台的服务员会轮流休息一次。在 10:50,11:50,12:50 和 1:50 每一个服务场所都有一个人休息 10 分钟;如果轮到一位服务员休息,但是他正在为 顾客提供服务, 那么该服务员必须给当前顾客提供完服务才能休息, 但是返回岗位的时间不 变,也就是说服务员实际的休息时间可能会比 10 分钟短一点。 员工安排是 Hungry's 快餐店面对的一个主要问题。目前,在中午的 4 小时里,有 6 位 服务员在订购/付费柜台,2 位服务员在提供食物柜台。由于公共汽车会在 11 点至 1 点之间 到达,而且一次到达的顾客会很多,所以他们他们正在考虑一个可变的员工安排方案,在 4 小时的前 1 小时和最后 1 小时,安排 3 位服务员在订购/付费柜台,1 位在提供食物柜台;在 中间的 2 小时,安排 9 位在订购/付费柜台,3 位在提供食物柜台(注意,两个方案在 4 小时 里的“员工-小时”数是相同的,都是 32,所以需要付给雇员的工资都一样)。你的建议是 什么? 对于仿真结果, 观察每个队列的平均对长和最大对长, 顾客在每个队列中的平均等待时 间和最长等待时间, 以及 4 小时总共能够吃完午餐走出快餐店的顾客数量。 绘制 3 个场所 (订 购/付费,领取食物,餐厅等位)的队列数据图。对所有的队列、资源以及站间行走进行动 画设置。 对于不同到达类型的顾客设置不同的人物图形, 顾客吃完后离开的图形也作相应的 改变。如果有兴趣,还可以对顾客在餐厅的座位坐下进行动画设置。 4-19 在 4.2.5 节有关于输出值的瞬态利用率和均态利用率的讨论中,我们说,如果资源的能 ,则瞬态利用率和均态利用率是相同的。试 力固定(也就是对所有的 t,有 M (t )  c  0 ) 证明之。 4-20 在 4.2.5 节有关于输出值的瞬态利用率和均态利用率的讨论中,我们说,这两个参数都 不会一直保持很大。证明之。 (记住要想证明一个命题不成立,只需找到一个反例即可)

56

第 5 章 详细作业建模
在第四章里展示了用“基本操作”面板里的模块可以创建的模型种类。这些模块都是一 些相对高层而且容易使用的模块, 但离建立足够详细的模型还有很长的距离。 有时这些高层 模块对读者们来说已经足够了。 但有时还不行。在建模获得一些经验、所建模型越来越大、越来越复杂、越来越详细时, 可能会发现需要对较低层的、更详细的、或者与“基本操作”面板的模块所提供的对象不同 的事物进行控制或者建模。Arena 不会让你被迫接受这些固定的建模构件,也不会强迫你为 考虑模型的各个方面而不得不学习一门编程语言或编程语法。 相反地, 它提供了几个不同的 建模层次, 从而为建立一些特殊逻辑结构的模型提供了较大灵活性。 一种好的办法就是从高 层模块开始,它们能走到哪儿你就建到哪儿(可能自始至终就是一层)。当你需要比它们更 高的灵活性时,就到更低、更详细的层次中去。这种结构允许你随意开发容易的高层建模结 构,也允许你在需要的时候到低层建模。标准的 Arena 提供了所有这些建模能力,你能熟练 掌握它们的用法。 这一章探讨了一些(当然不是所有)在“高等操作”(Advanced Process)面板和“操作 块”(Block)面板中包含的低层详细建模构件;后一种面板提供了最底层的建模逻辑,其 中的模块与作为Arena基础的SIMAN仿真语言中的程序块一致。这里我们采用的例子是一个 很复杂的汽车修理与维护车间的模型。我们也会谈到一点非平稳(时间相关)到达过程,模 型调试,以及更高层的动画定制等重要问题。 5.1节中给出了这个系统的描述,5.2节讨论了如何用一些新的Arena建模概念对这个系 统建模,5.3节描述了一些基本的建模策略,5.4节给出了模型逻辑,5.5节讨论了模型调试 问题,5.6节给出了一些调整动画细节的方法,以得到一些非标准的效果。在5.7和5.8节, 我们对模型进一步完美化,并提出了几种新的Arena建模概念。在5.9节,我们向你展示了 如何修改原始模型,以创造出更精美的模型。本章于5.10节结束,我们在这一节中提出了 一种完全不同的模型,库存系统,并借此机会展示了如何使用Arena最底层和最详细的建模 层次,即包含了SIMAN仿真语言的“操作块”面板。 在读完本章后,你应该可以建立非常详细和复杂的模型,也可以探索出Arena建模的丰 富而又深入的层次结构。

模型 5-1:汽车维护与修理车间
位于某中等城市市区的大型汽车修理商,由于其维护与修理业务增长太快而使得当前的 设施不足,因此决定要扩建其汽车维护与修理车间。由于当前所处的位置的限制,他们考虑 在郊区再建一个有三个修理间的新车间。新建的车间不仅应能提供额外的维护与修理能力, 而且应位于现有多数顾客的附近。 为了能够对工作流进行更好的控制, 由位于市区的车间对 两个地方的工作进行安排,而且主要的修理工作也将继续在市区车间进行。 根据该计划,允许顾客最多提前三个工作日在新的郊区车间打电话提出预约服务(在预 约的当天不提供服务) 例如, 。 在周三打电话预约的顾客可以在周四、 周五或周一得到服务。 如果无法为顾客在给定的后续三天时间安排服务的话, 他们可以第二天再打一次电话, 或者 在市区预约要进行的工作。 该汽车修理商具有顾客服务需求的大量数据, 对这些数据的分析 表明,顾客要求服务的呼入电话平均每天29次,全天都服从(平稳的)泊松过程(也就是说, 呼入电话的时间间隔独立、且服从相同的指数分布) 。对数据的分析还表明,55%的呼叫者 希望在第二天得到服务,30%希望在第三天;剩下的15%希望在第四天。如果不能安排在其 选择的某一天内提供服务的话,他们有90%的可能性希望安排在之后的一天。 大部分顾客(80%)会选择全天将车辆放在这里,而少数顾客(20%)愿意一直等到服 务完成。如果顾客选择等待,他们将会给定一个近似的等待时间。这个等待时间等于预计的 完成工作的服务时间(被称作预定时间(Book Time))再加上放宽因子(一个小时)。建 立这个新车间的目标之一就是使顾客具有很高的满意度。因此,公司决定每天最多安排5个 希望就地等待服务完成的顾客预约。 无论实际服务时间是多少,该汽车修理商都用一组标准的估计服务时间(Book Times) 来计算服务成本。各类服务活动的预定时间可用一个带有位移和比例因子的β-分布来表示 (44+90*BETA(2, 单位为分钟, 3), 且截断取整) 实际的服务时间与预定时间 。 (Book Times) 有些不同,它服从伽马分布GAMM(Book Times/1.05,1.05)。 该汽车修理商想使新车间盈利,但不知道每天应该安排多少预约服务,现在的处理是基 于每天所能安排的预定时间(Book Time)小时数的最大数量来进行的。这个值是基于三个 修理间、每间每天可用的服务时间是8小时来计算的。因为实际服务时间往往与预定时间有 所不同,所以最后确定每天可供安排的时间为24小时。 假定每周有五个工作日, 每天工作八个小时, 每个修理间每小时的成本估计为45美元 (包 括所有的资本和劳动) 。对顾客按预定时间的每小时78美元收费。因为实际服务时间与预定

时间有一定的不同, 所以该汽车修理商希望在修理开始的当天完成已安排好的服务。 为了补 偿服务时间的差异,每一个修理间每天最多可以加班3个小时。但是,加班的成本是每车间 每小时120美元。如果服务在这个时间内无法完成,顾客的车辆就会在修理间放置过夜,服 务在第二天完成。如果发生此事,那么汽车修理商会为顾客提供一辆替代车,为每辆替代车 每天将花费修理商35美元。如果修理商的负荷较大,导致某车在当天的预约服务不能开始, 此时假设顾客将自己的车开回家,第二天再开过来,因而就不需要替代车辆了。 对该系统所关心的统计量有:每天的利润,每天的预定时间,每天的实际服务时间,每 天的加班时间,以及每天安排就地等待服务的顾客中没能完成的作业数量。

5.2

新的建模特性

从仿真的观点来看,这个问题与我们在第三章和第四章所研究的非常不同。最明显的区 别是这个系统是一种服务性质的企业,而前面的系统是面向制造业的。虽然SIMAN仿真语 言最初的版本 (Arena是以该仿真语言为基础的) 是为制造业的应用而开发的, 但是现在Arena 的能力也应用到了服务系统的精确建模,包括快餐店、银行、保险公司、服务中心和很多其 它的企业。 尽管这些系统都有各自的一些特点, 但是基本的建模需求很大程度上与制造系统 相同。 现在,让我们看一下汽车车间,然后找出新的需求。随着工作的继续进行,会发现我们 已有的建模结构还不足以完成如此详细的系统建模。

5.2.1 多路径决策
进行服务预约时,将它安排到合适的工作日,然后等待这一天的到来。为此,根据预约 日的要求,我们需要将实体或预约送到该模型的五个不同的部分。 虽然我们可以通过用一系列的“决策”模块(Decide)实现它,但是模型会变得难看而 且也没有必要。你也许仍然还不太清楚,其实在第四章前三个模型里用到的Decide模块中可 以含有三个或者更多的分支。

5.2.2 集合
随着模型越来越复杂,经常会发现需要模拟实体到达一个位置或站时,需要从几个相似 (但是不完全等同)对象中选择一个。

最常见的情况是从一组资源中选择可用的资源。假设有三个操作员:Shelley、Lynn和 Charity。他们中的任何一个都可以完成需要的任务,这时,只要他们当前都是空闲的,则可 以选择这三个中的任何一个。“集合”模块(Set)为实现这种功能性提供了基础。Arena的 集合包含了一组相似对象, 这些对象可以通过集合名称和相应的下标来引用。 这些对象构成 了集合, 每个对象是集合的一个成员。 特定集合的成员都必须是同种类型的对象, 例如资源、 队列、图形等等。根据建模需要,可以将几乎任何一种Arena的对象收集到一个集合之内。 一个对象也可以出现在一个以上的集合之内。 例如在操作员集合 (Operators) 中包括了Lynn, 但她又能作为一个调整人员,因此,可能会定义一个被称为“调整”(Setup)的资源集合, 其中包括Lynn和Doug(Doug不是一个操作员)。现在,如果需要一个操作员,就从名为 Operators的集合中选取,如果需要调整人员,就从名为Setup的集合中选取。因为Lynn是同 属于两个集合中的一个成员, 所以可能会在任何一个情景下选择她。 用户可以按需要任意选 择集合的数目或集合间是否有重叠。 对修理中心来说,我们用集合来建立修理间模型、描述实体图形和预约队列。

5.2.3 变量与表达式
在很多模型中,可能会在多个不同的地方重复使用数据。例如,在一个模型中有几个地 方可能需要生成来自相同分布的服务时间, 并将它们输入到需要的模块中去。 但是如果要在 实验中更改这个分布的参数(或者分布本身),就必须打开每一个包括该服务时间的对话框 来改变参数值。有时,我们可能需要跟踪系统中实体总数变化的情形。还有的时候,我们可 能在整个模型中需要使用很复杂的表达式, 例如, 可能根据零件类型来确定加工时间。 Arena 的“变量”(Variable)和“表达式”(Expression)模块可以容易地实现这几种要求。 “变量”模块(Variable)允许用户定义自己的全局变量并赋初始值,而且还可以按照 它们的名称加以引用。 它们也可以被指定为一维或二维的数组。 “表达式” (Expression) 模块 允许用户定义各类表达式和它们所关联的值。 与变量相似, 表达式也可以在模型中以它们的 名称引用,可以被指定为一维或二维的数组。虽然变量和表达式看起来很相似,但是它们具 有不同的功能。 用户定义的变量可以存储一些能够在仿真运行期间重新赋值的量。例如,我们可以定义 一个叫做Wait Time的变量(用以表示等待时间),其初始值为2,在需要使用该量的地方输 入变量名即可。我们也可以定义一个叫做Number in System的变量(用以表示系统中的零件

数),其初始值为0。每次新零件进入这个系统,就在这个变量上加1;每次一个零件退出系 统就减1。对汽车车间来说,我们用一个名位Day的变量来跟踪这一周的当前日。我们还会 用很多变量来控制如何获得预约,如何在运行结束时收集用于计算统计量的信息。 与此不同,用户定义的表达式不能存储数值,而是提供了一种将某个名称和特定的数学 表达式关联起来的方式。当名称在模型中被引用时,相关的表达式就会被计算出来,并返回 其数值。例如,表达式可被用来计算一些分布或复杂等式的值,而计算公式中又包含了实体 的属性值或者系统变量值的当前值。 如果在模型中数学表达式只用在一个位置, 将它输入到 相应的位置可能会更容易。 但是, 如果表达式被用在几个位置或者要用的表达式的形式依赖 于实体的属性,那么用户定义表达式通常会更好。对汽车车间来说,我们会用Expression模 块 (在 “高等操作” 面板中) 来定义所生成的预定时间、 实际服务时间和预定需求的类型 (等 待还是离开)这些表达式。 变量和表达式有很多其它的用处,随着你们对Arena的进一步熟悉,这一点会越来越明 显。

5.2.4 子模型
在开发庞大而复杂的模型时,通常将模型分割成小的模型是有好处的,这种小的模型被 称为原模型的子模型(submodels),它们之间可能互相有交互,也可能没有。这会为建模 与测试过程提供便利。例如,我们可以将汽车车间模型分割成五个明显的(我们认为它们很 明显)子模型:生成预约呼叫、进行预约、服务活动、更新性能变量和控制逻辑。 Arena以子模型的形式提供了这种分解能力。这种特点允许将模型分成不同层次的视图, 也即子模型,每一个都在屏幕上有自己完整的工作空间。你既可以一次观看一个子模型,也 可以观看模型全景(也即顶层 (Top-Level) 模型)。每一个子模型都可以包括常规的模型窗 口(例如“电子数据表格”模块、静态图形和动画元素)所支持的各种对象。子模型本身也 可以包括更低层的子模型;可以无限地嵌套下去。子模型可以连接到其它的模块中去,也连 接到其它的子模型中去,或者孤立地处于一个Arena模型中。 在顶层模型视图和每一个子模型视图中,为了在逻辑区和动画区的不同区域中提供容易 的导航,可以建立带有相关热键的“命名视图”。工程工具栏的“导航”面板(Navigate) 可显示出列有顶层模型、所有的子模型、以及它们所以命名视图的树状结构。点击一个命名 视图的或子模型视图即可显示该模型所在的区域, 这使得在视图内和视图间的导航变得非常 容易。

虽然以上汽车车间模型还不像很多实际模型那么大,也没有那么复杂,但是我们仍然用 子模型来组织流程,并阐明概念。

5.2.5 实体副本
在开始更复杂的建模时,通常会发现创建“实体复本”的必要性。这些实体通常被用作 控制实体,可以完成许多功能。这种用法的一个很好的例子将在9.3节介绍,在那里会讲到 实体的受阻离开和中途退出等现象。 也有的时候需要在模型的某处将一批实体集合成一个实 体(也即将零件装盘),然后在模型的另一处再将成批实体分成单个。本书将在9.4节加以 说明。在汽车车间模型里,我们需要创建实体副本,让它代表要求预约的来电。可使用“基 本操作”面板中的“分离”模块(Separate)来创建或克隆实体的副本。

5.2.6 保持实体
模型中有时需要将实体保持在某个位置,直到系统允许这些实体行进的特定情况发生为 止。 我们已经看到其中的一种形式  实体在排队等待资源空闲。 但在此我们考虑更一般的 情况,实体被保持的位置是由模型中其它地方的活动所决定的,如系统时间或系统条件。 Arena提供了两种不同的保持实体的方法。第一种方法是实体被保持到由另一个实体发出行 进信号为止; 第二种方法是实体被保持到某些系统条件出现为止。 在汽车车间模型中我们将 采用第一种方法,可通过使用“保持”模块(Hold)和“信号”模块(Signal)来实现,也 即将顾客的预约一直保持到安排对他进行服务的那一天为止。第二种方法将在9.4节介绍。

5.2.7 统计量和动画
我们需要的统计量也是比较平常的,与前面模型中收集到的没有很大不同。但是,系统 的类型和分析需求却截然不同。 先看一下分析需求。 在分析服务系统时常见的目标是利润最 大化或顾客满意度最大化,还有成本最小化(当然,从极端意义上讲,它们是相互矛盾的目 标) 该汽车修理车间顾客满意度的关键测度的是在所承诺的完成服务时间以外的等待服务 。 的顾客数。很明显,我们的目标就是使其最小化。影响这些测度的关键因素是各天所安排的 等待服务的最大顾客数。创建模型后,我们可以很容易地增加或减小这个数,并确定其对性 能指标的影响。我们需要认真考虑仿真要运行多长时间,以及所要建立的系统的类型。下一 节会涉及到这些。

分析和提高利润是一个更加困难的问题。预约是基于Book Time的,而各天所需要的实 际服务时间可能有很大的不同。因此,我们如果想要控制模型变量以提高利润,那么就需要 知道改变这些变量所造成的影响。 通常的仿真输出总结报告是不会直接给出这个信息的。 但 是我们可以通过增加一些统计量来收集和提供所需信息,这不难做到。 查看动画运行应该是很有帮助的,就像在观测实际系统一样。遗憾的是,与以前的模型 不同, 一般很难为这种系统加上动画效果以使其展示出系统运行状况。 我们可以用动画模拟 预约的队列和资源, 但是相应的动画却是非常跳跃的, 而且也不能提供我们所需要的时间方 面的信息。虽然经常也观看这类系统的动画,但是这些动画一般都是用来“展示”而不是进 行分析的。不过既然已经提及,我们还是会在5.6节介绍如何给这种模型加上动画的。

5.2.8 终态仿真和稳态仿真
大部分(尽管不是所有的)仿真可以被分为终态仿真和稳态仿真两大类。这主要是仿真 研究的意图或目的方面的问题,与模型内部的逻辑或架构没有多大关系。 终态仿真(terminating simulation)是模型规定了特定的开始和结束条件的仿真,这些条 件是对实际系统需求的真实反映。 正如它的名字所体现的, 仿真会按照模型规定的特定规则 或条件终止运行。例如,一个商店在上午9点开门,开门时店内没有顾客;在晚上9点关门, 并继续服务到所有的顾客都离开。 再看一个加工车间的例子, 它则运行到生产出订单所规定 的500个装配件为止。这一类型的关键是仿真有一个明确定义的(虽然在开始时可能是未知 的)、自然的结束的时间,也有一个明确定义的启动方式。 与终态仿真不同,稳态仿真(steady-state simulation)则是通过长时间仿真运行来对某些 性能指标加以估计的仿真形式;也就是说,理论上的仿真时间应该是无穷大。在原理上,这 种仿真的初始条件是无关紧要的(虽然通常在实际中不是这样)。当然,稳态仿真也必须在 某一个时间点停止,不过正如所想象的那样,仿真会运行很长时间,因此需要设法保证它运 行的时间足够长。我们将在7.2节讨论这个问题。有关稳态仿真的例子也很多,例如一个儿 科急诊室在实际中永远不会停止或重新开始, 因此稳态仿真对此会很合适。 有时候某些系统 在实际中会有终止状态, 但为了设计其某种最坏的或者负荷最大的情况, 仍可以采用稳态仿 真模式进行。 现在为汽车修理车间模型选择应该用哪种仿真形式。虽然根据定义能看出终态系统和非 终态系统的差别很明显,但在实际很少如此。一些系统刚开始时采用一种类型,但是更进一 步检验后却发现它们实际上属于另外一种。 再加上有些系统同时包括两种类型的因素, 这就

使得这一更加复杂了, 此时往往依据分析人员所处理的问题的类型来确定仿真的分类。 例如, 考虑一个在上午11点开门, 晚上11点关门的快餐店。 如果对该快餐店的日常运作问题感兴趣, 就可用非平稳泊松到达过程, 并将系统看成是终态仿真进行分析。 如果只对发生在午饭前后 两个小时内的高峰期的运作感兴趣,则可以假设系统是一个以峰值到达率到达的平稳过程, 并可将这个系统作为稳态系统进行分析。 乍一看, 汽车修理车间很像是一个终态系统, 这个系统似乎可以以空闲状态开始和终止。 但也有可能某天不能完成所有的工作(记住我们只允许三个小时的加班)。需要在车间放过 夜的车辆会对第二天的初始条件有很大影响, 因此我们可以将系统考虑成稳态的。 假如情况 并非如此,我们将会继续在第六章将汽车车间问题作为终态系统进行分析。

5.3

建模方法

在第一章的图1-2中,简要讨论了Arena的层次结构。这种结构允许将任何层次的建模构 建组合在一个仿真模型中。在第三章和第四章中,我们基本上都是利用“基本操作”面板中 的构件来开发我们的模型, 尽管在处理故障或其它特殊统计量时确实也用到了几种在 “高等 操作”面板里的数据模块。 在创建模型时,我们推荐一般情况下要尽可能维持在最高的层次上构建模型。但是,当 发现这些高层构件已无法描述必要的细节时, 你就应该将模型的某些部分移到下一层, 而不 能牺牲仿真模型的准确性。你可以将不同层次和面板中的的建模构件同一个模型中混合使 用。随着对各种面板(和建模层次)的进一步熟悉,你会发现自己能够很自然地这么做。在 继续建模工作进行之前,先简要讨论一下可用的面板。 “基本操作”面板(Basic Process)提供了最高层环境。使用该面板可以既迅速又容易 地创建大部分系统的高层模型。“创建”模块(Create)、“操作”模块(Process)、“决 策”模块(Decide)、“赋值”模块(Assign)、“记录”模块(Record)、“分批”模块 (Batch)、“分离”模块(Separate)和“清除”模块(Dispose)的综合运用可具有很大的 灵活性。实际上,如果研究一下这些模块,就会发现有很多其他的特点我们还没有探讨。在 很多情况下, 仅单独使用这些模块就能提供仿真项目需要的所有细节。 因为这些模块提供了 几乎所有模型都需要用到的常见功能, 因此不管所希望的建模细节处于哪一层, 你都有可能 用到以上模块。

“高等操作”面板(Advanced Process)提供了其他一些更详细的建模能力,补充了“基 本操作”面板的功能。例如,“占用-延时-释放”模块(Seize-Delay-Release )的组合就提 供了与Process模块基本相同的建模逻辑。“高等操作”面板中的模块的一个有用特点就是 你可以将它们放在模型中几乎所需要的任意组合体中。 实际上, 很多有经验的建模人员都是 从这一层开始,因为他们感觉由此建立的模型对用户来说会更明晰。 “高等运送”面板(Advanced Transfer)提供用于物料搬运活动方面的构件(如运送设 备和传送设备)。与“高等操作”面板提供的一般的建模能力相似,“高等运送”面板中的 模块在为物料搬运系统建模时也具有很高的灵活性。 “操作块”面板(Blocks)提供了更低层次的建模能力。实际上,它提供了用来创建“基 本操作”面板、“高等操作”面板和“高等运送”面板中所有模块的基本功能。另外,它还 提供了很多在高层模块中不能实现的其它特殊用途的建模构件。如“while”循环、概率和 逻辑组合分支、 以及自动搜索等特征。 你可能注意到其中的几个模块与那三个高层面板中的 模块有相同的名称。尽管名称一样,但模块却是不同的,能够通过颜色和形状来区分这两种 模块。 如果你以前用过SIMAN仿真语言,并在其中分别定义过模型文件和实验框架(即使在 Arena中你也可以这么定义),那么“操作块”面板和“基本操作”面板、“高等操作”面 板以及 “高等运送” 面板之间的差别就很容易解释了。 这些差别最好通过两类面板中的Assign 模块来阐明。在使用“基本操作”面板的Assign模块时,你可以随意选择合适的赋值类型。 如果给一个新的属性赋值,Arena会自动定义这个新的属性并将它加入到模型各处的“属性 下拉列表”中。尽量在最高层建模的一个原因就是“操作块”面板中的模块没有这么方便, 其中的Assign模块只能完成简单的赋值,不能定义新的属性。虽然有这样的缺点,但在“操 作块”面板中的模块仍具有一些其它面板所不具备的强有力的特征。 另外,“构模元素”面板(Elements)中也有实验框架方面的模块。例如,在这里可以 利用Attributes模块定义新属性。 由于建模时可与更高层次面板中的模块相混合使用, 所以实 际中很少需要这些功能。但是如果某些特殊问题需要建立一个最低层的模型(如使用Visual Basic、C、和FORTRAN等程序设计语言的功能),则也可通过Arena接口加以调用。 “操作块”面板和“构模元素”面板也提供了为连续系统建模而设计的模块,这些内容 将在第11章介绍。

现在让我们返回到汽车维修车间模型中,该模型确实要用到“基本操作”面板中的模块 所不具备的特点。在开发模型时,我们会同时用到“基本操作”面板和“高等操作”面板中 的模块(在本章的结尾,会用“操作块”面板和“构模元素”面板开发一个库存模型)。在 一些情况下,确实需要用到较低层的构件;而在其它情况下,就只是展示一下它们的特性。 在创建含有低层构件的模型时,开发模型的方式会稍有不同。 如果仅有较高层的构件,一 般可对活动进行分组,然后再使用适当的模块加以建模。而如果含有较低层的构件,就需要 对实际活动有细致的描述。 从某种意义上说, 你的模型要能成为刻画这些活动的详细的流程 图。不过要做到这一点并不容易,除非你对各种模块的逻辑非常熟悉。

5.4 建模
在此,我们把模型分成几个部分,分别直接对各个部分进行开发,同时介绍各部分的功 能。以下按顺序分别介绍七个部分: 5.4.1节:定义数据, 5.4.2节:创建子模型, 5.4.3节:生成预约呼叫, 5.4.4节:进行预约, 5.4.5节:服务活动, 5.4.6节:更新性能指标变量, 5.4.7节:控制逻辑。 数据一节包括建模所需要的数据模块,接下来一节会说明如何创建子模型,剩下的五部 分每一个都将作为子模型加以开发。最后得出的顶层模型窗口外观上类似于图5-1。因为以 后才给模型加上动画,所以我们这里先删除包含在模块中的所有动画对象。

P186 图5-1 模型5-1:汽车维修车间模型的顶层模型视图

当读完下面有关建模的七个部分后,你可能能感觉到,这是开发一个模型所遵循的基本 步骤。理想情况下,人们总希望能够先对模型的结构有一个比较好的规划,以使其比较容易

建立。但是在实际中,你会常常返回到先前完成的部分,不断对模块或数据加以增、删、及 修改。因此在开发复杂模型时,一定不要指望能一次就成功(我们当然也不会)。

5.4.1 定义数据
让我们从Run>Setup菜单对话框开始。在Project Parameters表页中的Project Title栏内输 入项目名称。在Replication Parameters表页中,我们随便设定为重复仿真运行10次,每次仿 真20天。因为希望输出报告中的单位是小时,所以这里选择Hours作为基准时间单位(Base Time Unit) 。 由于实际系统开始时都是空的(除非有车辆放过夜,以及在随后3天有预约) 因此可 , 令预备运行时间的长度(Warm-up Period)为0。因为设定了多次重复仿真运行,所以需要 告诉Arena在相邻两次重复仿真运行之间要做什么。有四种可能的选项。 选项1:初始化系统(是) ,初始化统计量(是) 这会进行10次统计上独立而且相同的重复仿真运行并生成相应的报告,每一 次都是在时间0时开始且系统初始状态为空,每一次都运行240个小时。随机数发 生器(见12.1节)在重复仿真运行之间连续产生独立同分布的(IID)随机数。在 前一次仿真结束时可能需要放过夜的车辆在下一次重复仿真开始时将不被保留。 选项2:初始化系统(是) ,初始化统计量(否) 这会进行10次独立重复仿真运行,每一次都在时间为0时开始且系统初始状态 为空,每一次都运行240个小时,但输出报告中的统计结果是各次累积的。因此, 报告2会包括前两次重复仿真运行的统计结果,报告3会包括前三次重复仿真运行 的统计结果等等。这里的随机数发生器的运行也象在选项1中一样。 选项3:初始化系统(否),初始化统计量(是) 这会进行10次仿真运行,第一次从时间0开始,第二次从240开始,第三次从 480开始等等。因为系统在多次重复仿真运行之间没有进行初始化,所以时间会连 续增加,任何放过夜的车辆都会被带到下一次重复仿真运行中。报告只包括单独 一次重复仿真运行的统计量,而不是多次累积的结果。 选项4:初始化系统(否),初始化统计量(否) 这样也会进行10次仿真运行,第一次从时间为0开始,第二次从240开始,第 三次是从480开始等等。因为系统在多次重复仿真运行之间没有初始化,所以时间 将连续增加,任何放过夜的车辆都会被带到下一次重复仿真运行中。但这时输出

报告中的结果是累积的。第10次报告的结果将与做一次时间为2400个小时的单次 仿真运行是一样的。 理想情况下,我们不希望有很多车辆在修理间过夜,因而希望采用独立的重复仿真运行 模式。这意味着要么选择选项1,要么选择选项2。此处将选择选项1(有关的详细情况见第6 章)。 本例共有三项资源(三个修理间)。所有这三项资源都是可变容量的(在4.2节已作过讨 论)。我们可以为每一种资源单独定义一个容量调度;但是由于它们的容量调度形式是一样 的, 所以可以简单地重复使用单个调度 (尽管这么做会使你的模型在将来可能产生变化时减 少了灵活性) 在建立这种容量调度时, 。 可使用图示调度编辑器 (Graphical Schedule Editor) , 在Options对话框中将time slots的个数设定为12,将图中y轴的maximum capacity设定为2(我 们实际上可以设定它为1)。容量调度如图5-2所示。 你可能注意到,该容量调度要求这3个修理间每天有11小时可用,每天工作8小时,再加 上可能有3个小时的加班。资源在每天的第一个小时都不能用,因为要用这一个小时来调度 未来的预约,并允许当天的顾客在这个时候到达。 下一步就是定义资源。我们为容量调度类型选择“优先抢占”(Preempt)选项,因为车 辆在标准的8小时工作和允许的3小时加班后有可能仍未完成服务。 在这种情况下, 将停止对 该车辆上的工作,并选择在第二天完成该项工作。最后的电子数据表格视图如图5-3所示。

P188 图5-2 图示调度编辑器:修理间容量调度

定义完资源以后,就可以用“基本操作”面板中的“集合”模块(Set)来定义集合了。 利用Set模块可以定义资源集合、计数器集合、计数型统计量集合、实体类型集合以及实 体图形集合,也可以利用“高等操作”面板中的“高等集合” 数据模块(Advanced Set) 来定义其它的Arena对象集合。点击Set模块,然后在电子数据表格视图中双击相应位置以添 加一个新的条目,这样就可以定义一个集合。我们会带你详细了解创建该集合的细节。在 Name单元格中输入Bays,从Type单元格的下拉列表中选择Resource。接下来定义集合中的 成员,点击Member栏的“0 Rows”按钮,打开包含所定义的各项资源的电子数据表格,然

后双击相应位置打开一个新的空行。 因为已经定义了资源, 所以可以用下拉列表中选择每个 成员的资源名称。已完成的Bays集合成员的电子数据表格视图如图5-4所示。

P188 图5-3 资源电子数据表格窗口

P189 图5-4 Bays集合成员的电子数据表格窗口

下面定义两个实体图形的集合,Customer(顾客)和Vehicles(车辆)。每一个集合都有 两个成员,分别表示在等待的顾客和将车辆留下来的顾客。已完成的Set数据模块如图5-5所 示。

P189 图5-5 Set模块的电子数据表格窗口

我们还需要创建一个队列集合以存放将来的预约。首先,需要用“基本操作”面板中的 “队列”模块(Queue)定义五个队列(周一预约队列到周五预约队列)。然后,利用“高 等操作”面板中的Advanced Set模块来定义队列集合。在Name单元格中输入Appointment Queues,从Type单元格的下拉式列表中选择Queue。然后在电子数据表格中输入五个队列成 员的名称,类似于前面的资源集合。该集合的五个成员如图5-6所示。

P189

图5-6

高等集合模块成员的电子数据表格窗口

下一步,用“基本操作”面板中的“变量” 数据模块(Variable)来定义变量。应该指 出的是我们没有必要一定利用这个模块定义变量。当你在所需的某处(例如Assign模块)定 义一个新变量时,Arena会将这个新变量的信息自动输入到Variable数据模块中。但是,如果 需要定义数组变量或所定义变量的初始值不为零, 那么就必须要使用这个模块来设定所需要 的数组大小或变量初始值。 本例将总共定义15个变量。 前六个变量是用来控制模型的: 保存当前日期的变量 (Day) , 令其初值为4(后面再详加叙述);用来保存当天预约作业的预定时间(Book Time)当前值 的数组变量(Day Load);预定时间小时数的最大值(Max Load),令其初值为24;等待 服务完成的顾客数的最大允许值(Max Wait),令其初值为5;用来保存当天等待作业数的 当前值的数组变量 (Wait Load) 以及每天打入电话要求预约的平均顾客数 ; (Calls Per Day) , 令其初值为25。 下面三个变量(以及最后两个变量)将在仿真运行结束时用来计算累积输出值:到现在 为止完成的预定时间小时数的总数(Day Book Time);到现在为止完成的实际服务时间小 时数的总数 (Day Actual Time) 到现在为止完成的加班时间小时数的总数 ; (Day Overtime) ; (Total OT) 被延期的等待作业的当前数量 ; (Day 当前在修理间存放过夜的车辆的存放总天数 Wait Late)。 中间的四个变量将被用于控制逻辑:仿真中当前工作日的序号(Work Day);当日的 工作开始时间 (Day Start Time) 当日的正常工作 ; (不包括加班) 结束时间 (Day End Time) ; 用来决定等待作业是否被延期的宽放量(Wait Allowance),令其初值为1。最后的电子数据 表格视图如图5-7所示。

P190 图 5-7 变量定义的电子数据表格窗口

我们还需利用 “高等操作”面板中的“表达式” 数据模块(Expression)来输入模型 所需的几个表达式, 包括用于确定每个呼入顾客的预定时间的表达式, 用于确定顾客是否想 要等待自己的车辆的表达式, 以及确定实际服务时间的表达式。 这样就可以很容易地根据需 要将这些分布直接输入到模型中去。

从上一段讨论的第一个表达式开始。打开Expression模块,在Name单元格为第一个表达 式输入名称Book Time Expression,然后在Expression Values单元格输入AINT (44+90* BETA (2,3) ) /60。可以简单地将上式用键盘敲入,或者用“表达式构造器”为其输入。因为大部分 汽车修理车间的预定时间都是以整数分钟表示的, 所以我们用Arena中的表达式AINT截去小 数部分,返回一个不大于且紧邻该数的整数(AINT函数是Arena的很多内置数学函数之一, 这些函数完整的清单可以在帮助菜单中的“数学表达式”(Mathematical Expressions)主题 下找到)。注意,我们将结果除以60,以把时间转化为小时。 第二个表达式(Wait Priority Expression)用来决定顾客是否会一直等到其服务完成。其 表达式为DISC(0.20,1,1.0,2),它将会以0.2的概率返回1,以0.8的概率返回2。在这种情况 下,1就意味着顾客会等到服务完成。 最后一个表达式与前面的表达式有关,因为它需要用到第一个表达式得出的值。在生成 预定时间时,将它存储在一个叫做Book Time的实体属性中。随后将把Book Time属性值带入 表达式Actual Service Time,用于生成实际服务时间,其表达式为GAMM(Book Time/1.05, 。 1.05) 最终的数据项需要“高等操作”面板中的“统计”模块(Statistic) 。其中所有的条目都 是输出类型的(Output Type) ,这就意味着这些值只能在每次重复仿真运行结束时求取。前 面三个条目以小时为单位计算每天服务所需的平均预定时间、 平均实际服务时间和平均加班 时间。 利用前面定义的变量就可以计算这些值。 第四个表达式是求取平均每天被延期的等待 作业数量。 最后一个统计量由三项组成,用于计算平均每天的利润。第一项(Day Book Time / Work Day)*78,表示根据预定时间按每小时收费78美元计算的已完工工作的收入。第二项(Day *120, 表示因加班而导致的成本。 最后一项的前半部分 Total OT / Work ( Overtime / Work Day) Day)*35是由于需要为没能在预定时间内完成服务的顾客提供替代车辆而造成的损失,第 二部分24*45是资金和人力成本。 这些表达式可以直接输入,也可以用“表达式构造器”输入。最终的电子数据表格视图 如图5-8所示。

P192 图5-8 Statistic模块电子数据表格窗口

以上完成了所需的数据定义工作,现在可以建立模型逻辑了。

5.4.2 创建子模型
通过选择菜单Objects>Submodel>Add Submodel可创建子模型。 此时鼠标指针将会变成十 字形,将它移到你想放置子模型的那个模型窗口中,点击一下就可将其放好,如图5-9所示。 这个子模型对象的名字是Submodel跟着1个数字,该数字随着子模型的添加而递增。 若要将子模型对象的名字按自己的要求定义,则鼠标右击该子模型,选择Properties项打 开子模型属性窗口,如输入界面5-1所示。我们将第一个子模型命名为Generate Appointment Calls(生成预约呼叫)。新的子模型默认有一个进入点和一个离开点。对第一个子模型来 说,将进入点数量改为0,因为这个特殊的子模型仅被用来利用Create模块为模型的其它部 分生成呼叫。可以在Description栏输入对子模型的一些描述,不过由于这个模型很简单,仅 用名字就描述得足够清楚了,所以此处就不输入更多的描述了。 按照以上过程创建剩下的四个子模型, 使得最后的视图看起来如图5-1所示。 在创建过程 中, 你可能需要注意该图中每一个子模型进入点和离开点的个数。 一旦将所有子模型放在合 适的位置,并赋予它们正确的属性,就可以开始构造模型逻辑了。若要打开子模型并添加或 编辑模型逻辑,只需要双击子模型或者用“工程栏”中的的“导航”(Navigate)面板在子 模型和顶层模型之间来回切换即可, 如图5-10所示。 若要关闭子模型窗口, 你可以用Navigate 切换,或在子模型窗口中的空白处右击鼠标,并选择Close Submodel即可。现在我们已经可 以建立实际模型了。

P192 图5-9 新建的子模型

P193 输入界面5-1 子模型属性窗口

5.4.3 生成预约呼叫
这个子模型会生成每天的预约呼叫,并将它们传送到下一个预约处理的子模型。除了第 一天以外,逻辑过程都是非常直观的。在子模型中将生成单个的实体(每12个小时一个), 确定当天呼叫的次数,变量Day递增,创建足够多的实体副本使当天的离开实体数量等于呼 叫的数量,最后为每一个离开的实体赋必要的属性值。 回忆一下,顾客只允许预约未来三个工作日中的某一天。因为我们假定没有预备仿真 时间(Warm Up),所以我们应当认为在第一天仿真开始时已经有预约了。因此我们首先 需要检查一下是否处在第一天。如果是的话,就创建三个实体副本当作将要处理的预约。 因为Day变量初值为4(周四),所以它将被递增到5(周五),并且初始时相当于包含了 三天的顾客预约呼叫(周一、周二或周三)。接下来会将变量Day重置为周一,并让初始 实体生成预约呼叫。

P193 图5-10 Navigate面板

生成预约呼叫、并为变量和属性赋值的模块如图5-11所示。我们已经使用过这些模块类 型中的大部分,其中两个新的模块,“延时”模块(Delay)和“分离”模块(Separate), 分别来自“高等操作”面板和“基本操作”面板。

P194 图5-11 该子模型的逻辑过程可以总结如下: 生成预约呼叫

p194 (程序代码)

第一个模块是Create,用以在每天的开始时创建实体,如输入界面5-2所示。在Name和 Entity Type栏输入相应的名称和实体类型,常数12小时表示的到达间隔时间(每天的仿真时 间长度),以及第一次创建实体的时间(第0.01小时)。剩余数据接受默认值。我们希望在 建立了控制逻辑子模型后, 再解释为什么在创建第一个实体时加入了微小的延迟, 要不然等 到那里时你可能就已经忘了这件事了!

P195 输入界面5-2 Create模块

在第一个Assign模块中,对变量Day递增1,并令变量Call Number(呼叫数)的值为1, 如输入界面5-3所示。

P195 输入界面 5-3 第一个Assign模块

然后,这个实体被送到名为Check for Startup的Decide模块,这个模块能使实体的运动按 照某种可能性或条件而产生分支。 分支的目的地是由图形连接定义的。 到达实体将检查每一 个所定义的分支选项, 并前往满足条件的第一个分支的目的地。 如果所有的指定条件都没满 足,实体将会自动从模块底部的False离开点离开。

在此处的Decide模块中(如输入界面5-4所示),我们在Type处选择了2-Way by Condition 选项,以检验当前是否处在仿真运行的开始时间,也即当前的仿真时间是否是小于1的。如 果是,就将实体送到下面的Separate模块;否则,就将它送到为呼叫数量赋值的Assign模块。

P195 输入界面5-4 Decide模块

表5-1 Decide模块中的条件符号 描述 与 大于 小于 等于 语法选项 .AND. .GT. > .LT. < .EQ. == 描述 或 大于等于 小于等于 不等于 语法选项 .OR. .GE. >= .LE. Find 菜单选项,输入要查找的字符串,就可以在 模型中找到匹配该字符串的所有位置。现在可以输入 TNOW 试试。如果由于某种原因,你 忘记了错误是什么,可以点击 Run>Review Errors 菜单选项重新打开错误信息窗口,以查看 最后的错误信息。 现在,我们将介绍 Arena 中由命令驱动的“运行控制器” (Run Controller) ,可用它来寻 找和纠正逻辑与运行中的错误。在详细介绍之前,我们先定义三个即将用到的 Arena 变量: NQ,MR 和 NR,事实上在前面几章中已经见过它们了。许多 Arena 变量可用于建立模型逻 辑,并且可以在模型运行过程中观察它们的变化。上面三个变量的含义如下: NQ(队列名称)——队列中的实体数目(队长) MR(资源名称)——资源容量 NR(资源名称)——资源中处于忙态的服务单元的数目 注意, 这些变量的值在仿真运行过程中一般都会随时间变化而改变, 所以它们描述的是仿真 运行过程中某一特定时刻的状态。 Arena 变量给出当前仿真状态的信息,由于它们是 Arena 的保留字,所以你不能重新定 义这些变量的含义, 或者把它们当作你自己定义的变量一样来处理。 建议你花一些时间去浏 览一下 Arena 的各种变量, 可以在 Arena 帮助系统中找到它们。 你可以先浏览一下变量概要, 然后在需要用到某个特定变量的更多信息时再查阅其详细的定义。 现在, 我们将打开 “运行控制器” 来演示一些常用命令的用法。 , 在这里, 我们不对 Arena 的命令用法进行详细的描述。我们建议你通过帮助文档去自己学习并运用这些 Arena 命令, 这样可以更好地掌握它们。 通过点击 Run>Run Control>Command 菜单选项,或者点击在“运行交互” (Run Interaction)工具栏上的“命令” (Command)按钮( ) ,可打开命令窗口。此刻,模型

已经可以运行了,但还没开始运行。注意当前时间为 0.0。现在让我们通过 VIEW 命令查看

模型的前四行代码。输入命令: 0.0 > view source 1- 4 屏幕将显示如下响应:

(原书 P211) (程序语句) “运行控制器”列出了由 Arena 模型生成的 SIMAN 仿真语言的前四行代码。这些代 码对应着“生成预约呼叫”子模型中前三个模块,即 Create-Assign-Decide,用以创建预约 实体, 赋初始、 以及检验是否为仿真初始状态。 注意, Arena 包括一个额外的 Assign 操作块, 作为我们所建立的模块的一部分。 既然我们现在知道了这四行代码的意义, 就可以看看执行 这段代码到底会发生什么。首先,我们需要改变“运行控制器”的设置,以便它能显示所发 生的情况。我们通过 SET TRACE 命令实现来实现,输入: 0.0 > set trace * 在运行模型时,这条命令实现了对 Arena/SIMAN 仿真语言执行的所有活动的跟踪。现 在让我们只执行这四行代码。可利用 STEP 命令来执行,它使得 Arena 一步一步地运行模型 的第一个、下一个、直到第四个操作块。输入如下命令: 0.0 > step 4 Arena/SIMAN 仿真语言将产生如下响应:

(原书 P212) (第一部分程序行) 在时刻 0.01,系统创建出一个实体,下一个实体创建被安排在 12 小时后。实体进入第 一个 Assign 操作块(包含在 Arena 中的)并进行赋值操作。接着实体被送到我们所创建的 Assign 模块,在那里变量 Day 的值增加到 5,变量 Call Number 被赋值为 1。然后,实体被 送到第二个 Decide 模块,以检验相应的条件。 现在,输入 CANCEL 命令以取消跟踪状态,并且通过 GO UNTIL 命令让仿真时间推进

到时刻 1.1。 0.0 > cancel trace * *** All trace options canceled. 0.0 > go until 1.1 Break at time:1.1 现在,系统处于仿真时间为 1.1 的状态,让我们来看看在队列中有多少实体在等待资源 服务(资源:修理间 1,修理间 2,修理间 3) 。可利用 SHOW 命令来显示模型中队列里实 体数目、队列编号、以及所有其它队列的状态,如下所示:

(原书 P212) (本页底部的程序行) 从上面可以看出, 当前在队列 Bay Queue 中有 15 个实体, Arena 赋给该队列的编号 (Bay Queue 的值)为 3。在检验一个模型的时候,Arena 给其中的每个资源、队列等都分配一个 编号,用以在模型运行时加以内部参照。Arena 为每项内容所赋的编号在本次运行和下次运 行中可能是不一样的。所以要注意,如果你编辑并保存过模型,Arena 记录下的内容可能会 与上面显示的略有不同, 因此在下一次运行模型的时候, Queue 的数值可能就不是 3 了。 Bay 有一些办法可以强制让 Bay Queue 的数值为 3,但在这里就不讨论了。 接着我们利用 VIEW QUEUE 命令来查看一下队列中的实体情况,如下所示(由于篇幅 原因,在这里我们只显示出前两个实体) :

(原书 P213-214) (程序行) 上面的信息显示了实体的内部编号以及所有其他属性值。Arena 自己定义了许多属性以 供内部调用,你或许也注意到了属性 Arrive Time 是由我们在所创建的一个模块中定义的。 由于现在有一些预约呼叫实体在队列中等待修理间资源, 因此现在所有可用资源的服务 单元肯定都已被分配完毕了。我们可以通过 SHOW 命令来检验一下,如下所示:

1.1 Hours > show NR(Bay 1) ,MR(Bay 1) NR(Bay 1)=1 MR(Bay 1)=1 为了更有趣些一些,我们现在通过 ASSIGN 命令再添加一些资源:

(原书 P214) (倒数第二段程序行) 这样, 修理车间 1 资源的服务单元数目从 1 增加到 2。 由于多出来一个可用的资源, Arena 于是把它分配给队列中的下一个实体。让我们再来看一下队列和资源的状态。

(原书 P214) (最后一段程序行) 和我们所期望的一样,可用的资源被分配给了队列中的实体,现在队列中只剩下 14 个 实体。你也许感到很吃惊,我们竟然可以随意改变资源的数目,但实际上这正是资源调度所 能做到的。不过还要记住,Arena 中有一些变量是用户无法改变的,例如,TNOW,NQ 和 NR。现在关闭命令窗口,终止仿真的运行。 到目前为止,你应该粗略地体会到了“运行控制器”是如何工作的。它让你可以直接接 触到后台运行的 SIMAN 仿真模型。你应该花费一些时间来好好研究这些命令,并且至少要 对 SIMAN 仿真语言有个大概的了解。 Arena 中还存在一些稍微简单的、至少不是那么让人恐惧的方法,可以用来检验模型的 正确性或者发现逻辑错误。最简单的方法是运用动画来显示模型的逻辑过程。但是,你首先 需要花费一些时间来深入了解才能解决问题。 “运行交互” (Run Interaction)工具栏提供了 一些工具,你可能用得到。我们已经使用过了 Check 和 Command 命令选项,现在让我们了 解一下 Run>Run control> Highlight Active Module 命令选项。 单击 Navigate 项目栏,然后运行模型。如果现在打开的是顶层模型(Top-Level Model) 视图, 你可以看到, 当实体通过某个子模型时候, 该子模型高亮显示的。 在模型运行状态下,

双击“服务活动”子模型,可以看到当实体通过模块时,这些模块被高亮显示。但是,在某 些电脑上,由于系统运行的速度比较快,你可能只能看见有实体停留的模块被高亮显示,如 Delay 和 Dispose 模块。如果不相信的话,可以通过缩放操作来使得整个屏幕只显示一或两 个模块仔细进行观察。单击 GO 或者 Step 按钮,将看到 Arena 在模块间来回跳动以显示当 前的激活模块。 但是由于运行的速度太快, 通常看不到全部模块依次高亮显示的效果, 不过, 它至少是在努力给你显示出这样的效果来。 如果你选择了如上设置,而当前窗口中又没有包括子模型中的所有逻辑模块,那么, Arena 将每次改变窗口视图以显示当前不在窗口中的模块(只针对当前子模型中模块) 。一 般说来,所显示的模块被放于窗口中央,直到 Arena 需要调用另一个不在当前视图中的模块 为止。 尽管这可以让你看到更多的激活模块, 但是在不同模块间的来回跳动显示会让人感到 头晕目眩,所以我们建议你中止模型的运行,并返回显示所有逻辑模块的视图窗口。最后, 如果想取消这种效果,可以通过停止模型运行并清除 Highlight Active Module 选项来实现。 你也可以通过更改某些选项,让模型在运行时显示所希望的效果。单击 View>Layers 显 示如图 5-17 所示的对话框。此对话框可以在运行模式下打开进行设置。在这个对话框中, 可以打开(选中)或者关闭(清除)各种不同的选项,让模型在运行时显示不同效果。

(原书 P215) 图 5-17 层次设置(Layers)对话框 现在,假设模型运行时出现了问题,而你怀疑错误出在“服务活动”逻辑中的 Release 模块上。 如果在一个实体到达这个模块的时候, 可以暂停仿真运行以查看状态, 这就太好了。 很幸运, Arena 提供三种方法实现这种方式。 你可以通过进入命令窗口直接进行相应的设置, 或者采用更简单的方式,利用 Run>Run control>Break On Module 选项来实现。首先,你需 要选中想要插入断点的模块,然后点击 Run>Run control>Break On Module 菜单选项,这会 使得被选中的模块外出现一个红色框。接着单击 Go 按钮。模型开始运行,当实体到达你选 中的模块时,运行将暂停,当然这可能需要一些时间。现在你可以检查错误(例如,可以不 断地单击 Step 按钮逐步执行,直到发现错误之处) ,或者单击 Go 按钮继续运行模型,直到 下一个实体到达此模块为止。当你不再需要插入这个断点时,先选取被插入的模块,然后通 过再次点击 Run>Run control>Break On Module 菜单选项来取消中断。

你也可以运用 Run>Run control>Break…选项或者 Break 按钮(

)在某一特定仿真

时间、或某一特定状态、或在某一特定实体上设置断点。Break on Time(按时间中断)选项 使得模型运行到所输入的时间时中止,这类似于 Run Controller 中的 GO UNTIL 命令功能。 Break on Condition(按条件中断)允许你输入一个约束条件(例如,NQ(Bay Queue)>17) , 当模型运行到满足这个条件时中止。Break on Entity(按实体中断)在实体即将被激活时中 止模型运行,对于这个操作,你需要知道实体的 ID 号码,可以通过 Run Controller 或者在 仿真暂停时双击实体图形来查看。输入界面 5-16 显示了在时刻 198 以及按前述例子条件设 置断点的情况。

(原书 P216) 输入界面 5-16 断点设置

另一个在运行过程中监测模型状态的好方法是定义 watches。在我们定义之前,建议你 先清除所有模块中的断点。单击 Run>Run Control>Watch 菜单选项或 Watch 按钮( )

打开监测(Watch)窗口。我们定义两个监测项  一个是修理间队列中的实体数目,另一 个是修理间 1 的状态,如图 5-17 所示(同时也给出了在监测窗口中显示的输出类别) 。你可 以定义任意多个监测项,如果你不定义标号项,Arena 将用相应的表达式作为缺省标号。

(原书 P217) 输入界面 5-17 检测项定义 在关闭监测窗口前,单击 Window>Tile 菜单选项,则模型窗口和监测窗口将以横向排列 的形式同时显示出来(单击监测窗口可使其激活为当前窗口) 。在模型运行时,如果监测窗 口为当前激活窗口,单击 Go 命令将会看到上述定义的两个表达式的值的变化情况。如果模 型中存在动画,也可以看到动画情况。但是注意,表达式的值只有在监测窗口处于激活状态 时才能看到不断更新的情况。 最后,在一个模型运行时,你也许想看到关于模型状态的报告。Arena 允许你在模型运

行的任何时候查看状态报告,只需简单地在工程工具栏中单击“报告” (Reports)面板就可 以了。在模型运行的时候或者处于暂停的状态下均可查看报告。和监测窗口一样,你会看到 动画式的运行状态变化, 可以每隔一段时间查看一下报告而不必中止仿真运行。 但是要记住, 当你查看完报告后要关闭该报告窗口。 即使不用 Run Controller, Run Interaction 工具栏上的各种选项也为你提供了许多检查模 型逻辑错误的便捷方式,而不需要你成为一个 SIMAN 仿真语言专家。在这里,我们建议你 打开一个简单的动画模型,练习运用这些操作,熟悉其工作原理。虽然你可以等到用的时候 再学习这些操作, 但到那时, 你不仅要学会用这些操作来查找错误, 还要学习许多新的工具! 与其把工作积到一起,还不如现在就解决掉。现在你已经知道如何使用这些工具了,我们就 可以进入下一节,为汽车维修店模型增加动画效果。

5.6 为汽车修理店模型添加动画效果
在前面我们已经提到过, 这个模型与先前那些模型有所不同, 因为在这里很难确定对哪 些模块添加动画效果。本模型共分为四个基本部分:预约呼叫、服务活动、性能指标计算和 控制逻辑,其中大多数部分不需要动画效果。但是,我们可以使预约呼叫和服务活动具有动 画效果。 下面就从预约呼叫状态开始。 在前两个子模型, 即生成预约呼叫 (Generate Appoint Calls) 和预约服务(Make Appointment)中,包括了生成预约服务的逻辑过程。回忆一下,在生成 预约以及把预约实体放到队列中等待服务日时, 我们用到过一些主要变量。 我们动画设计的 第一部分就针对这些主要变量和五个预约队列。完成动画设计后,可以得到如图 5-18 所示 的画面。

(原书 P218) 图 5-18 预约呼叫状态的动画表示 我们选定三个感兴趣的变量——当前安排的 Book Time 小时数,当前某日的预约数量以 及该日当前等待服务的顾客数量。 第一个和最后一个变量可以用我们定义的两个数组变量表 示,即 Day Load 和 Wait Load。对于某天的预约数量,尽管没有定义过该变量,但我们把

这些预约放在了一个队列中。因此,我们可以利用 Arena 的变量 NQ 来对它添加动画。我们 可以利用动画工具栏中的“变量” (Variable)按钮( )来添加动画变量。

下面给出一些在模型中添加动画效果的建议。 如果在同一个动画设计中存在多个变量或 队列,一般要求这些设计具有相同的外观。首先,添加第一个变量,输入数据,选择颜色并 设定好大小形状。以后再添加时,可以单击 Snap( )按钮,这样可以很容易地创建另

外一个大小和间隔都相同的变量。一旦第一个变量的设置完成,就可以运用 Copy 和 Paste 命令复制出四个相同的变量, 然后再对每个复制出的变量进行相应的设置即可。 在我们的动 画设计中,可单击绘图工具栏上的 Text 按钮( )添加相应的变量标识说明。

可以按照上述复制/粘贴的方式逐个添加新对象, 或者先选中所有对象 (变量、 文本等) , 然后再用 Copy 和 Paste 命令进行复制粘贴,然后把这些复制出来的对象放到合适的位置, 并编辑相应的属性。 这种方法可以减少很多不必要的工作, 而且保证了所添加的动画对象具 有统一的外观。 除了以上的变量外, 我们还在动画设计中添加了五个预约队列。 我们仍建议你先设置好 第一个队列 Monday Appointment Queue,加上所要的背景,然后利用 Copy 和 Paste 命令添 加剩下的四个队列。 尽管在这部分动画设计中没有实体的运动, 但我们能够对预约的状态变 化有个直观清晰的了解。 服务活动部分的动画设计如图 5-19 所示,我们为三个修理间设计了相应的图形,并在 每个资源图形的下面添加了文本,以显示相应的修理间编号。这里,我们再一次建议你充分 利用 Copy 和 Paste 命令的便捷性进行添加操作。接着,单击动画工具栏上的 Queue 按钮添 加队列 Bay Queue,并且选择点状队列,我们在队列中选取 24 个点位,然后按图 5-19 所示 布置各个点的位置。进行这个操作前,最好先打开 Snap to Grid 选项,这样比较容易对齐。 我们建议在设置完前三个或四个点后, 先运行模型来检验间隔是否设置恰当, 然后再进行余 下的工作。

(原书 P219) 图 5-19 服务活动部分的动画设计 在实体图形设计部分, 我们先用 Arena 自带的基本图片库。 我们用图片 Blue Page 和 Red

Page 来表示预约实体,并切掉页面图形的底部以节省队列动画空间。在修改完图形后,它 们会被保存在.doe 为扩展名的模型文件中。这些更改并不会影响以后创建的新模型。接下来 打开文件 Vehicles.plb,选取一个红色车辆的图片添加到本模型的图片库中,用它表示就地 等待服务的顾客车辆。然后,复制一份该图片,把新图片的汽车颜色改为蓝色,用这一图形 表示正常状态的车辆。 最后,我们添加一个时钟和显示星期的对象到模型中,如图 5-20 所示。通过添加时钟, 观察者可以得到动画显示的仿真时间的当前状态。回忆一下,在这个模型中,一天的仿真时 间为 12 小时,并且要在第一个小时内处理预约呼叫,紧接着是 8 小时的正常工作时间和最 后 3 个小时的可用加班时间。因此,我们的时钟设计为 0 到 12。单击“动画”工具栏上的 Clock 按钮( ) ,在 12 小时制和 24 小时制中选择前者。但是,如果我们仿真一天的时间

不是 12 或者 24 小时,而是其他某个值,则无法利用此按钮选项设置了。下面,我们来介绍 一下怎么按自己的要求创建时钟。

(原书 P220) 图 5-20 时钟和日期指示器 我们的时钟利用两个动画变量来显示,由冒号隔开。其中第一个变量表示当前小时数, 第二个变量表示当前分钟数。下面来看一下怎么计算出这些变量的值。 首先计算出当前小时,如下表达式 AINT(TNOW-AINT(TNOW/12)*12) 将返回由 Arena 变量 TNOW 得出的当前小时。AINT 函数返回参数的整数部分,即对表达式 的值截断取整。可以很容易地验证上述表达式的正确性。这里返回的时间是基于 12 小时制 的。要在动画过程中显示小时,只要选择动画工具栏中的 Variable 选项,并输入上述表达式 即可。 计算当前分钟更容易一些,尽管表达式看起来有点复杂。如下表达式 (TNOW-AINT(TNOW) )*60 将返回当前分钟值。 如果你想让当前小时和当前分钟变量显示相同的外观, 建议你首先设置好当前小时变量

的大小外观,然后运用复制、粘贴和编辑操作得到当前分钟变量。 接下来, 添加日期指示器到模型中。 单击动画工具栏中的 Global 按钮 ( ) 打开 “全 ,

局图形布局” (Global Picture Placement)窗口,如输入界面 5-18 所示。这个窗口与实体以及 资源图片窗口类似。首先输入一个表达式(在本例中为变量 Day) ,然后为这个表达式关联 一张带有触发值(Trigger Value)的图片。你可以定义任意多对(触发值,图片)以显示所 需要的图形。在关联图片时,首先创建相应的图形,与创建实体及资源图形一样,只不过这 些图片关联的是所输入表达式的当前值。在本模型中,表达式 Day 的值在每次开始仿真的 时候都被置为 4,接着增加到 5,然后变为 1,接下来每隔 12 小时增加 1(当增加到 6 时被 重置为 1) 。指示器显示的初始符号为 THURSDAY。当变量 Day 的值变为 5 后,符号显示为 FRIDAY,然后随着时间变化为 MONDAY 等。

(原书 P221) 输入界面 5-18 用于定义当前日的“全局图形布局”窗口 为了保证所有的符号统一外观,我们先创建第一个符号,MONDAY,然后再通过复制、 粘贴和编辑建立其它符号。关闭“全局图形布局”窗口后,需要在模型中的适当位置放置全 局变量符号,操作方法和放置文本一样。然后可能需要改变这些符号的大小,可以在模型窗 口里直接更改,也可以重新打开“全局图形布局”窗口,通过设置“缩放系数” (Size Factor) 来改变所显示图形的大小。最后为变量添加标签,并在变量和符号上添加一个框。最终的动 画图形如图 5-21 所示,图中显示的是第一次仿真中的第一天的情况。

(原书 P222) 图 5-21 汽车维修店动画设计 当你完整地运行完模型后, 在分类总结报告中将给出十次重复仿真运行的情况汇总 (你 也可以通过 Reports 面板上的 Category by Replication 选项查看每次运行的情况) 。尽管我们 将不显示完整的分类总结报告, 我们还是会介绍其中一些感兴趣的统计结果。 由于对这个模

型我们选择了独特的性能指标, 因此只对这个报告中的两部分感兴趣。 第一部分统计数据是 修理间的资源利用情况。三个修理间每天被使用的时间大约都为 7.8 小时,这也许意味着我 们应该增加每天所允许安排的 Book Time 小时数,即 Max Load 变量的值。我们将在 6.4 节 作出这些变更(并在那里对这个变更的影响做适当的统计分析) 。 我们感兴趣的第二部分是分类总结报告中的输出统计,如图 5-22 所示。平均每天加班 时间为 1.8 小时, 平均每天利润为$536.14。 注意, 修理间每天的平均使用时间仅为 7.8 小时, 而每天平均加班时间却为 1.8 小时,可以看出这个系统的不确定性程度很高。我们也将在第 六章详细讨论这个问题。

(原书 P223) 图 5-22 汽车维修店输出统计 如果在学习本章的过程中, 你还没有试着建立自己的模型, 那么现在可以打开我们创建 好的模型(Model 05-01.doe) ,并在各个模块中浏览一下,以确认自己已经了解了我们所讲 述的各种概念以及特征。

5.7 模型 5-2:进一步完善汽车维修店模型
现在假设你已经完成了模型设计, 并且请客户进行了运行体验, 而客户则发现模型中遗 漏了一些东西。这种现象在现实世界中经常发生。客户在原来描述问题的时候,忘记了告诉 你两个主要的问题,以至当前的模型中缺少了解决这些问题的能力。第一个问题是,并不是 所有的服务都能在任意一个修理车间进行。为了降低设施费用,客户对修理间 2 和修理间 3 进行了全面装备,使得它们能完成所有的工作。但是修理间 1 只能为一部分顾客提供服务 (40%) 。第二个问题是,并不是所有的顾客都在一天的开始时到达。实际上,还存在一些 顾客根本就不来的情况。经过对历史数据的统计分析发现,大约 60%至 70%的顾客能按约 定准时到达。在模型设计中,我们假定这个比例服从参数为 0.6 到 0.7 的均匀分布。余下部 分的顾客一般在随后的两个小时内随机到达, 偶尔会有一个顾客不来。 我们对这些数据进行 了分析,将在后面把结果告诉大家。

5.8 模型 5-2 建模中的新问题
从建模的观点来看,这里涉及到几个新的概念。为了解决上面第一个问题,我们引入一 个新的集合,并且重新考虑模型的逻辑结构,以使修理车间资源得到最有效的利用。对于上 面的第二个问题,我们将更改顾客到达的过程,并找出一种方式来对迟到的顾客建模。

5.8.1 集合与资源逻辑
在新模型中,仍保留修理间资源集(集合 Bays) ,但是只有一部分服务是由这个集合提 供的。因此,必须创建一个新资源集合,在这个集合中只包括修理间 2 和修理间 3,它们向 其余的顾客车辆提供服务。然后要设置优先级,以更有效地利用资源。一般来说,我们需要 把以上两种不同类型的顾客分配到两个不同的队列中。下面,我们将介绍 Arena 如何为等待 的实体分配资源。 如果所有等待资源的实体都处于一个相同的队列中,那么分配资源的过程是比较明了 的。但是,如果一个模型中存在多处地方可能分配同一资源的情况(不同地方有不同的 Queue-Seize 组合) ,这时候就需要使用一些特殊的分配规则。首先,我们来考虑一下为实体 分配资源时可能遇到的不同情况:    一个实体需要有资源提供服务,而且现在该资源是可用的 资源变为可用状态,而且需要资源提供服务的实体处于同一个队列中 资源变为可用状态,而且需要资源提供服务的实体处于不同队列中

对于前两种情况,资源分配相对较为简单,但我们还是介绍一下如何进行的。 如果一个实体要求资源提供服务,并且资源现在是可用的,则没有什么要考虑的,资源 直接被分配给该实体。对于第二种情况,资源可用,但是有多个实体排在一个队列中等待该 资源提供服务,此时则把资源分配给队列中的第一个实体。这种情况下,关键因素是如何确 定实体在队列中的排列顺序。 Arena 提供四种排队规则: 先进先出 (First In, First Out: FIFO) ; 后进先出(Last In,First Out:LIFO) ;低优先权值优先规则(Low Value First) ;低优先权值 优先规则(High Value First) 。其中,FIFO 是默认规则,按照实体进入队列的先后顺序排列 其位置。LIFO 把最后到达实体放在队列的最前面(类似于堆栈) 。最后两条规则根据每个实 体的优先级别来排列顺序,其中级别可定义为相应的表达式并赋给实体的某个属性。例如, 当实体到达系统的时候, 可以将每个实体的交货期赋给相应的优先级属性。 如果你选择 Low Value First 规则,就相当于按照交货期来确定队列中实体的排列顺序,交货期紧的实体排在

前面。 如果需要资源提供服务的实体处于不同的队列中,情况则有点复杂。首先,Arena 会比 较各队列相对于该资源的占用优先权。 如果一个队列的占用优先权值比其他的小 (即优先级 高) ,则资源被分配给该队列中的第一个实体。如果所有队列的优先权值相等,则 Arena 运 用一个默认规则来选择,即资源被分配给等待时间最长的实体,而不管它在哪个队列中。因 此,这实质上是一种 FIFO 规则在具有相同优先权的多队列情况中的应用。这意味着如果多 队列中实体按照最早交货期规则排列,则可能出现满足该准则的实体却分不到资源的情况。 例如, 一个已经被延误的实体可能刚刚进入某个队列, 而另一个交货期绰绰有余的实体却已 经在另一个队列中等了一段时间了, 此时资源会被分配给等得时间长的实体, 而不是分配给 交货期紧的实体。 Arena 提供了一种解决这种问题的方式,即共享队列(shared queue) 。共享队列如它的 名称所显示的一样  两个或者更多的占用活动共享同一个队列。这可以让你定义一个队 列, 把模型中所有需要资源服务的实体都放在里面, 而不管它们的占用行为发生在什么位置。 Arena 将记录每个实体的位置信息,以保证在共享队列中的实体分配到资源后能按模型逻辑 被送往相应的位置。 这解决了模型中存在多个位置要求分配同一种资源的问题, 但并没有解 决在含有某些公共资源的不同集合中占用资源的问题,而这正是我们的模型中存在的情况。 我们将很快介绍如何解决这一问题。

5.8.2 非平稳达到过程
通过改变模型来限制准时到达的顾客的数量是相当容易实现的,我们将在 5.9.2 节加以 介绍。不同之处在于迟到的顾客的到达过程,其到达率是随时间变化的。这种类型的到达过 程在服务系统中相当典型, 需要用一种不同的方法来解决。 许多系统的到达过程都按平稳泊 松分布(stationary Poisson process)来建模,在这种分布中,每次到达一个顾客,并且顾客 的到达相互独立, 平均到达率不随时间变化。 这意味着到达间隔时间将服从一个固定均值的 指数分布。对于那些对概率不太感兴趣的用户,并不需要完全理解这个分布的含义,只要能 利用这种分布来表示模型中的到达过程就可以了。 在我们以前建立的大多数模型中 (不包括 模型 4-5,那个模型只是为说明一个特殊知识点而建立的) ,都用到了这种概率分布。在第 四章的“电子装配与测试系统”中,零件 B 的到达过程对该分布稍微做了一点变化。在那 个例子中, 我们假设到达过程是按照四个零件一批来进行的, 但每批的到达情况仍服从平稳 泊松分布。

在本节模型中, 未按时到达的顾客的平均到达率是一个时间的函数。 这种类型的到达过 程通常都按非平稳泊松分布(nonstationary Poisson process)来建模。一个想当然(但并不 正确)的建模方法是,对 Create 模块中的 Time Between Arrivals(到达间隔时间)栏输入一 个指数分布, 并用一个用户定义的变量作为均值, 然后根据当前时间段的到达率改变这个变 量值。在我们的例子中,需要每 15 分钟更改这个值一次。如果不同时间段的到达率变化不 大,上述方法可以提供一个近似正确的结果。但是如果到达率变化很大,这种方法将会给出 误导(以及错误)的结论。为了说明这个问题,最简单的方法是考虑如下一个极端情况的例 子。假设在模型中只有两个时间段,每个时间段 30 分钟。第一个时间段的到达率是 3(平 均每小时到达数) ,或者说平均到达间隔时间为 20 分钟;第二个时间段的到达率是 60,或 者说平均到达间隔时间为 1 分钟。假设第一个时间段中最后一个实体在第 29 分钟到达,我 们将用平均到达间隔时间 20 分钟产生下一个到达的顾客。 利用均值为 20 的指数分布很容易
1 得出下一个实体的到达间隔时间会大于 31 分钟。 这将导致在下一个时间段没有顾客到达,

而实际上,下一个时间段的期望到达数为 30。2 一般说来,在从一个时间段到下一个时间 段、且到达率变大(或到达间隔时间减小)的情况下,利用这种简单的方法会导致第二个时 间段内的到达数被错误地减少。同理,在到达率变小或到达间隔时间增大的情况下,会导致 第二个时间段内的到达数被错误地增大。 学会正确地建模并运用此类到达过程是非常重要的, 因为大多数情况下到达过程都会呈 现这种特征, 如果忽略了非平稳这个特性模型就会产生严重的误差而影响其有效性, 因为到 达的高峰与低谷会很明显地影响到系统的性能。 幸运的是, 利用 Arena 在 Create 模块中的内 置功能可以正确地生成非平稳泊松到达过程。我们将在 5.9.2 节介绍如何运用此方法,更基 础的方法将在 12.3 节介绍。

5.9 构建模型 5-2
因为在新模型中有两个与原模型不同的地方, 我们将把它们当作两个附加的问题加以解

1

准确(几乎准确)地说,其概率为 e  0.21 。实际上,这个数值是在给定第一个时间段中有顾客 到达且最后一个到达时刻为第 29 分钟的条件下,第二个时间段内没有实体到达的条件概率。但这并不是我 们所需要的,我们需要的是第二个时间段内没有顾客到达的无条件概率。这个是可以求出来的,但比较复 杂。 但是容易得出这个概率的一个下界, 可由 “第一个顾客在时间 0 后到达、 由均值为 20 的指数分布生成、 并在第 60 分钟后发生”这一事件的概率来估计。这是处理第二个时间段内没有顾客到达的一种方法(不是 唯一的) ,其概率为 e  e  0.0498 。因此,按照那个不正确的方法,至少有 5%的可能性在第 二个时间段中没有实体到达。现在,回到原文,看下一个句子,并且注意第二个脚注。
60 / 20 3

31 / 20

2

第二个时间段没有实体到达的概率应该为 e

60 (1 / 2 )

 0.000000000000093576 。

决。 首先, 我们针对三个修理车间并不是都能提供所有服务这一问题来对模型进行相应的变 更。解决完这个问题后,再处理顾客到达问题。

5.9.1 构建修理间模型
在模型 5-1 中,需要进行三处基本逻辑修改,以正确描述三个修理间的服务。首先,需 要定义一个新属性来表示新任务的类型。 接着还需要增加一个新的集合, 在这个集合中包含 两个能提供所有服务的修理间资源。最后,还需要更改服务逻辑。我们将按照上述顺序对模 型进行修改。 首先,我们要在“生成预约呼叫”子模型中名为 Assign Appointment Attributes 的 Assign 模块中增加一条赋值。所要赋的值由离散分布 DISC(0.60,1,1.0,2)产生,并把其赋给 一个新属性 Job Type(任务类型) 。如果所赋的值为 1,则表示可以在任何一个修理间接受 服务;如果值为 2,则只能由修理间 2 或 3 提供服务。接下来要定义一个名为 Bays 2 or 3 的 集合,这个集合的成员包含可以提供任何类型服务的修理间 2 和修理间 3。 现在我们需要更改“服务活动”子模型中的逻辑。新的逻辑如图 5-23 所示。观察一下 这个逻辑图,你可以看出左面的五个 Hold 模块和模型 5-1 是一样的。

(原书 P226) 图 5-23 新的服务活动逻辑 第一处变更在 Assign 模块 Assign Entity Picture 中。在这里我们需要识别动画中两种新 的任务类型。为了达到这个目的,我们在 Vehicle 图形集合中增加两种新图形。首先分别复 制红色车辆和蓝色车辆, 并把它们的车门颜色改为黄色。 现在这个集合中包括了如下四种图 形:Red Car(红色车辆) ,Blue Car(蓝色车辆) ,Red Yellow Car(红黄相间色车辆)和 Blue Yellow Car(蓝黄相间色车辆) 。其中红色车辆的优先权值为 1, 任务类型(Job Type 值) 为 1;蓝色车辆的优先权值为 2,任务类型为 1;红黄相间色车辆的优先权值为 1,任务类型 为 2;蓝黄相间色车辆的优先权为 2,任务类型为 2。回忆一下,优先权为 1 表示顾客希望 就地等待服务, 而工作类型为 1 表示可以在任何一个修理间接受服务。 新的图形集合中元素 的引用表达式如下: Vehicle(Priority+(AINT(Job Type/2))*2)

当你观看动画显示的时候,就可以分辨出这两种不同类型的任务了。 对子模型余下部分的更改包括,在此 Assign 模块之后插入一个新的 Decide 模块,并增 加一行处理新任务类型的新模块。这个新 Decide 模块用来把属于任务类型 1 的实体送到上 面一行的模块中,即条件为 True 的出口,这些工作能在任一修理间完成。那些只能在修理 间 2 或 3 接受服务的工作(任务类型值为 2)将被送到下面一行的模块中,即 False 分支的 出口。上面一行中的四个模块除了有一个小的改动外,和模型 5-1 中的几乎一样,我们将在 后面加以介绍。 通过运用“复制/粘贴”命令来建立下面一行的四个模块,然后根据需要对模块参数进 行相应的更改。首先,更改模块名称以保证其唯一性,接着打开新的 Seize 模块(Seize Bay 2 or 3) ,把资源名称改为 Bays 2 or 3(我们刚定义的新集合) 。对下一个集合的修改需要做出 一些解释! 我们现在有两个 Seize 模块用以描述对修理间资源的占用。上面一行的模块可以使用所 有三个修理间资源,而下面一行的模块只能使用修理间 2 或 3。需要找到一种方法设置优先 级,以更有效地利用修理间资源。在我们的模型中有两个层次的优先级。第一个层次是确定 队列中实体的排列顺序。当我们把新 Seize 模块的名称改为 Seize Bay 2 or 3 时,系统同时更 改了与之相关联的队列的名称,即 Bays2 or 3 Queue。现在每个 Seize 模块都有一个相应的 队列。两个队列都根据 Priority 属性值(顾客优先级)按照 Lowest Attribute Value 规则排列 实体。这意味着希望就地等待服务的顾客将排在队列的前面并首先得到服务。因为修理间 1 只能分配给上面一行的 Seize 模块,所以我们只要考虑如何分配修理间 2 和 3 就可以了。由 于在下面一行的 Seize 模块中的实体只能被分配到修理间 2 或 3,因此我们将为这行 Seize 模块赋予比上面一行 Seize 模块更高的优先级(资源占用优先级) 。 首先解释一下我们的模型逻辑, 然后再介绍如何实现。 我们将只考察每个队列中的第一 个实体以及修理间 2 和修理间 3。如果两个队列中的第一个实体都是就地等待服务的顾客, 且修理间 2 或 3 现在可用,那么我们将把资源分配给 Job Type 为 2 的实体,因为这种类型 的实体只能占用修理间 2 或 3,而另外一种类型的实体可以占用任意一个修理间。如果两个 实体都是希望把车辆留下的顾客(优先级均为 2) ,则可以采用与上面相同的逻辑。我们在 设计逻辑时,要保证优先为就地等待的顾客(优先级为 1)提供服务。 可以通过在两个 Seize 模块的 Priority 域设立如下表达式来实现上述逻辑。对于上面一 行的 Seize 模块,表达式为 (Priority*10)+1

对于下面一行的 Seize 模块,表达式为 Priority*10 这将会得到如下优先级结果: 顾客优先级为 1 且任务类型为 1 的实体,其资源占用优先级为 11, 顾客优先级为 2 且任务类型为 1 的实体,其资源占用优先级为 21, 顾客优先级为 1 且任务类型为 2 的实体,其资源占用优先级为 10, 顾客优先级为 2 且任务类型为 2 的实体,其资源占用优先级为 20。 这些资源占用优先级的确定能使我们所设计的逻辑得以实现, 因为它意味在相同顾客优先级 的前提下,任务类型为 2 的顾客一般将首先得到服务。当你观看最后的动画时,就可以看到 相应的效果。 对于余下的 Assign 和 Delay 模块,除了更改模块名称外,不需要作其他的改动。对这 个子模型的最后一处更改是针对最后一个新 Release 模块的, 我们把资源集合名称改为 Bays 2 or 3。最终的更改是在动画中增加新队列 Bays 2 or 3 Queue。 尽管优先级逻辑的定义有点不太好理解, 但是相应的的修改工作却很简单。 以上解决了 我们新模型的第一个问题。下面我们将考虑更复杂一些的第二个问题  顾客到达过程。

5.9.2 对顾客到达过程建模
为了解决第二个问题,我们必须修改顾客到达过程。在模型 5-1 中,在工作日即将开始 的时候,释放预约队列中所有的客户预约服务。而在这个模型中,我们只需要释放一部分客 户预约服务。 我们还需要增加部分模型逻辑来描述后来的顾客到达以及最终删除预约队列中 那些没有前来的顾客。所有这些逻辑都在“控制逻辑”子模型中添加,如图 5-24 所示。

(原书 P229) 图 5-24 新的控制逻辑子模型 首先, 加入逻辑过程描述在每个工作日的开始只释放部分顾客的预约服务。 这涉及对模 型 5-1 中逻辑过程的两处修改 (图 5-24 所示的第一行模块所描述的逻辑) 在 Create 模块后, 。 我们加入一个新的 Assign 模块,Determine On Time Arrivals。这个模块的赋值内容如图 5-25 所示。在第一个赋值操作中,我们确定准时到达的顾客的数量,并把它赋给一个新的变量

On Time。这只需从参数为 0.6 和 0.7 的均匀分布中产生一个随机数值,然后乘以当前预约队 列中的预约数量,并对这个结果舍入取整(ANINT 函数)就可以了。接下来,从当天的预 约数量中减去这个值,即可得到可能迟到的顾客的数量,并把它赋给一个新的变量 Late。最 后,我们定义一个新变量 Total Late 并不断更新其值,它表示迟到顾客的总数。你可能已经 注意到了, 这个值中可能包括没有前来履约的顾客。 我们在迟到顾客总数中随意选择了某个 数值作为爽约的顾客数。

( 原书 P229) 图 5-25 确定准时到达顾客数的 Assign 模块 第二个更改是在紧接其后的 Signal 模块中进行的。在模型 5-1 中,信号的 Limit 域采用 了默认设置,即允许 Hold 模块释放无限多个等待此匹配信号的实体。在这个新模型中,我 们输入变量 On Time 作为 Limit 域的值。 这将限制 Hold 模块只释放数量为 On Time 值的实体。 如果现在运行这个模型看动画效果, 你就会注意到并不是所有的预约服务都在每天开始时候 被释放(为了看清楚这个情况,可能需要减慢动画的速度) 。你可能还会注意到,被释放的 实体都位于队列的前面部分, 它们在队列中的位置由它们建立预约的时间决定, 这看起来是 个很合理的假定条件。 现在我们来建立考虑迟到顾客到达的逻辑, 该逻辑过程表示在图 5-24 的第二行模块中。 通过对实际中的有效数据分析发现, 后来的顾客都会在工作日开始后的两个小时内到达。 在 对这些数据进行分析时,在这两个小时内每 15 分钟观察一次,共八次。这些时间段内的到 达率分别为 7,6,4,3,3,2,2 和 1(单位为到达数/小时) 。首先,我们需要在 Arena 的 Schedule 数据模块中输入数据。先增加一个新的调度项 Late Arrival Schedule,并在 Type 栏 选择 Arrival 选项。 如果你一直跟着本书的讲解同时建立模型,别忘了模型中的调度要覆盖全天 12 小时, 所以你可能需要在最后的一些时间段中补充定义一些 0。如果你使用图示调度编辑器 (Graphical Schedule Editor) 来设置, 首先需要打开 Options 对话框, 并在 Time Slot Duration 中选择 15 Minutes,设置 Range 栏为 48(每小时 4 个时间段,共 12 小时) 。然后就可以开始 创建调度内容了,在第 5 到第 12 个时间段中分别输入上面给出的到达率即可。剩下时间段 的到达率设为 0。如果你以这种方法创建调度,看起来好像已经覆盖了全部 48 个时间段,

但实际上只覆盖了前 12 个时间段(前面四个时间段到达率为 0,后面的 8 个时间段到达率 为正数) 。 图示调度编辑器并没有假定每个调度都要覆盖一天(可以为任意时间长度) 。在这种情 况下, 调度将在第 13 个时间段重新开始, 因此我们实际上只定义了一天 12 个小时中的三个 小时。我们应该在 Options 对话框中的 When at the end of the schedule 一栏选中 Remain at arrival rate 选项,并令右边的数值为 0,这样才能得到第一天正确的调度。但是这样做带来 的问题是,由于我们选择了用单次仿真模拟 20 天的运行情况,故此第一天以后的调度值永 远都是 0。因此,我们需要设法保证只是后九个小时的时间段(也就是最后 36 个 15 分钟时 间段)的调度值为 0。可以通过右击 Schedule 数据模块中的 Durations 项来定义,右击后选 择 Edit via Dialog(通过对话框编辑)或者 Edit via Spreadsheet(通过数据表编辑) 。选择 Edit via Spreadsheet 将打开如图 5-26 所示的 Durations 窗口, 在窗口中可以通过双击来增加新行, 并在其中输入 Value(参数值)和 Duration(相应的持续时间)组合。对于 Arrival-Type(到 达类型)的调度,默认时间单位通常是小时,所以对于有到达发生的八个 15 分钟时间段, 我们输入持续时间为 0.25。最后输入的一对数据(0,9)表示,在后九个小时时间段中调度 值为 0。这样就把一天全部 12 小时的到达率都设置好了。 选择 Edit Via Dialog 也将打开 Durations 对话框框,输入的内容与上面相同。如果在添 加这些数值后重新打开图示调度编辑器, 将显示存在非整数持续时间的信息。 加入你采用的 是 15 分钟(而不是 0.25 小时)作为时间段长度,你将能够看到图示的调度。注意,如果你 要这样做的话, 记住在退出图示调度编辑器时不要保存数据, 否则刚才为最后部分新定义的 零调度值将会被删除。

(原书 P230) 图 5-26 Durations 数据表窗口 既然我们已经建立了到达调度,现在就来看一下有关的逻辑过程。输入界面 5-19 所示 Create 模块,将能够根据我们先前定义的非平稳泊松到达分布来生成实体(到达) 。

(原书 P231) 输入界面 5-19 创建晚来的顾客到达 Create 模块在每天的第一个小时内不产生到达, 并根据输入的到达率产生第二个小时和 第三个小时的到达,而在最后的九个小时内则没有到达。在其后的 Decide 模块中,通过查 看变量 Late 的当前值来确定当天是否还有没来的顾客。如果这个变量的值为正,表明还会 有顾客到达。如果表达式的值为 True,则实体将被送到下一个 Signal 模块,在那里发出一 个信号,其 Signal Value 域为变量 Day 的值,Limit 域为 1。这将使得当天预约队列中的下一 个实体被释放出来得到服务。 然后,控制实体被送到其后的 Assign 模块,在这个模块中,变量 Late 的值减 1。控制 实体接着被送到这行的最后一个模块中并被清除。 如果创建了一个控制实体, 而所有顾客都 已经到达(Decide 模块中的表达式值为 False) ,则实体将直接被送到 Dispose 模块。以上即 为后来到达的顾客的所有逻辑过程。 不过我们还没有最后结束, 因为还有可能在当天预约队列中的顾客实体不来了。 我们增 加最后一行逻辑结构来处理这种情况。 第一个模块在第一天第 3 小时的时候创建一个控制实 体,其后每 12 小时创建一个。然后这个实体被送到其后的 Decide 模块来判断变量 Late 的 值是否为正。如果为正,则意味着实体将保留在当天预约队列中(也可以通过 Arena 变量 NQ 来查看队列中的实体数目) 。所有这些实体都被认为是爽约的顾客。如果这个表达式的 值为真,则实体将被送到后面的 Remove(移除)模块。 Remove 模块从队列中移除实体并把它送到模型中的另一个地方。这需要通过输入队列 标识符和实体所在的位置 (在队列中的位置, 值为 1 表明在最前面) 来指出所要移除的实体。 如果你试图从一个未定义的队列中移除实体,或者所指定的位置大于队长,则 Arena 将终止 运行并产生一个错误。 Arena 中有两个可用的 Remove 模块, 在 一个在 Advanced Process (高 等操作)面板中,另一个在 Blocks(操作块)面板中。这里我们需要使用 Blocks 面板中的 模块,因为需要为 Queue ID 输入一个表达式,用来表示 Appointment Queues 集合中的一个 特定队列。Advanced Process 面板上的 Remove 模块虽然允许你输入一个表达式,但是在你 检验或者运行模型的时候会产生错误。

(原书 P232)

输入界面 5-20

Blocks 面板中的 Remove 模块

我们逻辑结构中的 Remove 模块如输入界面 5-20 所示。在 Rank of Entity 部分(实体在 队列中的位置)输入 1,并在 Queue ID 处输入表达式 Appointment Queues(Day) 。队列中被 移除的实体将被送到模块右边的底部出口点,也即被送到 Dispose 模块,从那里退出系统。 原来的控制实体将从上面的出口点被送到下一个 Assign 模块。 在 Assign 模块中,变量 Late 的值减 1,新变量 Total Missed 的值增 1。后面这个变量表 示爽约顾客的总数。也许我们应该对变量 Total Late 的值也减 1。在当前模型中,变量 Total Late 的值也包括了爽约的顾客数, 而我们忽略了这个小细节, 这表明着我们建模并不很完美 (大多数时候都会是这样的) 。我们可以很容易修正这个小问题,在模型运行结束时从变量 Total Late 中减去 Total Missed 即可。但由于我们在评价系统主要性能指标时并不考虑它们, 所以就不去修改了。完成赋值后,控制实体又被送回到 Decide 模块,以检查在当天预约队 列中是否还有顾客。 以上完成了对“控制逻辑”子模型的逻辑更改。我们还对模型做了一个额外的修改,在 Statistic 数据模块中增加了两个输出项,用来输出平均每天晚到的顾客数量,以及平均每天 没来的顾客数量。

(原书 P233) 图 5-27 模型 5-2 汽车维修店问题的统计量输出结果 运行这个新模型,并与模型 5-1 的结果加以比较,将会发现修理间资源的利用情况大约 为每天 7.46 小时 (模型 5-1 中大约为 7.8 小时) 这与我们的预期相符, 。 因为每天平均有 0.765 个顾客不来,这导致了模型 5-2 中大约有 0.34 小时的资源空闲时间。其它结果如图 5-27 所 示。 如果把这些结果与模型 5-1 的结果(见图 5-22)相比较,将会发现这个新模型的每天平 均加班时间和平均利润都减少了。 这是因为在新模型中存在爽约的顾客, 所以这个结果是合 理的。 到这里,汽车维修店模型的设计就结束了。在第六章中,我们将用模型 5-2 作为终态仿 真统计分析的基础。

5.10 模型 5-3: s,S)库存系统仿真 (
在本章的最后,我们将研究一类完全不同的系统,即库存系统,通过分析对此类操作的 。我们 建模,以表明系统仿真以及 Arena 的广泛适用性(不仅仅只能用来建立排队型模型 3) 将只使用 Blocks 面板和 Elements 面板上的模块, 主要为了说明它们的用途以及如何使用 (实 际上是如何使用 SIMAN 仿真语言) 。在习题 5-17 中,我们会让你运用 Basic Process 和 Advanced Process 面板上的高级建模工具重新创建这个模型。这个模型实际上和 Law and Kelton(2000)一书第 1.5 节中的那个模型是一样的。

5.10.1 系统描述
Bucky 装饰品公司是一个多国仓储公司,它保存一种类型的产品(当然是一种装饰品) 。 由于装饰品是不可分割的,因此库存水平必须是个整数,在这个模型中我们将用 I (t)表示, 其中 t 表示从仿真开始到现在的时间(单位为天) 。开始时,系统中装饰品的初始存量为 60, 即 I (0) = 60。 顾客到达间隔时间服从均值为 0.1 天的指数分布(昼夜连续不停) ,且第一个顾客不在 时刻 0 到达,而是在 0 时刻之后的一个到达间隔时间后到达。顾客需求为 1,2,3,或 4 个 装饰品的概率分别为 0.167,0.333,0.333 和 0.167。如果当前库存能满足一个顾客的需求, 则该顾客就会得到所有需求量并满意地离开。 但是如果当前库存低于顾客的需求量, 则顾客 就取完现有的全部装饰品(有可能什么也没有) ,余下不足部分作为未交付订货,等到库存 补充足够后顾客再取。通过允许库存水平 I (t)为负值可以及时反映这种情况,虽然这没有什 么物理意义,但却是种很方便的会计技巧。另外,还假定具有未交付订货的顾客会一直等下 去,且从不取消他们的订货。如果库存水平已经为负值了(例如已经有未交付订货) ,而此 时还有更多的顾客需求,则直接把需求量变负加到库存水平上即可。在这里,我们并不考虑 未来到达的装饰品是用来满足哪些具有未交付订货的顾客的 (因为他们非常礼貌, 所以不需 要考虑这个) 。 在每天开始时(包括第一天开始时的 0 时刻) ,Bucky 会查看库存水平以决定此时需不 需要向某个装饰品供货商发出订单。如果库存水平值(可以为正或负)已经(严格)小于常 数 s(假定 s=20) ,则 Bucky 将开始订货并使其库存达到另一个常数 S(定义 S=40) 。这意味

3

正如 Car M.Harris 最近指出的, “排队(queueing) ”显然是英语中唯一一个有五个(或以上)连续元音字 母的单词,见 Gass and Gross(2000) 。

着如果订货能即时到达的话,则订货量将刚好能使库存水平增加到 S。因此,如果 t 是一个 整数,I (t)是某天开始时的库存水平(可能为正、负或零) ,且 I (t) < s,Bucky 的订货量将 为 S- I (t);如果 I (t) S,则 Bucky 什么也不需要作,只要在下一天开始时(也即在时刻 t+1) 再进行检查即可。由于采用了以上这种库存检查/补充方式,故这类系统通常被称为(s,S) 存储模型。 但是,在一天开始时下的订单通常是不可能立刻到货的,而是在后半天的某个时候,即 存在一个交货间隔期(也称为提前期) ,该间隔期服从以 0.5 和 1 天为参数的均匀分布。所 以当订货到达时,库存水平将增加所订货物的数量;但是,如果在订单下达后有新的需求发 生,则在订货最终到达,库存水平将是一个小于 S 的值。注意,在确定库存检查时间和交货 间隔期时,要保证最多只能有一批订货在路上,以至于将不会同时存在超过一个订单,因为 在一天开始时所订的货物最迟将会在这一天结束(也即在第二天开始)前到达,这是下另一 个订单的最早时机。习题 5-18 能帮你更好地理解这些含义。 Bucky 所感兴趣的是这个系统运行 120 天的平均总运作费用, 该费用由如下三个部分组 成:  平均每天的订货费用(Average ordering cost per day) 。每订货一次将花费$32(不 论订货量大小) ,再加上每单位货物$3。如果没有订货,则不存在订货费用,甚至 $32 的固定费用也不存在。$3 不是一个装饰品的(批发)价格,而是 Bucky 每订一 个装饰品的管理费用(在这个模型中我们不考虑价格) 。在 120 天仿真结束时,所 有累计的订货成本除以 120,即得到平均每天的订货费用。 。无论什么时候,只要库存中  平均每天的储存费用(Average holding cost per day) 有实际的产品(也就是说,I(t)>0) ,则储存费用为每天每单位$1。因此总的储存费 用为

(原书 p235 第一个公式) (考虑一下) 平均每天的储存费用就是总储存费用除以仿真时间长度, 120 天。 , 即  平均每天的缺货费用(Average shortage cost per day) 。无论什么时候,只要存在未 交付订货(也就是说,I(t)Setup>Project Parameters。这些模块中没有多少需要看的东西,这里将略过这些视图, 读者可以自己查看。

原书 p238 图 5-30 Expressions 构模元素

原书 p238 图 5-31 Replicate 构模元素 图 5-31 所示的 Replicate 构模元素基本上与 Run>Setup>Replication Parameters 菜单选 项一样。其中只有两个输入项用非默认值,第一,把基准时间单位(Base Time Units)改成 Days,因为所有的时间度量都使用天,而且 Blocks 面板的模块中没有提供指定输入时间单 位的地方,这里假设都使用基准时间单位。第二,指定重复仿真运行时间长度(Replication Length)为变量 Days to Run,这个变量的初值为 119.9999,目的是避免在时刻 120 进行没用 的库存检查。 图 5-32 给出了 DStats 构模元素及其 Holding Cost 数据项,它的作用与 Statistics 模块中 对时间持续性变量的统计功能相同(也即 Statistics 模块的 Time-Persistent 部分) ,在这里, 主要是累计储存费用和缺货费用。在图 5-32 中可以看到一部分 SIMAN 表达式

(原书 p239 第一个公式) 这是 Inventory Level 为正时的瞬时储存成本(回忆一下,MS 是 Arena 的内置公式,用来求 取并返回最大值) 。与此类似,DStats 构模元素中的另一个数据项 Shortage Cost 的 SIMAN 表达式为

(原书 p239 第二个公式) 这是用来计算缺货费用的。我们想要的是这些值的时间平均,可通过下面的方式得到。

原书 p239 图 5-32 DStats 构模元素

原书 p240 图 5-33 Output 构模元素 图 5-33 给出了 Output 构模元素, 其作用与 Statistics 模块中的 Output 部分的作用相同, 这里要做两件事。第一(在图 5-33 中已显示出) ,求取并输出每天的平均订货费用,用 Total Ordering Cost 除以 Days to Run,然后将其保存在名为 Avg Ordering Cost 的输出项中。第二, 把全部三个输出项加起来,即求出平均总成本(Avg Total Cost) ,表达式如下 OVALUE ( Avg Ordering Cost ) + DAVG (Holding Cost ) + DAVG (Shortage Cost ) Arena 中的公式 OVALUE 返回其变元的最后一个(也即最新一个)值,这里是指在这个模 块的前一行数据项中求出来的平均订货成本, 前面的句子定义的东西 (我们也可以不这样做, 而是直接使用 Total Ordering Cost/Days to Run 来代替,但这样做的好处是能单独得出平均 订货成本这个输出量,而这个量通常也是我们所感兴趣的) 。Arena 的公式 DAVG 返回时间 持续型变量的平均值, 所以在这里使用了两次以求取平均每天的储存费用和缺货费用 (这两 项同时也分别在报告中单独出现) 。 现在来看一下 Blocks 面板中的逻辑模块,也被称为操作块(blocks) 。图 5-28 最上面的 一组操作块表示顾客到达,产生需求和离开。 图 5-34 中给出了“创建” (Create)操作块的输入界面,该模块需要输入三个非默认数 据项。在 First Creation 和 Interval 两栏中输入 Interdemand Time,该变量在 Expressions 构模 元素中被定义为 EXPO(0.1)。Entity Type(实体类型)定义为 Customer。

原书 p241

图 5-34 顾客到达的 Create 操作块 图 5-35 中给出的“赋值” (Assign)操作块,是用来从当前库存量(Inventory Level)中 扣除掉顾客需求量的。其中 Demand Size 已在 Expressions 模块中被定义为一个离散随机变 量,其以适当的概率取 1,2,3 或 4 作为需求量。

原书 p241 图 5-35 定义顾客需求的 Assign 操作块 然后,Customer 实体经由“清除” (Dispose)操作块离开系统。在 Dispose 操作块中唯 一要做的就是把 Record Entity Statistics 复选框清空 (在这个模型里不考虑实体的统计信息) 。 图 5-28 中间的一组操作块表示了定期的库存检查和订货决策。如果有订货,就等待货 物到来并增加库存水平;如果没有订货,那就什么也不做。 这个逻辑过程从 Create 操作块开始(见图 5-36) ,在模型中插入一个计数器用于统计仓 库中装饰品的数量,以决定是否下订单。如果下了订单则等待交货,然后把这些装饰品放入 货架。最好把创建第一个实体的时间设为 0 ,因为系统需要在运行开始时检查库存情况。 实体类型是 Inventory Evaluator 库存检查员) 创建相邻实体的时间间隔由表达式 Evaluation ( , Interval 来确定,它在 Expressions 构模元素里被定义为常数 1。

原书 p242 图 5-36 生成“库存检查员”实体的 Create 操作块 库存检查员一旦被创建,就进入“分支” (Branch)操作块(见图 5-37) ,Branch 操作 块和读者已经熟悉的 Basic Process 面板中的 Decide 模块具有某些相同的功能。在这里,需 要决定是否在此时进行订货。首先,以 Inventory Level < Litter s 作为条件添加 If 型分支,若 条件为“真” ,则表示此时需要进行订货(这个分支的对话框见图 5-37) ;另一个 Else 分支 表示现在不需订货,是唯一的其他可能。Branch 操作块的离开点对应相应的分支条件。在 这里, 如果进行订货就选择第一个离开点 (前往位于 Branch 操作块右上部的 Assign 操作块) , 第二个离开点对应 Else 分支,意味着什么也不做(所以实体直接进入位于 Branch 操作块右

下部的 Dispose 操作块) 。Branch 操作块中的一个重要部分是定义最大分支数(Max Number of Branches) ,其值默认为无穷大(这里设定为 1) 。一般来说,Branch 操作块按各分支的排 列顺序检查各分支条件是否满足,把进来的实体(或其副本)从每一个条件为“真”的分支 送出去,直到检查完所有的分支。这是一个很强大的功能,但是如果操作块中的各数据项处 理不当的话很可能导致错误。

原书 p243 图 5-37 Branch 操作块 如果要进行订货,则库存检查员实体进入后面的 Assign 操作块(见图 5-38) ,首先为属 性 Order Quantity(订货数量)赋值为 Big S - Inventory Level。操作块中的下一个赋值是计算 这次订货的订货费用,把变量 Total Ordering Cost 赋值为下面的表达式

Total Ordering Cost + Setup Cost + Incremental Cost * Ordering Quantity 注意以上赋值顺序很重要,因为在第二个赋值中要使用第一个的结果。

原书 p244 图 5-38 进行订货的 Assign 操作块 现在等待订货到达, 这需要通过把库存检查员实体送到图 5-39 中所示的 “延时” (Delay) 操作块来实现,他在这里停留 Delivery Lag 个时间单位(记住,在操作块中只有一种基准时 间单位) 。Delivery Lag 在 Expressions 构模元素中被定义为 UNIF(0.5,1.0) 。 在经过了交货延迟时间后,库存检查员实体进入后面的 Assign 操作块(见图 5-40) ,在 这里为变量 Inventory Level 增加 Order Quantity 数量。

原书 p244

图 5-39 描述交货延迟的 Delay 操作块

原书 p245 图 5-40 描述订货到达的 Assign 操作块 在订货交付后,库存检查员实体的工作就完成了,进入最后的 Dispose 操作块。 现在为模型添加一点动画。图 5-41 所示的对话框给出了绘制变量 Inventory Level 随时 间变化的散点图的过程。我们分别绘制两条曲线,红色曲线表示库存水平为负值,黑色曲线 表示库存水平为正值。为了表示正的库存水平, MX(Inventory Level,0)对应的曲线绘制 为黑色; 对于负的库存水平, 将表达式 MN (Inventory Level, 对应的曲线绘制为红色 0) (MN 是 Arena 的内置函数,用来计算并返回参量的最小值) 。当在任何一个图中取 0 的时候,将 会在 0 处得到一条水平线。 用某种方式观察库存本身的变化也是很有趣的。 为此, 我们在散点图的左边放置了一对 水平(Level)动画元素(有时也叫作温度计式动画) 。上面的动画图形(图 5-42 中的黑色 图形)描绘了库存中装饰品的实际数量,用表达式 MX(Inventory Level,0)表示,随着库 存增加而上升。下面的动画图形(红色的那一个,这里就不再麻烦地画出来了)描述了未交 付订货的装饰品数量,即 MX(-Inventory Level,0) 。当存在未交付订货的时候其值为正, 但我们更想把它画在 0 水平线的下面,所以选择填充方向(Fill Direction)为向下(Down) 。

原书 p246 图 5-41 散点图对话框

原书 p246 图 5-42 水平动画元素对话框 再添加一些标识后就可以运行了。 观察散点图和水平动画图可以发现, 当有需求时库存

水平会下降, 当订货到达时库存水平会上升。 每天的平均储存费用为 9.37, 缺货费用为 17.03, 订货费用为 100.39,总费用为 126.79。 , S)=(20,40)是不是最好的决策呢?这是一个 (s 很好的问题,在第六章最后的习题 6-10 和 6-11 中将会要求读者来解决。

5.11 小节
这一章对详细的底层建模能力和相应的调试及动画等问题进行了较深入的探讨。我们 介绍了一些有关 SIMAN 仿真语言的使用内容, 当然很不全面, 读者可以参考 Pegden, Shannon and Sadowski(1995)对 SIMAN 的完整介绍。到现在为止,读者应该已经掌握一个较为强 大的建模工具库,可通过选择各种层次的建模构件来处理多种不同系统。在下面的几章中, 我们将继续介绍 Arena 的其它建模能力。

5.12 习题
5-1 按模型 3-1 的形式建立在第二章中描述的模型, 但是这次只使用 Advanced Process 面板

中的模块来取代操作模块。使用动画工具栏中的散点图和动画变量来完善模型。运行 20 分 钟并和前面得到的结果进行比较。 5-2 零件以均值为 20 分钟的指数分布间隔时间到达一个两机器系统。到达后,零件先被送

到机器 1 加工,加工时间分布为 TRIA(4.5,9.3,11)分钟。然后零件以分布 TRIA(16.4, 19.1,21.8)分钟在机器 2 上加工。在机器 2 上加工完的零件再被送到机器 1 上第二次加工 (加工时间不变) 。然后零件离开系统。单次运行仿真 20000 分钟,观察平均队长和平均系 统逗留时间。 5-3 文件到达间隔时间为 EXPO(10),被送去进行剪切,所有时间单位为分钟。有两个剪切

器,一个主要的和一个备用的。所有到达的文件被送到主要剪切器那里。如果主要剪切器前 面的队列长度小于 5,则文件进入队列等待剪切,操作时间为 TRIA(9,12,15) 。如果主 要剪切器前面的队长已经是 5,则文件被送到备用剪切器(队列容量为无限大)处理,操作 时间为 TRIA(17,19,21) 。当主要剪切器处理完 25 份文件后,必须关闭进行清理,时间 为 EXPO (30) 在这段时间内, 。 主要剪切器队列中的文件将等待。 制作动画, 运行模型 5000 分钟。统计系统逗留时间、资源利用率、队长和排队时间。尽可能使用 Advanced Process 面 板中的模块。 5-4 卡车以间隔时间 EXPO(9)到达有三个码头的卸货区。码头 1、码头 2 和码头 3 的卸

货时间分别是 TRIA(25,28,30) 、TRIA(23,26,28)和 TRIA(22,25,27) 。如果有 一个码头空着,卡车立即到那个码头去。假设卡车到所有码头的行进时间为 0。如果有两个 以上的码头空闲,卡车选择码头的顺序是(3,2,1) 。如果所有码头都忙,则选择队长最小 的码头。 如果有两个以上码头的队长一样, 选择码头的顺序是 (1, 3) 用 Advanced Process 2, 。 面板中的模块建立仿真模型, 使用 Basic Process 面板中所需的模块完善选择逻辑。 运行模型 20000 分钟,统计码头利用率、队长、排队时间和系统逗留时间。 5-5 吊扇套件以 TRIA(2,5,10)时间间隔到达装配系统(所有时间单位为分钟) 。有四

个装配操作员,套件被自动送到第一个空闲的操作员处装配。套件装配时间和操作员有关, 如下表所示。 操作员 1 2 3 4 装配时间 TRIA(15,18,20) TRIA(16,19,22) TRIA(16,20,24) TRIA(17,20,23)

装配完成后,经检验发现大约有 7% 有缺陷。有缺陷的吊扇被送回装配它的操作员处修 理。 这些有缺陷的吊扇比新到的吊扇有更高的加工优级先。 因为这些吊扇要先分拆然后重新 装配,所以修理时间比一般装配时间多 30%。运行模型 20000 分钟,统计操作员利用率和 系统逗留时间。 5-6 习题 5-5 中的吊扇装配质量控制人员决定,如果一个吊扇两次没有通过检验就要被送

到另一个地方返工。对模型进行必要的修改然后运行 20000 分钟,比较两次仿真的结果(每 个模型只运行 1 次) 。同时跟踪返工的吊扇数。 5-7 建立一个有三个工作站的串行生产线模型,生产线的检验拒绝率很高:每个工作站均

为 7%。被第一个工作站拒绝的零件被送到废料库;被第二个工作站拒绝的零件回到组装它 的第一个工作站重新加工,重新加工的时间与原来的加工时间同分布,但增加 50%(这个 惩罚因子 1.5 只用于第一个工作站,返回第二个工作站时不需惩罚) 。被第三个工作站拒绝 的零件回到组装它的第二个工作站返工,在那里给予 50%的加工时间惩罚(返回第三个工 作站时不需惩罚) 。工作站 1、工作站 2、工作站 3 的加工时间分别是 TRIA(6,9,12) 、 TRIA(5,8.5,13) 、TRIA(6.5,8.9,12.5) (所有时间单位为分钟) 。零件到达系统的间 隔时间为 UNIF(6,14) 。运行模型 20000 分钟,统计每个工作站的队长、废弃零件数、工 作站利用率、 没有被拒绝过的零件的平均系统逗留时间和最大系统逗留时间、 至少被拒绝过 一次的零件的平均系统逗留时间和最大系统逗留时间。 此外, 统计被拒绝过的零件的拒绝次

数。 5-8 为了减少习题 5-7 中零件的系统逗留时间,可考虑一个新的优先级策略。队列中的优

先级是基于一个零件被拒绝的总次数, 不管是在哪里被拒绝, 一个零件被拒绝的次数越多它 在队列中的位置越靠后。 采用这个新的优先级策略后, 系统逗留时间有什么不同吗? (提示: 使用队列数据模块,利用拒绝次数确定队列中实体的排列位置。 ) 5-9 零件以间隔时间 EXPO(25)到达一个机加工车间(所有时间单位为分钟) 。车间有两

台机器,到达的零件用掷硬币的方法决定分到哪台机器。除了加工时间,两台机器的工作方 式相同。当零件到达一台机器的区域后,操作员就把零件装在机器上(车间里只有一个操作 员) 。当加工完成后,操作员再把零件移走,然后零件离开系统(零件只需在一个机器上加 工) 。同一个操作员要完成所有的安装和移走零件的工作,等待操作员时间最长的机器优先 操作。所需时间如下(采用三角分布形式) :

机器号 1 2

安装时间 8,11,16 6,8,14

加工时间 20,23,26 11,15,20

移走时间 7,9,12 4,6,8

运行 25000 分钟,统计机器利用率、操作员利用率、按使用机器划分的零件系统逗留时 间、总体系统逗留时间(不按机器划分)和每台机器等待操作员的时间(包括安装和移走) 。 使用存储器(storage)动画元素为安装、加工和移走过程建立动画。 5-10 一个小仓库为一个制造企业提供在制品储存服务。该企业生产四种不同零件,零件类

型百分比和每个零件的库存费用为: 零件类型 1 2 3 4 百分比 20 30 40 50 单位零件存储费用 $5.50 $6.50 $8.00 $10.50

存储费用计算如下,例如,若目前的库存包括 3 个零件 1,没有零件 2,5 个零件 3 和 1 个零件 4,则当前的库存费用为 3  $5.50 + 0  $6.50 + 5  $8.00 + 1  $10.50 = $67.00 当零件到达和离开时,如下所述,存储成本将会上升和下降。 零件以时间间隔 TRIA(1.5,2.0,2.8)到达(所有时间单位是分钟) 。由两台起重机存 入和取出零件, 其存取移动时间为 UNIF(1.2, 2.9)。 对零件的需求模式与零件到达模式相同。

如果发出需求时仓库中没有所需要的零件, 则作为未实现的需求加以统计。 所有等待出库的 零件都有优先级,优先级根据零件存储费用而定,费用高的优先。 对于零件的到达,在零件到达时增加存储费用,在零件入库后增加库存数量。对于零 件出库,当有零件需求时即刻减少总的库存零件数,在零件取出后再减少存储费用。 开始时仓库中每种零件各有 4 个,运行模型 5000 分钟。统计起重机利用率、平均存储 费用、仓库中每种零件的平均存储量、以及因为缺货而未能实现的需求数。 提示:使用下标变量表示零件的库存量和单位零件存储费用。 (注意,为下标变量赋值 时,需要在 Assign 模块中使用 Other 选项。 )使用离散分布决定零件类型,使用 Statistics 数 据模块收集所需的统计量。 5-11 一个中型机场有少数的国际航班到达,需要办理入境和海关手续。机场想要研究应该

对多少乘客进行包裹检查,以及需要多少海关人员。到达的乘客必须先办理入境手续(入境 手续不在这个模型的范围之内) 。然后他们认领包裹,前往海关检查处。到达海关的间隔时 间分布为 EXPO(0.2),所有时间单位为分钟。现在的方案是安排两个海关检查员处理那些不 用检查包裹的乘客,服务时间分布是 EXPO(0.55)。一个新的机场系统分析员建立了一种概 率方法,决定哪些顾客将需要检查包裹。这个决定在顾客将要进入海关正常队列时做出,决 定过程如下:利用均值为 7 的泊松分布生成一个随机数,为了避免得到 0,将这个数加 1, 并开始计数。 当计数器达到所生成的那个数时, 这个不幸的乘客将被送进第二个队列检查他 /她的包裹。然后再生成一个新的检查数字,重新开始以上过程。单独有一个检查员处理这 些乘客,服务时间分布是 EXPO(3)。坐这些大型飞机到达的乘客人数服从 240-350 的均匀分 布,仿真运行到所有乘客的手续办理完毕为止。建立以上系统模型并重复仿真运行 20 次, 统计不同类型顾客的系统逗留时间(被检查和不被检查)和顾客数,以及检查员利用率。 5-12 一个国家驾驶执照考试中心想要分析它的运作过程以找出可能的改进。 到达的顾客进

入大楼拿到一个号码,这个号码决定他们在笔试队列中的位置,笔试是自助式的,可从 5 个电子考试台中选择一个来完成。考试时间分布为 EXPO(8),时间单位为分钟。百分之十三 的顾客不能通过考试(考试有很多问题,难度大) 。这些未通过者会得到一本关于驾驶规则 的小册子进一步学习,然后离开了系统(步行) 。通过考试的顾客将选择两个摄影室中的一 个去照相并领取新执照。照相时间分布是 TRIA(2.5,3.6,4.3) 。摄影室有各自的队列,顾 客进入长度最小的队列排队,不管是否有人正在接受服务。如果两边队长一样,则选择最近 的摄影室,即摄影室 1。注意,这些规则可能会导致在两个摄影室都没人排队时(也就是两 个队长都是 0) ,出现不合理的顾客行为。当摄影室 1 忙、而摄影室 2 空闲时,一个来到照

相区的顾客可能选择去摄影室 1 排队 (根据相同队长的处理规则) 而不是在摄影室 2 立即得 到服务  不过,这是因为他们看不见摄影室里面的情况!然后,这些顾客骄傲地拿着新执 照离开系统。 中心一天营业 8 小时来处理所到达的顾客, 但会继续延长一小时服务来处理剩 下的顾客。顾客在一天中的每个小时到达模式是不一样的,具体如下: 小时 1 2 3 4 每小时到达数 22 35 40 31 小时 5 6 7 8 每小时到达数 35 43 29 22

仿真运行十天,统计平均每天考试未通过的人数、电子考试台与摄影室的利用率(全部电子 考试台的整体利用率和每个摄影室各自的利用率) 和平均队长、 以及通过笔试的顾客的平均 系统逗留时间。为所有电子考试台和摄影室添加动画。 5-13 国家执照管理局的一个办公室有两种到达。想购买新图版的人到达间隔时间分布为

EXPO(6.8),服务时间是 TRIA(8.7,13.7,15.2) ,所有时间单位为分钟。想要更新驾驶执 照或申请新执照的人的到达间隔时间分布是 EXPO(8.7), 服务时间是 TRIA (16.7, 20.5, 29.2) 。 办公室有两条队列,每种顾客一条。办公室有五个办事员:两个人负责图版业务(Mary 和 Kathy) ,两个人负责执照业务(Sue 和 Jean) ,一个组长(Neil)可以为两种类型的顾客服务。 Neil 将会为等待时间最长的顾客服务。假设五个办事员一天八小时都工作。注意,当位于多 个“先进先出” (FIFO)队列(对应于多个 Process 模块)最前面的实体试图占用同一资源 时, 选择哪个实体 “赢得” 资源的逻辑与把所有的队列合并成为单一 FIFO 队列的情况相同。 观察两种顾客的系统逗留时间。 5-14 习题 5-13 描述的办公室准备对 Kathy 进行多种能力培训,这样她就能够为两种顾客

提供服务了。按这种考虑修改模型,看这样对系统逗留时间有什么影响。 5-15 改变习题 5-14 的模型,使每个办事员有 30 分钟的午餐时间。第一个人的午餐时间在

第 180 分钟时开始,其后一个接一个,持续 150 分钟。午餐的顺序是:Mary,Sue,Neil, Kathy 和 Jean。这会对顾客的系统逗留时间造成什么影响? 5-16 修改习题 3-10 中的概率板(probability-board)模型,使得只要改变单个变量的值就

可以立即改变所有木桩的右弹概率。运行模型,设置右弹概率为 0.25,和习题 3-10 模型中 的吹风情况进行比较。 5-17 不使用 Blocks 面板或 Elements 面板中的模块,只使用 Basic Process 面板和 Advanced

Process 面板中的模块,重建模型 5-3(库存模型) 。 5-18 模型 5-3 中,在确定库存检查间隔和交货延迟时间时,我们使得在任何时间段内都不

可能出现一个以上订货。如果改变这些数据,使得在给定时间段内可以有多次订货,那将会 怎么样呢?模型 5-3 仍有效吗?(注意,在模型 5-3 中我们利用库存检查员实体的某一属性 表示订货数量;如果订货数量用一个变量来表示会怎么样呢?) 5-19 在模型 5-3 中,不使用“偷懒的”仿真终止时间 119.9999,而是就按准确的 120 分钟

运行仿真,但要补充逻辑过程用以防止在时间 120 发生没用的库存检查。 对输出结果有什 么影响? 5-20 拓展模型 5-3,使得仓库中除装饰品外还储存小摆设和小机具。顾客的到达方式和以

前一样,但是现在每个顾客对装饰品、小摆设和小机具都有需求。对装饰品的需求和以前一 样,对小摆设的需求服从 POIS(1.9) ,对小机具的需求为 POIS(2.3) 。假设一个顾客对一 种产品的需求与他对其它两种产品的需求是独立的。 仍然有一个库存检查员在每天一开始的 时候到达,但是现在必须检查三种产品的库存并按各自的(s,S)订货策略订货。对于装饰 品, (s,S) = (20,40),和以前一样;对于小摆设, (s,S) = (15,35),对于小机具,(s, S) = (25, 45)。 装饰品的交货延迟不变, 仍为 UNIF(0.5, 1.0), 小摆设的交货延迟是 UNIF(0.4, 0.8),小机具的是 UNIF(0.8,1.7)。小摆设和小机具的订货费用(包括固定的和可变的) 、储 存费用和缺货费用与装饰品相同。运行仿真,运行时间和模型 5-3 一样(即可以修改终止时 间以避免在时刻 120 处出现无用的库存检查) 。求取每天的总成本,以及每种产品各自的储 存和缺货成本。 5-21 在习题 5-20 中,假设三种产品的供应商合并,并同意消除在同一天订货中的多重固

定费用,也即,不管 Bucky 在一天中订了什么产品,他只需要交一共 32 美元的固定费用, 而不是每种不同产品各交 32 美元。 (如果没有订货,也就不需交固定费用) 。根据本题的情 况修改习题 5-20 的模型。 从选取更好的 s 和 S 值的角度出发, 你认为这种费用结构对 Bucky 有什么激励(见习题 6-13 和 6-14)?

第 6 章 终态仿真输出分析
在本书 2.6 节中曾提醒读者,当建立仿真模型时,随机数据(即分布或概率驱动的)输 入会带来输出的随机性及相关统计分析问题, 这是迄今为止本书中建立的所有模型都面临的 问题。本章中,将以第 5 章中所建立的汽车维修店仿真模型 5-2 为例,教读者如何在仿真中 采集适当的数据,如何从已得到的输出报告对这些数据进行统计分析。同时,本章还介绍如 何使用输出分析器(Output Analyzer)做更为深入复杂的统计分析(对仿真模型中两个不同 方案进行比较) ,如何使用过程分析器(Process Analyzer) (通过运行多种可行的备选方案, 从中选择出最佳方案,或是衡量输入数据对输出数据的影响作用) ,以及如何使用 Arena 中 的 OptQuest for Arena 工具  与 Arena 配套的仿真优化软件(它将控制仿真模型的运行, 从而寻找输入控制参量的最佳配置)。 在第 6.1 节中,将讨论仿真运行的时间类型,它对输出统计分析有很大影响。在 6.2 和 6.3 节中将以模型 5-2 为例,介绍单变量数据收集并对其进行统计分析的基本技巧。6.4 节中 将对该模型的输入参数进行简单的改动并利用 Arena 中的输出分析器来验证仿真结果是否 发生改变。6.5 节将引入更多的模型变化,使用过程分析器以一种更高效有序的方式运行它 们,从而找出那些效果可能最好的参数,并且分析输入数据对输出结果的影响作用。最后, 6.6 节中将应用 OptQuest for Arena 工具在大量可能的模型输入参数组合中, 快捷高效地搜寻 至少在某种意义下是最优的模型结构。 总之, 本章将阐明获得精确可靠结果的统计分析方法, 这些数据将帮助决策者做出正确且富有远见的决策。 过去许多人几乎忽略了上述的问题, 所幸那令人羞愧的事现在已经没有了。 如果仅仅运 行一次仿真模型,之后就试验几个随机抽出的方案(并且只运行一次),那么这样的结果或 结论的有效性、精确性或者一般性显然是无法保证的。有时候结论的有效性、精确性以及一 般性是不正确的,因此有可能做出不适当的估计及错误的决策。读者将会发现,要做好这些 事情其实不费太多的力气, 只是你的计算机可能会忙碌一些, 但无论如何计算机在大部分的 工作时间里还是闲置的, 并且机器运行是廉价的 (相对于读者将要根据仿真结果所做出的决 策而言)。读者已经辛苦地建好了仿真模型,现在该是让模型(及计算机)运行并检验其性 能的时候了,这样你才能有充分的把握将这些结论应用到决策中去。

1

6.1 仿真类型
多数仿真都可以被归类为终态仿真或稳态仿真。 对大多数模型来说, 这主要取决于研究 目的,与模型的内部逻辑或是结构没有太大关系。 终态仿真就是在仿真模型中明确地规定了仿真开始和结束的条件, 这些条件是目标系统 实际运行模式的反映。 正如其名称所显示的, 仿真运行将在模型中某个定义好的规则或是条 件下终止。譬如,一家商店在早晨 9 点开门营业,正常情况下晚上 9 点关门结束营业,但是 当还有顾客排队时,商店会适当延长营业时间直到所有顾客都离去。另一个例子,某流水线 车间根据订单需要生产 500 件产品, 那么系统就一直运行到所有 500 件产品都装配完成为止。 在终态仿真的时间结构中, 最关键的一点是有一个明确定义的起始点以及一个明确定义的自 然的终止点(尽管可能在仿真开始时并不知道这个终止时间是多少)。 与终态仿真不同, 稳态仿真中对于数量的估计是建立在长期运行的基础上的, 理论上运 行时间是趋于无穷的。在理论上(尽管在实际中常常不是这样)仿真的初始条件是不影响仿 真结果的。当然,稳态仿真也会在某一时刻终止,读者可以猜想到那是相当长的一个运行过 程;读者还需要做另外一些工作来确保仿真运行时间已足够长,这将是本书在 7.2 节中讨论 的问题。以急诊室为例,它将永远不会真正停止工作或是重新开始,故而采用稳态仿真将是 非常恰当且合乎实际的。 有时人们在做一个系统的稳态仿真时也会让它在一定的时候终止下 来,这样做的目的是为了设计某些最坏的情形或是峰值负荷的情形。 本章中,将以第五章中的汽车维修店仿真模型 5-2 为例,对其进行终态仿真统计分析, 该系统将在第五章中描述的情形下开始运行, 并在 20 个工作日 (每个仿真工作日为 12 小时) 后终止仿真运行,仿真时间大约一个月。 (本模型同样适用于稳态仿真,让运行时间大大超 过 20 个工作日即可, 但除了仿真长度外没有别的变化; 这里选择运行 20 个工作日只是将其 作为终态仿真来研究而已。 )稳态仿真的统计分析与终态仿真是不同的(本书将在第 7.2 节 中以 7.1 节建立的模型为例进行说明) 。

6.2 数据收集及分析策略
对于终态仿真,要为统计分析收集恰当的数据从概念上讲是非常简单的  做 n 次独 立的重复运行即可。1

1

虽然概念上很简单,但也说明了对于大型的或是有很多变量的仿真模型来说,需要大量的运行时间。 2

为完成这一工作,打开 Run > Setup > Replication Parameters 对话框,在 Number of Replication 选项中键入读者希望的重复仿真次数 n。 值得注意的是, 要确保 Initialize Between Replications 栏中的两个复选框都是被选中的(缺省值),这样才能保证系统状态变量以及 统计累加器在每次仿真结束后都被清零,也即各次重复仿真所使用的是独立同分布(IID) 的数据。这些设置将能够保证仿真重复运行 n 次,每次运行都从初始状态开始运行(初始的 系统状态及清空的统计累加器)并且应用了独立随机数来驱动仿真2。对每次重复仿真而言, 都独立产生该次仿真的输出报告,可通过 Category by Replication 报告查看。 表 6-1 模型 5-2 重复仿真 10 次所得的每天平均利润(Daily Profit)与未能按时完成服 务的等待顾客数(Daily Late Wait Jobs) 重复次数 1 2 3 4 5 6 7 8 9 10 Daily Profit(美元) 475.43 525.17 513.98 389.42 513.96 401.20 450.52 388.71 574.67 565.81 Daily Late Wait Jobs 0.6500 0.6500 6.5500 0.6000 0.7000 1.0500 0.6500 0.9000 0.4000 0.2500

举例来说, 我们对模型 5-2 进行 n=10 次独立重复仿真试验,可得到如表 6-1 所示的 Daily Profit 与 Daily Late Wait Jobs 的性能指标。一定要记住表中的任何一个值都是基于一次完整 仿真运行过程的结果,并且它们都只是在某一次具有特定开始和终止条件的随机重复仿真 中, 代表 Daily Profit 与 Daily Late Wait Jobs 的随机变量的一个 “观测值” (或者 “实现值” 。 ) 我们能提前得知 n=10 是恰当的重复仿真次数吗?答案是否定的。而且如果我们不对这 些数据进行分析, 那么就仍然不能知道重复仿真多少次是恰当的, 这是因为我们无法预先知 道仿真结束后在输出报告中的输出变量变化范围是多少。下面将说明如何找到(或是猜测) 一个合理的样本量。 顺便说一下, 为了统计分析而进行重复运行时, 读者也许希望关掉动画, 可以通过如下操作完成:选择 Run > Run Control 并选择 Batch Run (No Animation),从而消 除动画。若想以后再恢复动画,只需再回去清除上述的选择即可。
2

实际上,每次重复仿真都是由同一随机数流推进的,在 12 章中将介绍随机数发生器如何工作以及如何控 制它。 3

相信读者不希望将每次重复仿真的所有性能指标的观测值都先复制出来,再应用统计 软件包、或是电子数据表格、或是计算器来进行分析。值得庆幸的是,Arena 内部自动跟踪 了输出报告中每一次重复仿真的记录。如果读者进行了多于一次的重复仿真,在 Arena 的分 类汇总报告(Category Overview report)中将会给出各次重复仿真的输出结果的均值,并给 出输出结果的置信度为 95%的置信区间;这些内容将在第 6.3 节介绍。 读者可以将每次重复仿真结果中感兴趣的部分保存到扩展名为 “.dat” 的二进制文件 中(以后可以导入到 Arena 输出分析器中,6.4 节中将谈到这一应用)。可在 Statistic 数据 模块中定义输出文件的名字,这个文件就将记录表 6-1 中的数据。

6.3 终态仿真系统的置信区间
正如在 2.6.2 节中的手工仿真那样(应用那里给出的公式),可以总结一下表 6-1 中重 复仿真 10 次所得到的输出数据。在表 6-2 中给出了样本均值、样本标准差、95%置信区间 半长、以及各次重复仿真输出结果的最小值和最大值。 表 6-2 模型 5-2 的 10 次重复仿真输出结果统计分析 Daily Profit(美元) 样本均值 样本标准差 95%置信区间半长 最小值 最大值 479.89 70.17 50.20 388.71 574.67 Daily Late Wait Jobs 0.6400 0.0510 0.1616 0.2500 1.0500

如果读者在 Run > Setup > Replication Parameters 中选择多于一次重复仿真的话,在 Arena 的分类汇总报告中会自动记录表 6-2 中的信息(样本标准差除外,但是在半长中已经 包含了本质上相同的信息)。图 6-1 显示了模型 5-2 重复仿真 10 次后的分类汇总报告中的 相关内容;除了微小的舍入误差外,这些数据与表 6-1 中手算的数值是吻合的。

原书 P260 图 6-1 模型 5-2 重复仿真 10 次的结果 需要提醒读者的是, 当进行多次重复仿真后, 关于分类汇总报告有几点需要注意。 第一,

4

当进行不多于 100 次的重复仿真时,在“半长”(Half Width)栏显示的置信区间的半长值 是精确的;否则这些项将比实际数据大,导致这样的结果是由于生成这项报告的 Crystal Report 软件所存在的一些局限。但是,在扩展名为“.out”的文件中的半长值是准确的,其 它一些 Arena 内部处理过程以及一些应用分析工具(如输出分析器、过程分析器、与 Arena 配套的仿真优化软件)的数据都是准确的。第二,对某些在单次仿真中取整数值的仿真输出 数据(例如对某种物体的计数) ,虽然其在多次仿真下的平均值未必是整数,但在报告中却 会对它们舍入取整;但这样的问题也只出现在分类汇总报告中,而在“.out”文件或是其它 内部处理及应用分析中都不会出现。 这些问题可通过下载一个补丁得以解决; ( 详见附录 E。 ) 如果读者想要改变一些条件或是报告内容,比如定义非 0.95 的置信度,或是以某种组 合形式输出结果,或者绘制置信区间、最小值、最大值的曲线图,就需要将数据保存在某一 “.dat”文件中,并应用输出分析器来完成这样的工作(详见 6.4 节)。读者也可以使用过 程分析器来得到置信区间的曲线图。 显而易见, 如果想要减少 Daily Profit 与 Daily Late Wait Jobs 的期望值的置信区间半长, 就要增加样本数量 n。但是到底增加多少才合适呢?如果读者在心中已有一个希望半长大小 的预期值, 就可以很容易地算出大概多大的 n 可以达到这个目标 (尽管这可能不是一个准确 值)。假定读者根据初始的几次重复仿真得到了样本均值及标准差,以及一个半长相当大的 置信区间。例如,从我们初始的 10 次重复仿真中得到的 Daily Profit,可得出样本均值是 479.89,样本标准差是 70.17,以及 0.95 置信度的置信区间的半长是 t n 1,1 / 2 s n  2.262 $70.17 10  $50.20

它表示点估计值$479.89 有一个 10.5%的误差范围。 如果读者想要得到一个特定的半长 h 当 ( 然比初始重复仿真得到的半长要小一些) 就可以应用上面的半长公式来求得相应的 n 的值: ,
2 n  t n 1,1 / 2

s2 h2

这里存在的困难是,公式右端项也依赖于 n 的取值(t 分布的自由度与 n 有关,样本标 准差 s 也与 n 有关, 并且 s 不但依赖于 n 的值, 而且依赖于 n 次重复仿真所得到的数据集) 。 然而,为了得到样本量的一个粗略估计值,读者可以将公式中的 t 分布用标准正态分布来替 代(二者在 n 大于 30 的条件下是接近的),并且假定当前估计的标准差 s 与计算大样本时 的值是相同的。这样就得到如下所示的近似求取一定置信度下特定半长 h 所要求的样本量 n 的公式:

5

2 n  z1 / 2

s2 h2

上式中,s 是根据初始重复仿真所得到初始数据计算出的标准差(这一数值需要提前计 算出来)。另外一个更简单但是稍微不同的近似公式是(将代数证明留给读者来完成) n  n0
2 h0

h2

上式中,n0 表示初始重复仿真次数,h0 表示初始数据求得的半长。在上面 Daily Profit 值的 例子中,若想把 h0 = $50.20 减少到 h = $20.00,则所需要的重复仿真次数为: n  1.96 2 70.17 2 20 2  47.3 (按第一个公式的近似)

或 n  10 50.20 2 20 2  63.0 (按第二个公式的近似)

第二个公式算出的近似值一般比较大,原因是公式中使用了 t n0 1,1 / 2 而不是 z1 / 2 。要注意 的是, 样本量是以半长减小倍数的平方增长的  即若要减小半长到初始值的一半, 就需要 原来 4 倍的样本量。这看起来可能是不经济的(得到两倍的效果却需要做四倍的工作),并 且读者会感到重复运行的次数越多,每一次运行带来的新信息也越少。 因为模型在无动画时运行得非常快,所以保守的决策(从统计意义上)是做 100 次重复 仿真。模型 5-2 所需要的修改仅是在 Run > Setup > Replications Parameters 中,将重复次数 由 10 改为 100, 并且在 Run > Run Control 中选择 Batch Run (No Animation)使仿真快速运行。 将这一改动后的模型命名为模型 6-1。这轮仿真结束后得到的 95%置信区间为: 492.63  13.81 或是表示为[478.82,506.44](此处省略了$符号)。这样就达到了我们想要将半长减小到 20 或更小的目标。 理解什么是置信区间是非常重要的。同样以 Daily Profit 的输出值为例。每次仿真都得 到一个 Daily Profit 值,但因为随机输入的影响,这些值在不同的重复仿真中是不同的。读 者会同意这 100 个值的均值比任何一次仿真得到的值都更具代表性。 同理, 做的重复仿真次 数越多,得到的均值效果就越好。均值的期望值常常用 µ 表示,可以被认为是经无限多次 仿真运行得出的均值;也即,µ 是不存在什么不确定性的。 但不幸的是, 我们人类不可能等待无限多次重复仿真运行, 所以要用一个有限样本来加 以估计,例如用 100 次重复仿真得出均值估计 492.63。以 492.63 为中心的置信区间可被当 作是一个“随机”区间(下一轮 100 次重复仿真会得出一个不同的区间),此例中,这一区
6

间以 95%的概率包含或是覆盖 µ,也就是说如果做许多轮的 100 次重复仿真运行,并从每一 轮中求出一个区间,大约有 95%的区间都会包含 µ。因此,置信区间将给出 µ 的点估计 (492.63),同时也给出了这一估计的精确度。 置信区间并不意味着 95%的重复仿真得出的 Daily Profit 值会落在这个区间里,那样的 区间被称为预测区间(prediction interval),它同样可以由相同的一批数据得到,并且也是 非常有用。两者之间的主要区别就在于:随着 n 的增加,置信区间会缩至一个单点,而预测 区间不会,因为每次重复仿真的变化都会影响到后者。 关于置信区间,最后需要提及的是有关置信度的定义(“大约”95%等)。Arena 应用 的是标准方法,即假定数据(如经重复仿真得到的 100 个 Daily Profit 观察值)是独立同分 布的(对我们来说这是满足的),且服从正态分布(实际上这是不满足的)。从原理上说, 置信区间公式中的 t 分布要求数据来自正态母体。那么,若违背了正态假设会对实际的置信 区间产生什么样的影响呢?我们可以肯定地说, 这与很多因素有关, 包括数据及它们的真实 分布、以及重复仿真次数 n。只要 n 足够“大”,根据中心极限定理可以确保我们得到满意 的答案(实际的置信度与所定义的非常接近)。但是 n 到底需要多大?答案是不可预估的, 而且取决于数据的实际分布与正态分布的近似程度, 尤其是对称性。 这些可以通过对数据绘 制直方图来检验,在图 6-2 中绘制了 n=1000 次重复仿真(而非初始 100 次)时 Daily Profit 的直方图(只有 100 个数据点的直方图没有很好的说明性)。为绘制这张图,对模型 6-1 做 了如下改动,首先将 Run > Setup > Replications Parameters 中的重复次数由 100 改为 1000, 其次将这 1000 个 Daily Profit 值保存到一个名为 Daily Profit. Dat 的文件中, 这只需在 Statistic 数据模块中的 Output File 栏内输入该文件名即可,这样就得到了模型 6-2。接着运行 Arena 的输出分析器(将在 6.4 节中介绍这一独立的软件)来读取 Daily Profit. dat,并将该文件导 入到一个纯 ASCII 文本文件中(File > Data File > Export),在电子数据表格系统中对该数 据进行重新整理使其成为一列,再将它存为一个纯 ASCII 文本文件,然后把它导入到输入 分析器中(详见 4.5.4 节内容)。

原书 P264 图 6-2 由 1000 个 Daily Profit 值绘出的直方图

采用目测就可以看出,直方图的形状(图中的阴影柱状)与我们熟悉的正态密度函数钟
7

形曲线差距不大(尽管图形有一点向右偏斜,但不很严重),这就预示了使用标准置信区间 的方法是可行的,尽管 n 的数值相对小了一些。对这个模型而言,在一台 2 GHz 的机器上 做 1000 次运行只用了不超过 2 分钟时间。本例中为了检验数据的近似正态性所做的 1000 次重复仿真就像一个轻松的游戏,但如果是大型工业系统的模型,是不可能做这类实验的, 那样应该如何检验呢?尽管不存在一条通用的准则, 但很多仿真经验 (由中心极限定理的各 种广义形式所支持)告诉我们:如果从每次重复仿真中得到的某个值是“和”或“均值”的 形式、而不是极值的话,那么使用标准正态理论的统计推断方法是相当安全的。本例中的 Daily Profit 值是均值,这或许可以解释图 6-2 中的近似正态分布的现象,也可以验证 Arena 中使用基于正态理论的统计方法的正确性。

6.4 比较两个备选方案
在大多数仿真研究中, 人们最终感兴趣的是比较一些一般模型中不同的方案。 不同方案 间的区别,可以小到参数变化,大到完全不同的逻辑结构。在某些例子中,需要应用统计方 法来比较不同方案的输出结果,从而保证做出恰当的结论。本节中,仅限于比较两个方案的 情况,在 6.5 节中将会比较更多方案。 将模型 6-2 做如下改动就得到模型 6-3: Run > Setup > Replications Parameters 中的重 将 复仿真次数减小到原来的 100 次; Statistic 数据模块中, 在 在点击 Output File 列、 Daily Profit 行确定的方框中,把每次重复仿真的 Daily Profit 值保存到 Daily Profit. dat 文件中。我们将 比较两个方案。第一个称之为基准方案,与第五章中的模型 5-2 相同,具有完全相同的输入 参数和运行条件(除了做重复仿真 100 次而不是 10 次)。第二个方案即我们称之为多预约 方案,也就是将基准方案模型中的输入参数 Max Load(在 Variable 数据模块中)的初始值 由 24 小时改为 28 小时。我们的考虑是通过增加预约工作数量,使系统里的资源更加忙碌, 从而增加收入,相应地提高 Daily Profit。当然这只是最好的打算,因为同时也会出现负面 结果,如增加了付给工人的加班费,增加了一天里本应修完而没能完成的车数,并为此需要 支付更多的租车费用  这还不包括失去顾客信任的损失。 故而并不清楚这项改变会对全部 利润的影响,以及具体数量将是多少  这正是仿真可以完成的工作。 通过运行基准方案和多预约方案(一次仿真运行,长度为 20 个工作日,每个工作日 12 小时),得到的 Daily Profit 输出值分别为 475.43 美元和 737.95 美元。表面上看来,后一种 方案更佳,因为收入明显高于为加班和支付租车费所付出的成本。但是如果读者仔细阅读

8

6.3 节(或是第 2.6.3 节)的话,就会明白:只通过一次仿真运行而没有对输出结果做统计分 析就轻易下结论的话, 是很容易做出错误决策的。 下面将运用一种能够使我们得到正确统计 结论的方法来做比较。 在使用正确的方法做比较之前,先用一种貌似合理却不很正确的方法来比较。在第 6.3 节中,注意到经 100 次重复仿真,Daily Profit 的期望值的 95%置信区间是 492.63  13.81,或者 [478.82,506.44] 返回到多预约方案,同样运行 100 次重复仿真得到的置信区间为: 564.53  22.59,或者 [541.94,587.12] 这两个区间根本没有重合的部分, 说明两个方案中 Daily Profit 的期望值是截然不同的。 然而, 比较两个置信区间是否重合并不是进行方案比较的最佳方法; 正确的比较方法要使用 Arena 的输出分析器,下面将予以介绍。 正如我们以前提到的那样,输出分析器(Output Analyzer)是一个独立于 Arena 的应用 程序,它使用由 Arena 经 Statistic 数据模块生成的输出文件(即.dat 文件)。尽管 Arena 可 以完成输出分析器的一些工作(如生成期望输出值的置信区间),但是输出分析器具有更多 的优势,包括对两种方案进行统计比较。 为了将每次重复仿真的 Daily Profit 值保存到.dat 文件中供输出分析器使用,在 Statistic 数据模块中的 Output file 列、Daily Profit 行交叉处的方框中输入 Daily Profit. dat。当仿真结 束时,文件中就会有 100 次重复仿真得到的 100 个 Daily Profit 值;文件的格式是二进制的, 输出分析器只能识别这种类型的文件,而其他类型(如字处理或是电子数据表格)都无法识 别。因为此处需要保存两种方案各自 100 次重复仿真所得到的 Daily Profit 值,需要两个这 样的文件,这就要在运行仿真前更改 Statistic 模块中的名字(如 Daily Profit Base Case. dat 和 Daily Profit More Bookings . dat) 也可以在一个方案运行结束后在操作系统中修改 Daily , Profit.dat 的名字。当对两种方案都做了 100 次重复仿真之后,打开输出分析器(它应该与 Arena 在同一文件夹中,除非读者做了非常规的安装)。 在输出分析器中, 选择 File > New (或者快捷键 Ctrl+N 或按钮
) 来建立一个新的数

据组。这不是一个包含具体数据的.dat 文件,而是包含许多.dat 文件的组群,读者可以选择 感兴趣的文件加入该组群,这样就可以筛去许多现有的、但不需要的.dat 文件,可以使得操 作时更简便。读者可以保存这类组群文件(缺省的文件扩展名为.dgr),当读者打开它时就 同时打开了其中的.dat 文件,而不需要分别打开许多个.dat 文件了。此处将这个数据组保存 为 Output Analysis 06-Ol.dgr。
9

使用数据组窗口的 Add 按钮,可以选择打开 Daily Profit Base Case. dat 和 Daily Profit More Bookings . dat 中的文件,使它们可以进行比较。可以使用输出分析器中的“均值比较” 分析工具(Analyze > Compare Means)进行比较。如输入界面 6-1 所示。

原书 P267 输入界面 6-1 使用输出分析器进行均值比较 首先将这些数据文件加入进去, 然后需要对两个备选方案指定一些参数 (即在对话框中 称之为 A 和 B 的两个方案,在 Replications 栏都选择 Lumped,这就意味着两个方案的 100 次重复运行的输出值都“集总”到一起用于统计分析),接着需要在 Title 后输入这个比较 的名字,并接受或是改变比较的置信度。然后有两个选择按钮  Paired-t Test(缺省选项) 和 Two-Sample-t Test 对应两种检验策略, 它们与随机数分配及统计独立性有关, 这些内容在 12.4.1 节中会加以讨论。Paired-t Test 方法更具一般性,并且当通过精心的随机数分配来提 高仿真精度时(这里没有用到),这一方法更适用。 比较结果如图 6-3 所示。输出分析器对 A、B 两方案的均值按 A-B 进行了相减;因为方 案 A 为基准方案,方案 B 为多预约方案,而更多的预约意味着增加 Daily Profit 值,所以两 个方案 Daily Profit 均值间的差应为负值(492.63-564.53= -71.90)。为了发现均值间是否存 在统计上显著的差异性(即差值是否远离 0 点),输出分析器给出了一个期望差值的 95% 的置信区间。因为本例中置信区间不包括 0,故可以得出结论:二者之间存在统计意义上的 显著差异,即当预约增加时 Daily Profit 会更高。置信区间的确可以更好地说明这一切,因 为它通过检验得出了“拒绝统计假设”的结论(区间里不包括 0),而且还量化出了差值的 大小。读者现在就可以明了,按这种方案增加预约数量将会如何提高 Daily Profit 的值。

原书 P268 图 6-3 Daily Profit 期望差值的置信区间和假设检验

10

6.5 用过程分析器做多方案评价
在 6.4 节中定义了不同输入参数(Max Load)的两个方案系统,然后对这两个方案运行 仿真模型,并且进行了统计分析,从而得到正确的结论,即两方案在 Daily Profit 这项输出 值上存在显著差异。然而,当读者想要运行并比较多于两个方案的情形时,又该怎么做呢? 我们面临以下两个问题: (1) 系统地管理模型中的各种变更。在不同备选方案比较中,如果存在许多方案时, 对模型进行修改和运行管理将是非常枯燥费力的,在设定每一个备选方案的模 型时将涉及到许多参数的变化,而且在运行每一个备选方案模型时,又要改变 所有需要保存的输出文件的名称。 (2) 从统计上有效地评价这些方案,并且挑选出哪些方案与其它方案有显著差异, 哪些方案比其他方案明显更优,甚至挑选出这些方案中的最佳方案。 Arena 中提供了另外一个独立的应用程序  过程分析器(Process Analyzer,或缩写为 PAN),它可以很好地解决用户面临的第一个问题,并且为第二个问题提供强有力的支持, 从而帮助用户以一种统计上可靠的方式评估所得到的仿真结果, 然后做出正确的决策。 PAN 处理的是 Arena 的程序文件,这些文件通常用.p 作为扩展名;当运行完一个仿真模型后,就 会生成相应的.p 文件,或者也可以不运行模型而只通过模型检验来生成这个文件(Run > Check Model 或 F4 键或 按钮)读者可进行如下操作来运行过程分析器, 。 比如通过 Windows

的开始按钮来启动它(标准安装时,它与 Arena 位于在同一个目录下),即运行 Start> Programs > Rockwell Software > Arena 7.0 > Process Analyzer 即可;也可以在 Arena 中通过 Tools > Process Analyzer 菜单选项来启动。无论哪种方式,PAN 都会在一个独立于 Arena 的 窗口中单独运行(如果 Arena 也在运行的话)。 过程分析器中的基本元素是“情景”(scenarios),所谓“情景”包括以下内容的组合: 存在于计算机中某个地方的程序文件(.p)、一个所选择的输入“控制”(controls)变量值 的集合、一个所选择的系统输出“响应”(responses)值的集合,以及该“情景”的描述性 名称。一个 PAN“项目”(project)就是一个由许多“情景”构成的集合,可以将其保存为 一个 PAN 文件(扩展名为.pan)供以后使用。为不同“情景”定义的程序文件(.p)可以是 同一个程序文件,也可以由不同的 Arena 模型(.doe)文件产生。不难看出,读者可以选择 模型中的变量和资源容量作为“控制”变量,可以选择模型输出的内容(由 Arena 生成)或 者读者在 Variables 中自定义的其它变量作为“响应”。一旦用户定义好“情景”,PAN 就
11

会根据用户为每个“情景”定义好的控制变量的集合,带入那些所选定的变量值去运行仿真 (如果愿意的话用户可以选定所有控制变量值),并且对应每一个“情景”的控制变量值给 出相应的输出响应结果, 所有结果被列在一个表中。这些工作也可通过以下操作来完成:用 户将每个“情景”中的不同控制变量值依次代入 Arena 模型并“手动”运行仿真。很显然, 在 PAN 中操作更容易、 更快捷, 并且能够对结果进行有效的统计比较。 为了高效使用 PAN, 用户在建立自己的模型之前就要考虑哪些输入参数是为了定义不同的情景而需要改变的, 并 确保在模型中通过 Variables 定义它们,或在 Resource 中将其定义为容量(capacity),这样 才能在 PAN 的“情景”中作为“控制”变量被选定。 启动过程分析器后,可以通过 File > New(或者 Ctrl+N 或 目,或者通过 File > Open(或者 Ctrl+O 或 )创建一个新的 PAN 项

)打开一个先前保存过的项目文件(文件扩

展名为.pan)。PAN 只能一次打开一个项目窗口,但是用户可以同时运行 PAN 中的多个例 子。当为项目增加一个新的“情景”时,只需在指定位置双击打开“情景属性”(Scenario Properties)对话框,在此对话框中用户可以为“情景”命名并在 Tool Tip 处填写说明性文 字,并在 Program File 处把这个“情景”与已存在的某个程序文件(.p)联系起来(可使用 Browse 按钮来搜寻你所需要的.p 文件) 本节中用于 PAN 实验的是模型 6-4, 。 除了将 Statistic 数据模块中 Output File 处填入的 Daily Profit. dat 删掉之外,它与模型 6-3 基本上是相同的, 因为 PAN 可以自动跟踪这些数据,故而将它们写到读者自己定义的文件中只是浪费时间。 此处仍然对每种“情景”做 100 次重复仿真。首先检验这个模型(Run > Check Model 或 F4 键或 按钮),这样就生成了 Model 06-04. p 文件,并将它选作此处的程序文件。如果之后

读者想要编辑这些内容,只需右击情景所在的行并选择 Scenario Properties 即可。为了给这 个“情景”选择“控制”变量,右击其所在的行(不要右击该行的左边缘),或者右击顶部 的 Scenario Properties 标签,然后选择“插入控制”(Insert Control)调出一个对话框,其中 包含一个可扩充的树状结构, 在这个可扩充树中包含有资源 (resources) 系统变量 、 (system) (重复运行的次数及长度)以及用户自定义变量(User Specified)中可能的控制变量;单击 任何一棵树的“+”标记可以详细显示它的各条目,从而用户可以双击选择任何输入,使它 在“情景”这一行中显示为一个控制变量。在本模型的实验中,选择了 3 个控制变量,它们 都来源于用户自定义的变量:  Max Load,在第 6.4 节中已讨论过,它使得我们可以更改每天允许预约的工作小时 数。  Max Wait,在每一天中我们可接受的就地等待服务的最大车辆数。
12



Wait Allowance,根据预定服务时间(book time)确定所承诺的服务时间时所引入 放宽因子(小时)。

一旦选定了所有需要的控制变量, 可在本行或者顶端再次右击, “插入响应” 选择 (Insert Response)来选取所需要的响应项;本例中从用户自定义组中选择了两个响应,Daily Profit 和 Daily Late Wait Jobs(后者揭示了不能在承诺的时间内完成的“等待”工作的平均数量, 这一指标必须维持很低以保证客户的满意度)。控制变量显示的是模型中已经定义好的值, 但是读者在 PAN 项目窗口中的“情景”所在行中可以很容易地编辑它们的值(这就是 PAN 用处的体现),因而执行相应情景时可以很方便地修改它们。在基准方案情景中,控制变量 值与原始模型中的相同(分别为 24,5,1)。因为还未曾运行这一情景,所以响应栏的值 是空白。图 6-4 给出了 PAN 项目窗口的部分内容,这是在定义完此情景并将项目保存为 Experiment 06-01. pan 后的窗口(之所以称之为实验,因为它实际上确实是一个设计好的实 验过程)。

原书 P270 图 6-4 定义了第一个情景(基准方案)后的 PAN 项目 Experiment 06-01. pan 读者可以重复以上步骤来加入更多的情景。 然而, 如果它们与以前已经定义的情景相似, 则可以先复制(在左边的情景编号处右击,并选择“复制情景”(Duplicate Scenario)), 然后在复制的情景中编辑即可。 我们可以随机改变控制变量的输入,来观察它们如何影响输出响应。通过 PAN 很容易 做到,但那样我们却不能系统地学到很多知识。而且,需要记住的是做仿真归根结底就像是 在化学实验室中做实验一样(只是它不会产生难闻的气味),所以我们可以应用实验设计的 原理,对本模型设计一个系统的实验,通过一定的方式(这就是设计)来改变控制变量取值 (在实验设计中称为因子),从而观察它们如何影响输出响应(在实验设计中我们也这样称 呼它们)。对初学者来说,如果实验中每个因子(控制变量)有两种水平, “低”或者“高” (传统上分别用“-”和“+”表示),这里有 k=3 个因子(控制变量),就可以得出所有高 低两个水平值的 2k 种组合方式,它被称之为 2k 因子试验设计问题,在本例中包含 2k=23=8 种不同的情景。虽然因子(控制变量)的高低水平值的选择往往是主观的,但是可以尽量从 实际问题出发并拓展,因此我们选定 Max Load 的高、低水平值分别为 40、20,Max Wait
13

的高、低水平值分别为 7、1,Wait Allowance 的高、低水平值分别为 2、0.5(注:对每个控 制变量而言,基准方案的值包括在此范围内)。每种情景都可以描述成三种“-”和“+”符 号的组合序列;比如,“+-+”表示了 Max Load = 40 ,Max Wait = 1, Wait Allowance = 2 的情景。图 6-5 给出了 9 种情景的 PAN 项目,其中也包括基准方案情景。

原书 P271 图 6-5 定义了所有情景后的 PAN 项目实验 Experiment 06-01. pan 要运行一部分或全部情景,可以通过单击每行最左列来选择本行(Ctrl+ Click 可以增加 选择的行,或者 Shifts+ Click 来选择相邻数行)。之后选择 Run > Go(或者 F5 功能键或者 按钮)。图 6-6 给出了运行这 9 种情景后的结果,在 Rresponse 列中给出了每种情景重复 仿真 100 次的均值。观察 Daily Profit 列,可以清楚地看出 Max Load 增大时 Daily Profit 值 也相应提高, Max Load 降低时也随之降低。 当 但是 Daily Profit 与 Max Wait 和 Wait Allowance 之间的变化关系却不显著。观察 Daily Late Work Jobs 列,却很难看出哪一个控制变量的变 化对输出响应有明显的影响。

原书 P272 图 6-6 运行 PAN 项目所有情景后的结果 上图中的结论是基于对每种备选方案的仿真运行次数都多于 1 次得到的 (读者应该还记 得,在模型文件中每种情景我们设置重复仿真次数为 100 次,因为我们没有选用“系统控制 变量”(System Controls)里的 Num Reps 项来控制重复仿真次数,所以对每一个情景 PAN 都运行了 100 次重复仿真),当然,如果能够知道这些数据的统计有效性那就更好了。为研 究 Daily Profit 值的统计有效性,选择对应的列(单击 Daily Profit 单元格上方的 Response 标签,选中这一列的结果),接着选择 Insert > Chart (或 ,或在本列中单击右键并选择

Insert Chart)。这里有许多选项可选,本节只完成其中的一种,读者可以通过 Help 的帮助文 档来学习其余的。在 Chart Type 对话框里,选择 Box and Whisker(盒状图),单击 Next,

14

选择 Use these Responses 下的 Daily Profit,再点击 Next 并且接受这个(第 3 个)窗口的缺 省值。 在最后一个 (第 4 个) 窗口中, 选中 Identify Best Scenarios 方框, 并确保选择了 Bigger is Better 这一项(“越大越好”,为缺省值),并且在误差容限(Error Tolerance)处填入 0 (不管那里的缺省值是什么)。 这些工作都完成后,就会看到类似于图 6-7 中出现的内容。若读者想要使图更大一些, 可以选中图片然后拖动四周的边框即可。如果右击图片,选择 Chart options,接着选择 Data 标签,读者就会看到一个表格,在表格中给出了每一种情景的除均值外的数值结果,如多次 重复仿真后的最小值和最大值、95%置信区间半长、以及置信区间的最小和最大边界值等。 在图中,垂直方向上的方框给出了每种情景下 Daily Profit 期望值的 95%的置信区间,红色 的(奇数项情景)与蓝色的(偶数项情景)区间相比,在 Daily Profit 期望值这一项上明显 更好(指出颜色是为了使单色印刷的书中内容更生动)。更准确的说,这也意味着“红色的” 情景所构成的子集合,在 Daily Profit 期望值方面,有 95%的可能包含了真实的、最佳的情 景。如果选择的 Error Tolerance 大于 0,则“红色的”子集合有 95%的概率包含最佳的方案、 或者误差容限范围内的最好方案。 必须记住, 这些结论是基于每种情景所定义的重复仿真次 数所得出的(在本例中,定义每种情景重复仿真 100 次,但是也可以为不同的情景定义不同 的重复仿真次数);如果读者想要使被选定的(红色)集合变得更小,可以增加这些情景的 重复仿真运行次数,或者读者也可以将 Error Tolerance 定义为一个正数,这意味着在这一个 数量范围内就算所选择的情景比真正最佳的方案差也是可以接受的。所以使用正的 Error Tolerance 可以减少被选定的情景数量,不过要冒一点风险,即所选择的情景可能比真正最 佳的情景略差一点。这一选择过程的统计理论基础,是 2001 年由 Nelson, Swann, Goldsman, 和 Song 所建立的。

原书 P273 图 6-7 选择一个包含最佳(最大 Daily Profit)方案情景的子集 当然, 读者还可以做一个类似于图 6-7 的关于 Daily Late Waiting Jobs 的输出响应图 (建 议大家这样做)。然而,这个图在控制变量水平如何影响输出方面,没有明显的意义。 现在回到 Daily Profit 输出响应结果和图 6-7,显而易见,影响力最大的控制变量(至少 在这三个控制变量中)是 Max Load,它的值越大则利润值越好。在图 6-7 中很直观地显示
15

了这种关系模式,我们也可以计算出每种控制变量的主要影响(main-effect estimate),得 到量化结果 (可参看文献 Law and Kelton 2000 的第 12 章) 去掉 Max Wait 和 Wait Allowance 。 两个控制变量的影响(将它们固定为基准模型中的水平,即 5 和 1),然后来研究 Max Load 单独发挥作用的情况,让它们取介于 20 和 40 之间更多的值(20,22,24,,38,40)。 为此,我们建立一个新的.pan 文件(Experiment 06-02. pan),结果如图 6-8 所示。图中显示, 利润上升到某一点后就开始下降,很明显,太大的 Max Load 起了负面的影响。由图中可以 看出,将 Max Load 设置在 30 时可使利润最大化(图中红色与蓝色的底色显示,本实验的 结果有统计显著性,即 Max Load 介于 26 和 36 之间时比其它情况更好)。 仔细观察图 6-8,在右上部的 Daily Late Work Jobs 输出响应栏,随着 Max Load 的增加 也有增加的趋势, 尽管不很明显。 这从模型本身也能看出其含义  如果接受了越来越多的 工作预约而又没有增加工作能力, 那么因无法按期完工而被延误的等待作业数量显然会越来 越大。在最佳的(利润最大化)Max Load 处(其值为 30),Daily Late Work Jobs 是 0.908, 对于每天只允许有 5 项就地等待服务的工作来说, 这个值太大了一些, 因为这样每天几乎都 有一项工作不能准时完成。虽然主要目标是提高利润,但是我们不能接受 Daily Late Work Jobs 太大的情况(比如大于 0.75),因为太多的延期交货会激怒并失去部分客户。如果我 们能保持在 Daily Late Work Jobs 不超过某个值(比如 0.75)的情况下,使得利润最大化, 那不是更好吗? 6.6 节将介绍如何来做。

原书 P274 图 6-8 Max Load 单独作用下的 Daily Profit

6.6 用 OptQuest 寻找最佳备选方案
在满足 Daily Late Work Jobs 输出响应不超过 0.75 的条件下寻求 Daily Profit 最大值的过 程中, 6.5 节所评价的那些情景只不过是无数可能性中的几种罢了。 假定读者可以自由地选 择关于 Max Load、Max Wait 和 Wait Allowance(在所定义的范围内)可能取值的组合,因 为共有 3 种输入控制变量,这一过程就可以看作是在三维空间中寻找可以使 Daily Profit 最 大的 3 维向量。由于存在许多种可能的组合,因此对它们全部评估是不现实的。

16

应该从哪里开始着手呢?一个合理的位置就是迄今为止所知的最佳点。在图 6-6 和图 6-8 的所有情景中,很显然当 Max Load = 30、Max Wait = 5 和 Wait Allowance = 1 时,Daily Profit = 581 为最佳点;然而此时 Daily Late Work Jobs 的值却很大(为 0.908,现在要求这个 值最大不超过 0.75),所以这一情景不可接受。再观察图 6-6 和图 6-8,寻找一个 Daily Late Work Jobs 小于 0.75、而同时 Daily Profit 值很高的情景,看来基准方案(Max Load = 24、 Max Wait = 5 和 Wait Allowance = 1,此方案的 Daily Profit 值为 492,Daily Late Work Jobs 略小于 0.70)是迄今为止所发现的最好的可接受的情景。 (这一结果是否令人沮丧?是否这 意味着在第 6.5 节中我们是在浪费时间呢?答案是否定的, 因为我们也学到了许多关于三个 控制变量如何影响两个输出响应值的知识,现在我们要寻找一个更好的方法。)所以我们在 3 维空间中,从代表基准方案的点出发开始搜索。 接下来该向哪个方向搜索呢?这不是一个容易回答的问题。许多人在这方面做了很多 年的研究工作, 并且建立了解决这一问题的许多方法。 Arena 中带了一个从 OptTek System Inc. 购置的名为 OptQuest 的软件包, 它应用了禁忌搜索 (tabu search) 和散点搜索 (scatter search) 等启发式算法,在输入控制变量空间中巧妙地移动,以达到快速、可靠地向最优点接近的目 的。OptQuest 在一定程度上与 PAN 类似,它们都“操纵”Arena 模型的运行;区别在于 PAN 是模拟用户指定的那些情景,而 OptQuest 则自己决定对哪些情景进行仿真运行,并且这些 情景以一种迭代的方式向最佳的输入控制变量组合靠近。 欲了解关于 OptQuest 如何与 Arena 协同工作的更详细的内容,请查看 Help > Product Manuals > OptQuest for Arena User’s Guide。 (此处用模型 6-4) , 要运行 OptQuest for Arena, 首先激活所要研究的模型的 Arena 窗口 选择 Tools > OptQuest for Arena 来打开 OptQuest 应用系统窗口, 接着通过 File > New (或者 Ctrl+N 或 )打开一个新的文件。这样就打开了模型中现有控制变量(输入参数)的“控

制选择”(Control Selection)窗口,其中包括资源水平(没有在 Schedule 中定义为可变容 量)和变量。沿着左列向下,选择(勾选上那些对应的方框)Max Load、Max Wait 和 Wait Allowance,接着单击左下方的 Reorder 按钮将这些条目提到顶端以便后面使用(OptQuest 不会改变未勾选上的输入项,它们会保持模型中既定的值不变)。每行的建议值(Suggested Value)就是用户提供给 OptQuest 的开始点的值,也将是应用在模型中的当前值,在本例中 提供给 OptQuest 的值,就是我们目前所知道的最好的开始点的值。在表格中,下界(Lower Bound)和上界(Upper Bound)限定了 OptQuest 在搜索过程中的取值范围,故而它们应该 设置得与实际情况相符。为了留给 OptQuest 足够的搜索空间,同时保证搜索方案接近实际,
17

我们定义 Max Load 的取值区间为[20,40],Max Wait 为[1,7]和 Wait Allowance 为[0.5,2]; 这些数值范围与 6.5 节中 PAN 实验中的范围相同。因为 Max Load 和 Wait Allowance 是时间 值, 它们可以取相应区间内的任意实数, 所以它们的数据类型 (Type) 是连续的 (Continuous) 。 另一方面,如果 Max Wait 不是整数就没有任何意义了,所以它的类型(Type)应该是离散 的(Discrete),这可以通过下拉菜单来选择(接受输入步长的缺省值 1,这是 OptQuest 改 变输入控制变量时的增量值)。图 6-9 给出了完整的控制选择窗口。单击底部的 OK,将进 入到约束(Constraint)定义部分。

原书 P276 图 6-9 完整的 OptQuest 控制选择窗口 在“约束”(Constraints)窗口中,用户可以对输入控制变量的组合设置限制(注意, 不是对输出量  那些量在 OptQuest 中被称为“要求” (Requirements)而不是约束,这将 在后面讲到) 。在本问题中,除了那些已经定义好的控制变量的上下界外,没有任何其它约 束,所以此处不需任何操作。如果用户有约束的话,可以在本窗口中使用正确的变量或是资 源容量名称、以及常用的算术和关系运算符把他们写出来。单击 OK 继续向前。 在“目标和需求选择”(Objective and Requirement Selection)窗口中,用户可以选择需 要优化的目标,以及目标是最小化还是最大化。在 Daily Profit 栏左边的下拉菜单中,选择 “最大化目标”(Maximize Objective)。在这里读者可以规定对输出的任何要求;在 Daily Late Work Jobs 的左边下拉菜单中选择 Requirements,在“上界”(Upper Bound)栏中填入 0.75。一个“要求”在一定程度上与约束类似,只不过“要求”是作用于仿真的输出结果, 而约束是作用于仿真的输入数据, 但是它们的基本作用都是识别出任何不能满足需求的不可 行情景。单击 Record 按钮把所选择的条目移到菜单顶部(这样做是为了后面使用方便), 接着单击 OK。 在“选项”(Option)窗口中,用户可以设置有关 OptQuest 如何进行搜索的计算限制 和规程。“时间”(Time)表页中的输入项应该是很清楚的(我们将缺省的 10 分钟改为搜 索 20 分钟);本表页中 OptQuest 所称的“simulation”与我们曾命名的“情景”或者“方 案”是一样的。“精度”(Precision)表页中,用户可以定义每个情景要运行的重复仿真次 数,它即可直接显式地规定也可通过置信区间精度来隐含地规定;本模型中,根据之前关于
18

随机干扰水平的经验, 我们选择采用在 10 到 100 之间变动重复仿真次数。偏好”Preference) “ ( 表页中包括了许多其他控制项。最后单击 OK。欲了解这些设置的更多内容,可单击任何一 个窗口中的帮助按钮来查看相关内容。 如果想再回去查看上述的 OptQuest 窗口, 可以使用 OptQuest 窗口顶端的按钮: 用 看 Controls Selection 窗口,用 Selection 窗口,用 查看 Constraints 窗口,用 查

查看 Objective and Requirement

查看 Options 窗口。读者可以将完整的 OptQuest 设置保存在一个文件

中, 该文件的缺省名为.opt;此处我们将其保存在名为 Optimum Seek 06-01. opt 的文件中。 选择 Run > Start 菜单选项或者单击 , 开始 OptQuest 搜索。 通过选择 View > Status and

Solutions 和 View > Performance Graph 可查看 OptQuest 的优化进展情况。图 6-10 给出了 20 分钟后这两个窗口的内容。曲线给出了各个仿真(情景)运行所得到的最好(最大)结果。 在所定义的 20 分钟内, OptQuest 评价了 116 个不同的情景, 看起来最好的情景是第 111 个, 其 Max Load = 28.3, Max Wait = 7,Wait Allowance = 1.7, 同时得出 Daily Profit 的值为 611.5。 与基准方案的利润值 492.6 相比有了显著的提高:几乎每天增加了 119 美元的利润,超过了 24%的增幅。当我们将上述搜索运行 6 小时后,会得到一个更好的方案,它是这段时间内所 评价的 1693 个情景中的第 267 个, Max Load = 30.4, 其 Max Wait = 4, Wait Allowance =1.1, 相应的 Daily Profit 值为 612.2。通过更长时间运行搜索到的情景只比前 20 分钟内找到的结 果有微小的改进,这一现象和图 6-10 中曲线的形状都非常具有典型性  OptQuest 有这样 的搜索趋势,即在初期时结果改进显著(低投入高效率),之后要想有进一步改进就需要多 得多的工作量了。

原书 P278 图 6-10 搜索 20 分钟后 OptQuest 的求解状态和性能指标 OptQuest 不能完全保证找到最佳方案,归根结底,这是一个具有挑战性的难题,不仅 要检验如此之多的可能性, 而且目标不能被确定性地加以度量 (因为它本身受大量不确定性 因素影响)。然而在大多数情况下,相对于手工的组合与尝试,OptQuest 的确有更好的工 可以查看文献 Glover, Kelly, 作效果, 可以得到更好的结果。 想要了解 OptQuest 工作的背景, Laguna(1999)。记住,可通过 Help > Product Manuals> OptQuest for Arena Users Guide 来
19

查看更多帮助内容。

6.7 小结
到目前为止,读者应该对以下内容有比较好的了解了:即如何有效利用终态仿真模型 来得到对期望结果的正确而精确估计,如何找出不同备选方案(或是情景)在关键输出性能 指标上是否存在显著的差异, 以及如何有效搜寻最优方案。 要成为一名高效的模型使用者 (不 仅仅是一位高效的建模者,当然那也是同样重要的),读者还需要一个很长的提高过程。在 第 7 章中,我们将学习更多的建模方法,如果读者对长时间运行(或称为“稳态仿真”)的 结果感兴趣, 在第 7 章的最后还将研究基于长时间仿真运行的输出分析, 那种情况下用户需 要做的工作与本章所讲授的内容有些不同。第 12 章讨论了仿真中更深层的统计问题,包括 如何产生随机数,如何减少输出差异性(无需更多的计算量),如何让 Arena 自己决定做多 少次仿真运行来达到用户可接受的精度,以及如何设计仿真实验方法等。

6.8 习题
6-1 在习题 5-1 中,将你所得到的结果与书中的结果作一个统计比较;对这两个模型都做 50 次重复仿真后建立 95%的置信区间,看它们是否部分重迭。性能指标选取平均排队时间、 平均队长和服务台利用率。 6-2 使用习题 5-2 中的模型,把零件在机器 1 上的第二次加工时间改为 TRIA(6.7, 9.1, 13.6)。对新模型做 20000 分钟的仿真,并比较两个模型的结果(使用习题 5-2 中同样的三 个输出性能指标)。对这两个模型分别做 20 次重复仿真,对结果做简单的统计比较:求出 95%的置信区间,并找出这两个区间的关系。 6-3 在习题 5-3 中,为了使两个剪切器的期望平均系统逗留时间的 95%置信区间半长降至 1 分钟,需要做多少次重复仿真?(读者不需要作这一实验,只需要估算所需要的重复仿真次 数的大概数量即可)。 6-4 习题 5-4 中的设施处于拥挤的城市地段,这里土地非常昂贵,所以需要决定为队列中等 待卸载的卡车留出多少空间。如何解决这个问题(请谨记统计观点)? 6-5 在习题 5-5 中,假定可以多雇佣一名工人,而且所雇工人与相应四个位置的操作员的工 作能力完全一样, 他应该被安排在哪个位置工作呢?使用 PAN 对每种情景做 5 次重复仿真, 从中选择平均系统逗留时间最少的。 再回头看一下, 你原来的选择结果是不是令人很惊讶?
20

假定你可以多雇佣 5 名工人,并可以将他们随意安排到这四个已有的工人那里去,包 括可将这 5 个人一起安排到同 1 个工人那里去。最佳方案是什么?使用 OptQuest 来搜索这 5 个工人的最佳安排方式,目标是使平均系统逗留时间最小。 6-6 在习题 4-1 中,假设到来的顾客中有 7 名属于常顾客。对模型做 5 次重复仿真(5 天)。 假定所有的时间参数均与以前相同,在以下各种情景中,根据旅客的类型(“常顾客”和非 “常顾客”)来观察平均系统逗留时间的统计值: (a)分配四名工作人员只为非“常顾客”服务,第 5 名工作人员只为“常顾客”服务。 (b)对模型做如下改动:即当队列中没有“常顾客”在等待时, (a)中只为“常顾客” 服务的工作人员也可以为一般顾客服务。 (c)对模型做如下改动:使任何工作人员可以为任何顾客服务,但是优先服务“常顾 客”。 你认为这三种方案里哪种对“常顾客”而言是最佳的?哪种对非“常顾客”(占总顾 客的 93%)是最佳的?将该问题视作终态仿真,在按有效的统计方式对这些方案加以比较。 6-7 在习题 5-13 中,做 30 次重复仿真,并计算出两种类型顾客的期望系统逗留时间的 95% 置信区间。 6-8 在习题 5-14 中,做 30 次重复仿真,并估计这个模型与习题 5-13 模型的期望差异(基于 顾客的系统逗留时间)。注意使用适当的统计方法。 6-9 在习题 5-15 中,做 30 次重复仿真,并估计这个模型与习题 5-14 模型的期望差异(基于 顾客的系统逗留时间)。注意使用适当的统计方法。 6-10 对于模型 5-3 中的库存系统,使用 PAN 比较以下各组(s,S)下的平均总费用: (20, 40) (20, 60) (40, 60) (20, 80) (40, 80) (60,80) (20, 100) (40, 100) (60,100) (80,100) 对每种情况重复运行50次, 并使用适当的统计方法来找出其中的最佳方案 (成本最低) 。 这一问题来源于Law and Kelton (2000) 一书的第1.5.5节。 6-11 对模型5-3的库存系统,使用OptQuest来寻找(s,S)的最佳设置(总成本最小)。令s 在1和99之间取值(步长为1),S在2和100之间取值(步长为1)。要注意s和S必须是整数而

21

且满足s < S。 至于运行时间、 重复仿真次数等, 由读者自行决定。 这一研究与Law and Kelton (2000)一书的第12.4节和12.6.1节类似。 6-12 对于习题6-11,通过将库存检查间隔(Evaluation Interval,目前为1天)作为变量加入 到优化变量集中,来研究在每天开始工作时查看并补充(当需要时)库存是否是最佳方案, 让该值在半天到5天之间连续取值, s和S的取值情况与习题6-11相同。应用OptQuest求取最 优设置。如果读者使用Model 05-03. doe作为基础模型,就需要在Variable模块中定义 Evaluation Interval,而不是像原模型那样在Expression模块中定义,这样OptQuest才能对其 寻优。 6-13 对习题5-20中三种产品的(s,S)6个变量应用OptQuest寻优。使每个s在1和99之间取 值(步长为1),S在2和100之间取值(步长为1);当然,s和S必须是整数,且s < S。 6-14 对习题5-21中三种产品的(s,S)6个变量应用OptQuest寻优,它们的取值范围与习题 6-13种相同。将所得到的结果与习题6-13的结果相比较,并从供应商利用不同费用结构提供 的激励效果的角度对此加以解释。 6-15 在习题4-22中,假定你可以多雇佣一名职员,那名职员可以被派至人工登记处、自动 登记处或者安检处工作。这名新职员安排到哪儿最好呢?至于一个系统“好”的标准,可使 用所有类型顾客在系统中的平均总逗留时间作为评价指标。 请读者设置PAN运行, 并决定所 需要的重复仿真次数,以得到一个可信的结论。 6-16 在习题6-15中,假定你可以雇佣5个职员(而不是只增加1个),他们可以以任何方式 被指派到人工登记处、自动登记处或者安检处工作。你不能减少习题4-22中任何一处的职员 数。使用所有类型顾客在系统中的平均总逗留时间作为评价指标,这5名职员的最佳配置方 案是什么?你会使用所有这5个人吗?设置OptQuest运行,并决定重复仿真的次数。 6-17 在习题4-22中(职员数量固定在初始水平上不变),航空公司注意到尽管不需要附加 服务的旅客可以到自动登记处完成服务, 但多数旅客还是选择在人工登记处接受服务, 选择 人工和自动服务的人数比例分别为35%和50%。假定通过有效“宣传”,选择人工与自动服 务的人数比例变为10%和75%(的确存在10%的旅客需要人工登记处的附加服务)。而这一 转变将如何影响旅客的平均系统逗留时间呢?对以上两种情况做200次重复仿真, 并比较之。 6-18 习题2-8描述了对模型3-1的一种变形。 用一种有效的统计方法来度量该变化对平均排队 等待时间以及服务台利用率的影响。 读者可自行决定重复仿真的次数, 以得到一个有意义的、 且具有满意精度的结论。

22

第 7 章 中级建模与稳态统计分析
在第四章和第五章中介绍了许多利用 Arena 建模的基本元素, 基本操作面板和高等操 作面板中的一些基本用法,以及对实体流动的控制,包括资源的调度(Schedules)和状态 (States) 、集合(Sets) 、变量(Variables) 、表达式(Expressions) 、站(Stations) 、运送 工具(Transfers ) ,以及增强动画效果等。在这一章里,我们先介绍几个概念,通过这些 概念读者可以构建更加详细的模型, 然后我们在这些概念的基础上展开本章的内容。 像前 面的章节一样,我们将通过一些精心设计的例子来阐明这些具体的细节。首先在 7.1 节中 介绍一个新的实例;在 7.1.1 节中讨论 Arena 中因实体而异的加工序列(Sequences)的概 念;在 7.1.2 节中讨论对一个系统建模的一般流程,和对一个项目建模所应达到的详细程 度,以及对数据的要求及其可用性,并在 7.1.3 节讨论建模所需的数据部分; 7.1.4 节中 讨论模型的逻辑部分。7.1.5 节中将引入动画,包括导入已有的 CAD 图形作为场景布局。 7.1.6 节讨论如何验证所建立的 Arena 模型反应了你所需要解决的问题。 然后在 7.2 节中继续讨论输出数据的统计分析,这次我们将用 7.1 节中所建立的模型 做稳态仿真输出分析。 当读者已经阅读和消化了本章的材料后, 对于如何考虑在很多细节上的建模就有了比 较清晰地认识,并且能够学会如何通过长时间运行来对系统的稳态性能加以分析。

7.1 模型 7-1:一个小型制造系统
图 7-1 描述了一个小型制造系统,包括零件到达系统,四个制造单元(Cell 1、2、3、 4) ,以及零件离开系统。Cell 1、2 和 4 各有一台机器;Cell 3 有两台不完全相同的机器, 其中较新的一台机器的加工时间是另一台的 80%。这个系统生产三种类型的零件,每种 零件的加工顺序是不同的。零件的加工顺序和加工时间(以分钟为单位)如表 7-1 所示。 所有的加工时间服从三角分布,其中 Cell 3 的时间是旧机器的加工时间。

P286

图 7-1 小型制造系统的布局 各种零件混合在一起到达系统,到达间隔时间服从均值为 13 的指数分布;第一个零 件在 0 时刻到达。 各种零件的分布情况为: 零件 1 占 26%, 零件 2 占 48%; 零件 3 占 26%。 所有零件从左边进入系统,从右边离开,在系统中以顺时针方向移动。现在,忽略距离的 因素(稍候将讨论) ,假定在任一对单元之间的移动时间都是 2 分钟。我们将收集关于资 源利用率、 排队时间和队长、 以及各种零件的系统逗留时间 (从进入到离开) 的统计数据。 开始时,我们运行仿真 32 小时。

7.1.1

Arena 中的新概念

我们需要 Arena 中的一些新概念来描述这个问题的某些特征。 第一个特征是三种零件 按不同的工艺计划(加工顺序)通过系统。在先前的模型中,所有的实体都按相同的顺序 通过各个位置。对于这种系统,需要有一个能够自动安排实体运动线路的工艺计划。 第二个特征是 Cell 3 的两台机器是不相同的  新机器加工零件的速度比旧机器快。 现在需要对这两台机器加以区别。 第三个特征是实体在系统中的流动形式。 在先前的模型中, 实体在系统中的流动是通 过直接连接(Connect)或是直接的路径(Route)选项来完成的。当使用 Connect 选项时, 实体立即被送到下一个模块,在仿真中没有运送时间。如果在新的模型中使用 Connect 选 项,那么就必须包含一定数目的 decide 模块,用以引导零件到下一个正确的加工单元, 但这样无法模拟两分钟的运送时间, 也无法用动画来模拟零件的流动。 虽然我们可以使用 Delay 模块来描述运送时间,但它并不能帮助我们用动画来显示零件的移动。我们倒是可 以使用 Decide 模块后面跟随一系列 Route 模块的形式来模拟两分钟的运送时间并动画显 示零件的移动。不过,在 Arena 中有一个“序列” (sequences)的概念,它可以很容易地 模拟出实体按以上方式通过系统的情况,并且描述出零件的运送时间。 表 7-1 零件的工艺路线和加工时间
零件 1 加工单元 / 时间 1 6,8,10 2 1 11,13,15 3 2 7,9,11 加工单元 / 时间 2 5,8,10 2 4,6,8 1 7,10,13 加工单元 / 时间 加工单元 / 时间 加工单元 / 时间 3 15,20,25 4 15,18,21 3 18,23,28 4 8,12,16 2 6,9,12 3 27,33,39

在许多系统中, 不同实体都是根据其各自预先定义好的路径通过系统的。 大多数制造 系统中, 不同零件也各有其工艺计划, 具体指定了每种零件在系统中必须完成的操作序列。 许多服务系统也有相似的要求。例如,一个机场旅客通行的模型中,可能需要根据旅客是 否携带需检查的行李或者仅带有手提包、 以及根据旅客乘坐的是国内航班还是国际航班等 因素,来要求旅客从不同的路径通过机场。 Arena 根据预先定义的站点访问次序(在 Sequences 模块中定义)自动使实体按规定 路线通过系统。 利用高等运送面板中的 Sequence 数据模块可以定义一个指定的站点序列, 并且可以定义在每个站点的属性或变量。将所定义的序列赋给实体(使用内置的 sequence 属性,下面将介绍) ,使实体以此顺序通过系统中的各站点。在将实体向下一目的地传输 时,需在 Route 模块中选择 Sequential 选项。 当实体按照自己的序列行进时,Arena 会记录实体的当前位置以及下一时刻的去向。 这个工作可通过三个特殊的、自动定义的 Arena 属性来完成:Entity.Station(M) , Entity.Sequence(NS) ,和 Entity.JobStep(IS) 。每个实体都拥有这三个属性,并且新创建 的实体的属性默认值为 0。Station 属性记录实体的当前位置或当前正要被运往的位置。 Sequence 属性记录实体需要遵循的序列。 Jobstep 属性则指定实体当前在序列中的位置。 而 首先使用 Sequence 数据模块对每种实体将要经过的一系列站点加以定义和命名。然 后,当新零件进入系统时,把特定序列的名字赋给该零件实体的 Sequence 属性  NS1, 这样就把实体与相应的序列联系起来了。当实体被从一个站点运送到序列中的下一站点 时, 我们在实体运出模块的 Destination Type 域中选择 Sequential 选项。 当运行到这一时刻 时,Arena 将首先对 Jobstep 属性(IS)的值增 1。然后根据 Sequence 属性和 Jobstep 属性 的当前值检索到目的站点。完成在 Sequence 模块中定义的赋值操作(如果有的话) ,并把 检索到的目的站点赋给实体的 Station 属性(M) 。最后,Arena 将实体运送到那个站点。 一般来说,实体按规定顺序完成加工,然后离开模型。然而不一定必需如此。只有在 实体使用 Sequential 选项进行运送时,Jobstep 属性值才自动递增。 因此我们可以临时停止 实体按照规定序列的传输, 而是将实体直接运送到另一站点, 稍后再重新回到序列规定的 位置。 当在加工过程中某些工位上的一些零件被要求返工时, 这一点很有用。 返工完成后, 零件可以很方便地再次回到正常加工序列。 在任何时刻都可以对 sequence 属性重新赋值。例如,可以通过为 Sequence 属性赋新
1

Arena 在内部使用 M,NS 和 IS 作为属性名,而在下拉式菜单中提供相应的别名 Entity.Station, Entity.Sequence 和 Entity.Jobstep。

值和将 Jobstep 属性重置为 0 来处理一个不合格的零件。按新的序列,零件将被送往返工 区的一系列站点,也可以通过减少或增加 Jobstep 属性值在序列中回溯或前跳。为了确保 正确地重新设置 Jobstep 属性,必须要注意谨慎行事,并且要记住 Arena 总是先对 Jobstep 增值,然后再查找序列中的目的位置。 正如我们在前面提到过的, 读者可以在序列中的任何阶段设置属性和变量。 例如改变 实体图形,或者将加工时间赋给用户定义的属性。对这个小型制造系统,需要使用这一功 能来定义加工时间,这些加工时间是由零件本身和其所在的加工站点决定的。

7.1.2 建模方法
具体的建模过程依赖于系统的复杂性和可用数据的性质。 在简单模型中, 需要什么模 块和如何放置它们是很明显的。 但在更复杂的模型中, 就需要慎重考虑一下用什么样的建 模方法比较合适。在学习了更多关于 Arena 的知识后,读者会发现有很多方法可以用来模 拟一个系统或系统中的一部分。 对经验丰富的建模者来说, 并不只有唯一的正确方法来模 拟一个系统。尽管如此,但如果没有正确地捕捉到系统所需的细节要求,那么所用的建模 方法就有可能是错误的。 复杂模型的设计常常由模型的数据需求和可用的数据来推动。 经验丰富的建模者经常 要花大量时间决定如何收集、存储和使用数据,然后再设计所需的模型结构。当数据要求 变得更加苛刻时,这一方法通常是在短期内正确建立模型的唯一途径。在对供应链系统、 仓储系统、配送网络和服务网络系统建立仿真模型时,这一点是很明显的。例如,典型的 仓库有成百上千种不同的存储单元,也即 SKUs(Stock-Keeping Units) 。每一个 SKU 可能 要求能够描述出其在仓库中的位置、 尺寸、 权重的数据, 以及该存储单元重新进货的数据。 除了详细说明与仓库存储的内容相关的数据之外,还有客户的订购数据以及 SKU 的存储 装置或者设施类型等其它信息。如果需要模型在实验期间具有改变 SKU 的位置、存储装 置、重新进货策略等能力,那么所用的数据结构将是很关键的。尽管本书中要建立的模型 并没有那么复杂,但仍然建议在开始建模之前考虑这些数据需求。 对我们的小型制造系统来说, 数据结构将会在一定的程度上影响模型的设计。 我们可 以使用 Sequence 来控制零件通过系统的流程,同时在 Sequence 模块中为零件赋加工时间 属性(本例中,在这里只赋零件在 Cell 1 以外的其它制造单元中的加工时间,而在 Cell 1 中的加工时间,我们将使用 Expression 模块来定义) 。零件的运送时间和在 Cell 3 中新机

器加工时间因子(80%)将使用 Variables 模块来定义。在这个模型中,我们还将使用集合 (Sets)来实现将正确的序列和图像与零件的类型相匹配。 首先,我们将利用数据模块来定义有关参数,然后进入需要新模块的模型主题部分。 其次,我们可以在模型中使用 CAD 图形或是其他图形来加入初始的动画元素。最后,我 们将简要地讨论模型确认的概念。至此,对怎样打开和填写 Arena 的对话框应该已经很熟 悉了,所以我们就不再细述如何在 Arena 中输入信息的一般细节了。对于在前面的章节中 已经介绍过的模块和概念, 我们仅简单地说明必须加入的数据。 如果想了解我们当前处在 模型的哪一部分,可以翻看图 7-5,那里面给出了完整的模型。

7.1.3 数据模块
我们将从“高等运送” (Advanced Transfer)面板里的“序列” (Sequence)数据模块 开始。双击相应的位置添加一个数据行,输入第一个序列的名字,Part 1 Process Plan。然 后进入“步骤” (Steps)栏输入加工步骤,即 Arena 站点的列表。例如,Part 1 Process Plan 要求输入下列 Arena 站点:Cell 1,Cell 2,Cell 3,Cell 4 和 Exit System。在 Step Name 栏 可为各步骤命名, 这里可任意取为 Part 1 Step 1 到 Part 1 Step 5。 在输入序列时最常见的错 误是忘记输入最后一站,即通常实体离开系统的地方。如果忘记了,那么当第一个实体结 束了它的加工路线后,Arena 会弹出运行错误信息, 因为 Arena 不知道下一步该将它送 到哪里。在定义 Sequence 的时候,记住一旦已经输入过一个站点的名字,那么随后就可 以从模型里其它站点的下拉列表中找到它。同时读者也需要为 Cell 2、3、4 的零件加工时 间属性赋值。由于我们将用 Expression 数据模块定义 Cell 1 上的加工时间,所以这里就不 需要为它赋值了。 输入界面 7-1 显示了序列 Part 1 Process Plan、 步骤 Part 1 Step 2,以及对 Process Time 的赋值情况。使用表 7-1 中的数据,可以相当简单地输入其余的序列步骤。稍后我们 将展示如何在模型逻辑中使用这些序列。

P290 输入界面 7-1 Sequence 数据模块

接下来,通过“高等操作”面板中的 Expression 数据模块定义 Cell 1 的零件加工时间 表达式。该表达式命名为 Cell 1 Times,包括在 Cell 1 中加工的三种零件的加工时间分布。 本来我们可以在前面的 Sequence 模块中很容易地输入它们,但是我们还是选择用表达式 来设置加工时间, 这样读者就会看到可以用不同的方法来为加工时间赋值。 因为有三种不 同的零件在 Cell 1 上加工,所以需要一个三行的表达式数组,每种零件占一行。输入界面 7-2 显示了这一模块的数据。 然后,我们将使用“基本操作”面板里的 Variable 数据模块来定义 Cell 3 的机器速度 因子(Factor)和运送时间(Transfer Time) 。在定义因子变量时,先观察如下结果:输入 到 Sequence 数据模块中的 Cell 3 的零件加工时间是针对旧机器的,假设新机器序号为 1, 旧机器序号为 2,则第一个因子值为 0.8(相对于新机器) ,第二个因子值为 1.0(相对于 旧机器) 。运送时间值输入 2。如果我们打算用概率分布的形式定义运送时间,那么我们 必需要用 Expression 来定义。而不能用 Variable。输入界面 7-3 显示了需要输入的数据。 我们将使用“基本操作”面板中的 Set 数据模块来定义关于 Cell 3 的机器集合、零件 图形集合和实体类型集合。第一个是“资源型” (Resource)集合,Cell 3 中包含两台机器: Cell 3 New 和 Cell 3 Old; “实体图形” (Entity Picture)集合命名为 Part Picture,包括 Picture.Part 1、Picture.Part 2、和 Picture.Part 3;最后, “实体类型” (Entity Type)集合命 名为 Entity Types,包括 Part 1,Part 2 和 Part 3 三个集合成员。

P 290 输入界面 7-2 定义 Cell 1 加工时间的 Expression 模块

P291 输入界面 7-3 定义速度因子和传输时间的 Variables 模块 建立集合时,首先添加零件加工序列这一项。进入 Set 模块后,读者会发现可用的集 合种类只有 Resource、Counter、Tally、Entity Type 和 Entity Picture,没有我们需要的类 型。可以通过使用“高等操作”面板中的 Advanced Set 数据模块来解决这个问题,这个

模块有三种类型:Queue,Storage 和 Others。Others 是一种几乎可以把任何相似的 Arena 对象设置成集合的选项。这里我们也使用这个选项,输入集合名 Part Sequences,集合元 素包括:Part 1 Process Plan、Part 2 Process Plan 和 Part 3 Process Plan。 在设置逻辑模块之前,先打开 Run>Setup 对话框,设定重复运行时间为 32 小时,基 准时间单位为分钟。同样也要通过 Edit>Entity 为实体选定图形,打开图像设置窗口,创 建三种不同的图形 — Picture.Part 1、 Picture.Part 2 和 Picture.Part 3。在本例中,复制蓝 色,红色和绿色的球,给它们重新命名,并且在各图形中上分别加上数字 1、2、3 来指示 三种不同的零件类型。 在定义了所有的数据模块后, 我们就可以在主模型中放置逻辑模块 并定义其参数了。

7.1.4 逻辑模块
模型的主要部分包括一系列逻辑模块, 用来描述描述零件到达, 进入单元和零件离开。 图 7-2 中所示的四个模块将被用来模拟零件的到达过程。Create 模块以均值为 13 分钟的 指数分布间隔时间来产生到达的零件。

P 292 图 7-2 零件到达模块 此时,并没有把每个到达的实体与其加工序列联系起来,我们将在 Assign 模块中建 立这种联系,如输入界面 7-4 所示。此赋值模块有两个目的:决定所到达的是哪种类型的 零件,并且为每一类达到的实体定义一个索引号,Part Index,通过这个索引号就可以把 每一到达实体与集合中适当的序列联系起来。 我们首先用离散分布来确定零件的索引号或 是零件的类型。 这种分布可以按给定概率产生一些相应的值。 在本例中, 分别按概率 26%, 48%,26%生成整数值 1,2,3。这些值和相应的概率是按“累积概率”和“数值”的顺 序一对一对地来定义的。最后一个数值(本例中是 3)对应的累积概率应该是 1.0。一般 来说, 并不要求这些数值必需为整数, 可以取包括负数在内的任何值。 零件索引号的值 1、 2、3 不仅可以表示零件类型,在本例中,也可以作为前面定义的集合 Part Sequence 中的 元素的序号,这样就可以将零件与其加工序列正确地联系起来。为达到这个目的,我们把

Part Index 属性作为 Part Sequence 集合的元素下标,这样我们就能把正确的加工序列赋给 Arena 的 Entity.Sequence 属性了。 我们还需要正确地将实体类型与相应零件的图形联系起来。 在最后两个赋值中, 通过 使用 Part Index 属性作为相关集合的元素下标,就可以做到这一点了。回顾之前创建的集 合 Entity Types 包括 Part 1、 ( Part 2、 Part 3 三个元素) 以及包含三种图形元素 , (Picture.Part 1,Picture.Part 2 和 Picture.Part 3)的集合 Part Picture,读者可以将这些集合看作是一个以 刚刚赋值的 Part Index 属性为下标的(一维)数组变量。在本例中这是没问题的,因为在 零件类型(Part Index)和加工序列、实体图形之间是一对一的关系。如下标为 1 表明零 件 1 的加工序列取 Part Sequence 中的第一个元素。 (在下一步的建模中要注意,这不一定 总是正确的。 它之所以在这个案例中是正确的, 是因为所定义的数据结构具有一对一的关 系。 )

P 292 输入界面 7-4 Assign 模块:定义零件属性

在这个案例中,上面的 Assign 模块确定了零件类型、并为其安排了相应的加工序列 和图形。 注意在 Assign 模块中首先定义 Part Index 的值是很关键的, 因为在后面的多个赋 值中都要用到它。现在我们准备把零件按它的加工序列送到第一站。 我们可以用“高等运送”面板里的 Route 模块来完成这一工作。之前,我们需要告诉 Arena 实体在哪儿,或者零件的当前位置(即目前所在的站点的位置) 。如果读者已经跟 着我们建立了自己的模型,就会发现在我们刚完成的 Assign 模块中的属性列表中有一个 属性叫做 Entity.Station(如果愿意的话你现在就可以进去看看) 。你可能想增加一条赋值 来定义零件的当前位置。不幸的是,如果你这样做的话,当运行模型的时候 Arena 将会报 错;不过我们可以使用下面介绍的 Station 模块来实现这一点。 在我们完整的模型中有六个站点:Order Release、Cell 1、Cell 2、Cell 3、Cell 4、和 Exit System。后五个站点是在填写零件的加工序列(Part Sequence)信息时定义的,第一 个站点 Order Release 是实体进入 Station 模块(在“高等运送”面板中)时定义的,该模 块不仅定义了这个站点,而且告诉 Arena 当前实体就在这个站点中。已完成的 Station 模 块如输入界面 7-5 所示。

P 293 输入界面 7-5 Station 模块

最后我们将使用 Route 模块(在“高等运送”面板中)把零件送到加工序列中的第一 个站点处。Route 模块的作用是将实体传送到指定的站点,或者是按照加工序列实体将要 前往的下一站点, 运送时间 (Route Time) 可以定义为变量或表达式。 在这个模型中, Route Time 为先前定义好的变量 Transfer Time, 如输入界面 7-6。 其中在 Destination Type 处选择 Sequential 选项, 此时模块中的 Station Name 区域将会消失不见, 并且在运行模型时, Arena 将根据在实体的加工序列来传送实体。

P 294 输入界面 7-6 Route 模块

接下来建立四个加工单元的逻辑。 这四个加工单元的逻辑在本质上是相同的, 都是零 件到达加工单元(一个站点) ,排队等待机器加工,在机器上加工,然后将零件按加工序 列运送到下一站。可以通过使用图 7-3(针对 Cell 1)所示的 Station-Process-Route 模块序 列来模拟所有的四个加工单元。

P 294 图 7-3 描述 Cell 1 的逻辑模块

Station 模块提供了零件将要被送达的位置。 在这个模型中, 我们按加工序列来运送零 件, 所以被运送的零件将从它的序列中找出下一个位置。 Cell 1 的 Station 模块的输入如输 入界面 7-7 所示。 到达 Cell 1 站点的零件将被送到下一个 Process 模块 (使用直接连接的形式) 在最底 。 下表示延时的 Expression 栏中,输入先前定义的数组表达式 Cell 1 Time,并且使用 Part

Index 属性作为数组的下标,以取出正确的零件加工时间。这个表达式将生成我们在前面 定义过的一个三角分布的随机数。其余输入见输入界面 7-8。

P294 输入界面 7-7 Cell 1 中的 Station 模块

P295 输入界面 7-8 Cell 1 中的 Process 模块 实体在 Cell 1 中的加工一完成就,就会被送到 Route 模块(见输入界面 7-9) ,然后实 体将按加工序列被送到下一站。除了名字之外,这个 Route 模块(见输入界面 7-6)与我 们在 Order Release 站点中的 Route 模块是完全一样的。 其余的三个加工单元与 Cell 1 是非常相似的,所以我们将跳过细节描述。在创建它们 的逻辑结构时,可对 Cell 1 的模块复制三次,然后按要求编辑相应的数据即可。对于每个 新的 Station 和 Route 模块,简单地把所有出现 Cell 1 的地方改成 Cell 2、Cell 3 或 Cell 4 即可。对三个新 Process 模块做类似的修改,并且把表示 Cell 2 和 Cell 4 的延时表达式 (Expression)改为 Process Time。回想一下,在 Sequences 模块中,我们是通过把零件在 相应站点上的加工时间赋给实体属性 Process Time 来定义 Cell2、3 和 4 上的加工时间的。 当零件送到这些单元中时,Arena 自动完成赋值,这样在模块中就可以使用了。

P295 输入界面 7-9 Cell 1 中的 Route 模块

此时,读者可能会觉得我们在 Cell 1 中用表达式来设置零件的加工时间,而在其他加 工单元中却通过在序列中给属性赋值的方式来定义加工时间, 具有很大的随意性。 实际上, 我们这么做主要是为了说明, 在仿真模型里有多种不同的方法可以组织和使用数据。 我们

可以很容易地就把 Cell 1 上的零件加工时间也通过加工序列来定义, 与其他的加工时间放 到一起。同样,我们也可以用表达式来定义 Cell 3 和 4 的加工时间。但是使用表达式来设 置 Cell 2 的加工时间是很困难的,因为零件 2 在 Cell 2 上加工了两次,而且两次加工时间 是不同的,如表 7-1 所示。因此,若采用表达式的话我们的模型就必须具备一种能力,即 它可以知道零件是第一次还是第二次经过 Cell 2,并且要使用不同的表达式来定义这两个 加工时间。这可能是一个有趣的练习,但是从建模者的观点来看,为什么我们不就在序列 中定义这些值呢?读者应该也意识到了, 从加工单元和工件的数量来说, 这个模型规模是 相当小的。在实际中,同时有 30 到 50 台机器、成百种不同类型的零件,这并没有什么稀 奇。 如果读者承担了一个那样规模的问题, 那么强烈建议你一定要非常重视数据结构的设 计,因为它将影响一个仿真项目的成败。 Cell 3 的 Process 模块略为有些不同,因为它有两台不同的机器,一台新的,一台旧 的,它们加工零件的效率是不同的。如果机器是相同的,那么就可以使用单一的资源,然 后把容量设为 2。我们应该还记得在前面将这两台机器组成了一个集合,叫做 Cell 3 Machines。现在需要在 Cell 3 中使用这个集合。输入界面 7-10 显示了这个单元的 Process 模块所要求的数据输入。

P296 输入界面 7-10 Cell 3 中的 Process 模块

在模块中的 Resource 部分,我们从资源类型(Resource Type)的下拉菜单中为其选 择为 Set(集合)类型。我们在 Set Name 栏选取我们前面定义过的 Cell 3 Machines 作为该 集合的名字,实体可以占用(Seize)某个集合成员(具体机器)加工,该成员的标识可 以作为属性赋给实体。最后,可以使用一个表达式来确定使用哪个资源。在“选择规则” (Selection Rule)处,接受默认的选择规则  Cyclical,也即实体将选择排在上一个刚被 使用的资源之后的第一个可用的资源。 在这个例子中, Arena 将尽量交替使用这两个资源; 但是如果当前只有一个资源可用的话,那么就选择这个可用资源。显然,这些规则只适用 于多个资源可供选择的情况。随机(Random)规则产生随机的选择;优先顺序(Preferred Order)规则将选择集合中第一个可用的资源。一旦选择了这个选项,则如果新机器可用 的话,Arena 将总是使用新机器,因为它在集合中是第一个资源。 “剩余” (Remaining)

规则只适用于资源容量大于 1 的情况。 借助 Save Attribute 选项,我们可以把所选定的集合资源的下标保存在某一属性中。 在这个例子中,将在属性 Machine Index 中保存这个下标值。如果选择了新机器,这个属 性将被赋值为 1,如果是旧机器,属性将会被赋值为 2。这些编号是按照定义集合时所输 入的资源的顺序而确定的(先输新机器、后输旧机器) 。使用属性 Process Time(在加工序 列中定义)乘以变量 Factor(Machine Index)来定义延时的 Expression 栏。别忘了 Cell 3 上的加工时间是针对旧机器的,而新机器的加工时间是这个值的 80%。在定义表达式时 要注意,如果选择了集合中的第一个资源(新机器) ,则 Machine Index 被赋值为 1,变量 Factor 将根据这个属性值取出其第一个元素 0.8。如果选择了集合中的第二个资源(旧机 器) ,则 Machine Index 被赋值为 2,变量 Factor 将取出其第二个元素 1.0。虽然以上方法 对于这个例子来说似乎有点过于复杂了,但它能充分表明了 Arena 的强大灵活性。还有一 种可用的方法,它不需要变量(Factor) ,而是直接使用下面的逻辑表达式: Process Time * (((Machine Index = = 1)*0.8) + (Machine Index = = 2)) 或 Process Time * (1 – ((Machine Index = = 1)*0.2)) 至于这个表达式是如何工作的, 我们将把它留给读者去思考。 (提示: 如果 a 等于 b , 则“a= =b”的值为 1,否则为 0) 。 在定义完所有的数据、 零件到达过程和四个加工单元之后, 就只剩下定义零件的离开 过程了。这可由如图 7-4 所示的两个模块实现。

P297 图 7-4 描述零件离开系统的逻辑模块

和以前一样,我们使用 Station 模块来定义 Exit System 站点的位置。用 Dispose 模块 清楚已完成加工的零件。完整的模型(不过动画部分还没完全加入)如图 7-5 所示。

P297 图 7-5 完整的模块 此时我们已经可以运行模型了, 但是想从中看出我们所定义的加工序列是否在正确工 作还是很困难的。所以在开始分析模型之前,应该先为模型建立动画,以帮助我们确定模 型是否在正确运行。而且,如果模型需要呈送给更高的管理层去看,那么我们也希望能开 发出很生动的动画画面。

7.1.5 动画
我们可以使用与第五章相同的方法来设计动画  创建自己的实体图形、资源图形、 和基于图 7-1 给出的图案的背景。 但也可能有人已经建立了能准确地反映该系统背景的图 形,比如说,有人曾用 CAD 系统画过相应的车间布局图。Arena 可以把 CAD 程序里的文 件集成到它自己的工作区里,例如由 AutoCAD 系统绘制的以 DXF 格式保存的文件就可 以直接导入到 Arena 里。其他由别的 CAD 或者画图程序(例如 Microsoft® Visio®)生成 的文件,只要支持 AutoCAD 的标准 DXF 格式,都可以导入 Arena。 如果原先的 CAD 图形是二维的,则只需要将其以 DXF 格式保存,然后再将文件直 接导入 Arena 即可。大多数 CAD 对象(如多边形等)在 Arena 中将以相同或相似的对象 来表征。如果图形是三维的,读者首先必须将其转换为二维。在转换过程中颜色可能会有 损失,但是在 AutoCAD 或是 Arena 中都可以再次添加颜色。这种转换会将对象转换成由 线条组成的图形,所以导入的图形在 Arena 中只能作为单个线条加以操作,也可以把这些 线条组合成一个对象。假设我们已经有了 DXF 文件,读者可以从“在线帮助”中查找创 建 DXF 文件或者转换一个三维图形的有关细节(Importing DXF Files 主题) 。注意,如果 当前的背景是白色的,而一个转换的文件往往又会以白线的形式导入 Arena,所以你可能 什么也没看见。此时读者可以简单地改变窗口的背景颜色(用 Draw 工具栏中的 钮) ,或者选定所有的线并改变线的颜色( 按钮) 。 按

对这个小型制造系统,我们将从三维图形着手,把它转化为以 DXF 格式保存的二维 图形文件(Model 07-01.DXF) 。通过 File>DXF Import 菜单命令可将 DXF 文件导入当前 的模型文件。首先选择这个文件,将鼠标指针移到模型窗口,此时指针变为十字形。用指 针画一个框,则整个图形就被导入到这个框里了。如果导入图形的尺寸不合适,读者还可

以选定全部的图形,重新按需要改变其大小。现在以这个图形为基础来制作动画。 制作动画时,先要去掉所有的字母和箭头。然后从 Process 模块 Cell 1 Process 处把 Cell 1 的队列动画元素移到所导入图形中相应的位置上。 现在把鼠标的指针置于一台机器的左上角, 拖动指针使边界包括整个机器图形。 使用 Copy 按钮将机器复制到剪贴板,现在点击 Animate 工具栏上的 Resource 按钮( )打

开“资源图形布局” (Resource Picture Placement)窗口。双击 Idle 资源符号并用剪贴板里 的图形取代当前的图案。清除机器的基座,在表示机器顶部的部分画两个方框。必须要这 么做, 因为原始图形是由线条组成的, 没法向其中填充颜色。 现在从原图中清除所有的线, 然后向方框中填充自己喜欢的颜色。 复制这个新的符号到你自己的图形库里, 然后再把它 复制为 Busy 图形。保存图形库,关掉资源窗口,最后把资源放置到相应位置。现在就得 到了所需的资源图案,稍后我们再回来增加更多的动画效果。 下一步,画一个大小尺寸与机器的基座相同的方框,然后清除机器的全部图案。用另 一种颜色填充这个新方框, 然后在方框的顶部放置一个刚才建好的资源符号 (读者可能需 要重新设置资源符号的尺寸) 。现在移动指针,使资源符号位于新机器的中央位置。再对 新资源符号和机器基座进行复制,并且改变它们的名字,用来表示其它加工单元。注意需 要把 Cell 3 和 4 的资源符号翻转一下。 最后还需要移动和重新设定其他队列的位置和大小。 一旦这些都完成了, 就可以运行 这个动画, 观察你自己的手艺了。 这时将看不到零件在系统里移动 (因为还没有设置路径) , 但是可以看到队列中和机器上零件的变化情况。 在动画运行中, 如果仔细观察其中的一台 机器,将会注意到零件被放置在这个机器的右上角加工,而并不是我们希望看到的情况。 理想的情况是,零件应位于机器顶部和基座之间。把这个表示出来并不难。选择一个资源 (可以在编辑模式下或是暂停运行来完成) ,然后利用 Arrange>Bring to Front 菜单或是 Arrange 工具栏上的按钮 动画来表示零件的移动。 在以前的动画中,基本上只有一条路径通过系统,所以增加路径是非常直观的。在这 个小型制造系统中, 有多重的路径经过系统, 所以必须仔细地为每一个可能的运送线路添 加路径。例如,一个零件离开 Cell 2 后可能去 Cell 1、3、或 4。首先要确定各站点的位置, 使用 Animate Transfer 工具栏中的 Station 按钮来添加站点动画对象。然后设置路径。如果 忽略了路径设置,仿真仍会用 2 分钟的运送时间将实体(正确地)送到相应的站点,但是 来加以实现。再次运行动画,将得到预期的效果。下面开始用

不会出现实体移动的动画画面。读者还需注意的是,路径是双向的。例如,假设从 Cell 1 到 Cell 2 添加了一条路径,但是忘记了设置从 Cell 2 到 Cell 1 的路径,那么当零件 3 完成 了它在 Cell 2 上的加工后,Arena 会按加工序列将它送往 Cell 1,但由于没有设置这样一 条路径,系统将会查找从 Cell 1 到 Cell 2 的路径并使用它。因此,画面上可以看到零件从 Cell 2 的入口以逆时针方向移动到 Cell 1 的出口(对于这个模型来说是一个错误的画面) 。 运行并观察新建的动画模型时, 读者可能会注意到偶尔零件会彼此超越或者经过, 这 是由动画驱动模式和有关的数据所造成的。 读者应该还记得所有的零件运送时间都是两分 钟,与运送的距离无关。而 Arena 是基于运送时间和动画中路线的长度来设定实体运送速 度的。在这个模型中,有些路线是非常短的(从 Cell 1 到 Cell 2) ,而另外一些却很长(从 Cell 2 到 Cell 1) 。因此,被运送的实体将会以不同的速度移动。如果这一点很重要的话, 需要搜集更好的运送时间,并表示在模型中。最简单的方法是清除 Variables 模块中的 Transfer Time,并且在 Sequence 模块中把这些新的运送时间赋给某一属性。如果运送时间 和背景图形都正确的话, 那么实体将以相同的速度移动。 现在唯一可能遇到的问题是当一 个零件进入主通道时另一个零件恰好在同一位置经过, 这就导致了两个零件会重叠在一起 移动,直到彼此的行进路线分开时为止。这是一个很难解决的问题,不过不值得为它而困 扰。如果仿真的主要目的是用于演示的话,那么通过观察动画,找出一段这种情况不会发 生的时间段,只演示这一段就可以了。一种解决的方法是使用物料搬运建模构件,这些内 容将在第八章中介绍。 给模型加上简单的注释之后,最终的动画演示看起来会像图 7-6 中那样(这是在系统 时间为 541.28 时的观察画面) 。在这个时刻,可以检查模型是否在正确地运行,或者至少 可以检查它是否在以我们希望的方式运行。我们将在下一节中继续讨论这个问题。

7.1.6 模型验证
模型验证(Verification)是确保 Arena 模型能根据建模假设以预期的方式加以运行的 过程。比起模型确认(validation)来,验证要容易得多,模型确认是确定模型是否与真实 的系统的运行规律一样。 我们将在第十三章中更加详细地讨论这两个方面的问题。 在这里 只是简单介绍模型验证的问题。 模型验证所处理的问题有时很明显,但有时也不那么明显。例如,如果试运行模型, Arena 报错, 指出没有定义 Cell 3 的一个机器资源, 这个模型显然没有按照预期情况运行。

实际上,我们一般把这个叫做调试(debugging)过程!不过,我们假设你不会出现那样 的问题(或者说如果出现了,你自己就可以很容易地加以纠正) ,所以我们这里所处理的 是是那些不太明显的问题。

P300 图 7-6 小型制造系统的动画画面:模型 7-1 当读者在建立象本书中的这种小型、 课堂练习类的问题时, 模型的验证是相当容易的。 当开发一个更接近实际规模的模型时, 读者会发现验证将是一个很艰难的过程, 并且对于 非常非常大的模型来说,是绝对无法做出 100%保证的。 一个简单的验证方法是让一个实体进入系统, 然后跟踪它, 以确定模型的逻辑和数据 是否正确。可以使用标准工具栏中的 Step 按钮( )来控制模型的执行,让实体一步一

步地通过系统。对于这个模型,也可以在 Create 模块中设定 Max Arrivals 域为 1。为了控 制实体类型,读者可以用你想要观察的那个零件类型来替代在 Assign 模块中用以确定零 件类型的离散分布。 这样读者就可以检查每个零件的加工序列。 另一种常见的方法是用常 量替换某些(或全部)模型数据。使用确定性的数据可以更加精确地预测系统的行为。 如果准备使用模型来做真正的决策,那么读者应该检查在极端情况下模型的运行情 况。例如,只引入一种零件类型、或者增加/减少零件的到达间隔或服务时间。如果模型 有问题,那么将最有可能在这种超负荷运行的情况下暴露出来。同样的,读者应该有效地 利用动画,你对所模拟系统的运作过程很熟悉,通过观察动画就能发现很多问题。 还有一种好方法是使用不同的数据做长时间的仿真运行, 通过观察输出报告中的结果 来找出可能存在的问题。此时一种很有用的方法是性能评估(performance estimation) 。在 计算器发明之前(当然也没有个人电脑) ,工程师总是带着一个叫做计算尺的工具(经常 由皮袋包着,挂在他们的腰带上) ,用来计算由专业人员或老板提出的复杂问题。这些装 置通过引入对数计算而产生了神奇的效果。 虽然它们能很好地计算一些问题 (当然不可能 像计算器那样简便和快捷) ,但是他们只是返回由单个数字组成的序列(实际上是从尺子 ,如 3642。由于工程师需要指出小数点的位置,所以他们在使用计算尺之前 上读出来的) 就需要能对问题的结果做个粗略的估计。例如,如果工程师估计结果可能是 400 左右,那 么计算尺显示的答案就是 364.2。不过,如果估计的结果是 900 的话,那就很难判断计算

尺上的答案到底是多少了(364.2 还是 3642?) 。此时,必需要首先确定是工程师的经验 估计出了问题, 还是在使用计算尺计算的过程中出了问题。 我们猜想读者现在可能会提出 两个问题:1)为什么要讲这个长长的不相关的故事;2)过去真的使用过这样的工具吗? 好的,答案是:1)是为了阐明观点,2)作者之一确实用过! 那么如何使用这种伟大的性能评估技能呢?可以为仿真定义一组条件, 然后估计会导 致什么样的结果, 然后运行仿真模型, 通过观察输出报告中的数据来确定你结果是否正确。 如果结果正确, 那么读者就可以愉快地再去尝试另一组不同的条件了。 如果结果是错误的 (或者至少不太对) ,则需要找出为什么。发生错误的原因可能是由于对结果的估计有问 题、缺乏对系统的理解、或者模型中有错误。有时候模型里一些没有料想到的交互作用可 能会产生很难发现(但却是存在)的问题。通常情况下,应当彻底地运行仿真模型,并且 保证在用它做决策之前所得到的结果是令人满意的。 最好是在项目的早期就开始做这种验 证工作,并且要经常做。 现在回到 2.7 节,当我们提到模型验证时,我们的建议是验证程序代码。估计现在读 者的反应会是“什么程序代码?” 。的确有程序代码,事实上在第五章中简单地展示了一 些代码。但是读者可能仍然会问, “为什么要使用代码”?解释这个原因需要一些背景知 识(另外一种历史课) 。在 1982 年,System Modeling 公司(原先开发 Arena 的公司)成 立,并开始发布仿真语言 SIMAN®(Arena 正是以它为基础开发的,并且读者可以通过 Arena 访问和使用 SIMAN) 。那时个人电脑刚刚开始进入市场, SIMAN 被设计成可以在 这些新型机器上运行的系统。事实上,SIMAN 只要求有 64Kb 的内存,但在当时这已经 是很大了。当时还没有动画能力(与 SIMAN 配合使用的动画工具 Cinema®是在 1985 年 才首次发布的) ,使用文本编辑器来创建模型,就像使用一般的程序设计语言一样。完整 的模型要求建立两个文件:一个模型文件,一个实验文件。其中,模型文件中包括所有的 模型逻辑,通常称为. mod 文件。而实验文件则定义了实验的条件,被称为. exp 文件,它 要求用户列出模型中用到的所有站点、属性、资源等。在建立这些模型或实验文件时,必 须遵从一种相当严格的语法。比如,只能在第 10 列才能开始写某些语句;有些部分后面 要跟逗号,有些跟分号或者句号;所有的资源和属性只能用数字来引用;只能使用有限的 一组关键词等(你的许多老师就是通过这种方法来学习仿真的) 。 从 1982 年起,SIMAN 一直在不断地改进,并且仍然是 Arena 仿真模型的重要基础。 当运行 Arena 仿真时,Arena 检查所用模块中的每个选项和用户提供的数据,然后创建 SIMAN 形式的 MOD 和 EXP 文件。这些是用于仿真运行的文件, “基本操作”面板、 “高

等操作”面板和“高等运送”面板中所有的模块都是以 SIMAN 仿真语言中的构件为基础 建立的。这么做的目的就是要利用功能强大而灵活的 SIMAN 语言去建立一个易于使用的 仿真工具(即 Arena) 。所以,在用 Arena 仿真建模时仍然可以察看 SIMAN 代码。事实上, 甚至可以生成和编辑这些文件,但只能从上向下(从 Arena 生成 SIMAN 代码) ,而不可 能从下向上(从 SIMAN 代码生成 Arena 模型) 。当对 Arena 更加精通以后,有时可以通 过察看代码来确定模型是否能准确地按照预期方式运行  这就是模型验证。 应当指出,在 Arena 中仍可使用基本的 SIMAN 语言来创建模型。如果只使用 Blocks 和 Elements 面板里的模块来构建模型的话,就相当于只使用基本的 SIMAN 语言。回想一 下,在之前的第 5 章构建库存模型时,就使用过一些 Blocks 面板中的模块。 可使用 Run>SIMAN>View 菜单选项来查看小型制造系统模型中的 SIMAN 代码。 选择 这个选项将会同时生成上述的两个文件,每一个都有单独的窗口。图 7-7 展示了一小部 分.mod 文件,它是 Cell 3 中 Process 模块部分的代码。SIMAN 语言具有相当强的描述性, 所以不难理解其表达的逻辑。实体到达模块时它内部的计数器会递增 1,然后实体进入队 列 Cell 3 Process.Queue,等待占用集合 Cell 3 Machines 中的资源,接下来生成由加工时间 所造成的延时(含调整因子) ,最后释放这些资源,内部计数器减 1,实体离开这个模块。

P303 图 7-7 Process 模块的 SIMAN 模型文件

图 7-8 显示的是.exp 文件中的一部分, 这个文件定义了在我们模型里所用的三个属性, 以及队列和资源。

P 303 图 7-8 Process 模块的 SIMAN 试验文件

这里不再深入解释文件的细节了, 我们这样做的目的仅仅是为了让读者知道它们的存 在。如果想更全面地了解,请参考 Pegden,Shannon,and Sadowski(1995)一书。 如果你对 SIMAN 比较熟悉,或者愿意更多地了解这些过程是如何进行的,建议你选

取一些模块并输入数据,再生成 MOD 和 EXP 文件。然后再编辑这些模块,在其中设置 不同的参数,再次生成新的文件。在两个 MOD 文件中寻找差别。这样读者就可以深入了 解这些过程是的如何运行的了。

7.2 稳态仿真输出的统计分析
第 6 章描述了终态和稳态仿真的不同, 并且指出了在终态仿真时如何使用 Arena 输出 报告、PAN 和输出分析器来做统计分析。在这部分将展示如何在稳态仿真下做统计推断。 在开始之前,我们鼓励读者一定要确认采用稳态仿真模式对所研究的问题是否合适。 常有人简单地认为, 一个长期运行的状态稳定的系统就要用稳态仿真来处理, 事实上这也 可能是正确的。但是,如果开始和结束的条件对模型来说非常重要的话,应用终态仿真分 析可能更合理。应当尽量避免使用稳态仿真模式做输出分析,这是因为虽然 Arena 能够 自动得出平均性能指标的 95%的置信区间,但要想获得此外的其它更多结果的话,稳态 仿真输出分析要比终态仿真难得多。所以如果不需要做稳态仿真的话,就尽量不要做。 在开始进行分析之前还有一点警告, 那就是稳态仿真的运行时间会很长。 因此, Arena 有更多的机会在排列其内部操作顺序时出现一些差异, 这将导致随机数流的使用上产生一 些差异(参见第 12 章) 。虽然这并不会使模型产生错误或变得不精确,但它还是会对数值 结果产生影响,特别是对那些在内部存在一些固有的统计可变性的模型。所以,当读者跟 着本书在自己的个人电脑上建立并运行模型时, 如果得到与本书不同的数值结果, 不要为 此惊慌,因为在某种意义上说这是意料之中的。对于这种情况,只是表明需要更多的仿真 输出数据统计分析工作而已, 因为这些变动因素不仅来自模型本身, 而且也来自内部处理 过程。 7.2.1 节中将讨论如何确定模型的预运行阶段(也可形象地称为“预热期” )和运行的 时间长度。7.2.2 节讨论了用于输出分析的“重复-删除”策略,这是到迄今最简单的方法 (并且在某些方面来说,也是最好的) 。在 7.2.3 节中将介绍另一种“批平均法” 。7.2.4 节 中给出简要总结,而 7.2.5 节中将介绍稳态分析中的一些其他问题。

7.2.1 预热期和运行长度
也许读者会注意到,我们的所有例子都有个特点,开始时系统都处于“空且闲”的状 态。这意味着开始时系统中没有实体,而且所有的资源都是空闲的。在终态系统中,实际

系统开始时可能就是这样的。 但在稳态仿真中, 我们要假设初始条件并不会影响系统性能, 并且假设系统是永远运行不停的。 在实际执行稳态仿真时, 不可避免地会有初始状态问题, 而且仿真过程也必须要在某 个时间点上终止。而且因为是第一次做稳态仿真,所以没有人知道系统“典型的”稳定状 态是什么样子,或者说运行多久才能进入稳定状态。因此可以多进行几次(长时间运行) 尝试,根据结果来做判断。如果系统的初始状态为空闲,而最终情况很拥挤,那么用所得 到的全部输出数据来估计系统性能时,将会得到比实际情况偏低的结果。 为了修正这一点, 读者可以试着取比空闲更好的初始状态。 这意味着在 0 时刻时模型 中放置一定数目的实体,并且以这种方式开始运行。虽然在模型中可以这样做,但却很不 方便。而且在 0 时刻究竟应该放置多少实体也很难确定。 另一种处理方法是运行这个模型足够长的时间, 初始阶段出现的偏差影响会被后面出 现的数据“淹没” 。这个方法在一些初始状态影响能很快消除的模型中是非常有效的。 事实上,稳态仿真模式下系统还是可以从“空且闲”状态开始,只不过需要让模型先 预运行一段时间,直到初始因素的影响已被消除。这时,清空统计累加器(注意保留系统 状态) ,重新开始收集此后的数据用于统计分析。很显然,采用这种方式不但得到一个非 “空且闲”的初始状态,而且可以由模型来决定开始(重新)观察性能指标时系统中应有 多少实体。虽然运行时间还是要求很长,但比上面的第二种策略所需时间要短得多。 很容易在 Arena 中指定一个初始预运行( “预热” )时间。打开 Run>Setup>Replication Parameters 对话框并在 Warm-up Period 处填一个值就行了 (但一定要注意所使用的时间单 位) 。模型的每一次重复运行仍然和以前一样,只不过在预热时间结束时清空所有的统计 累加器, 所以输出报告只反映在预热时间结束后发生的情况。 采用这种方法可以消除来自 初始状态的数据偏差。 一个困难的问题是不知道预热时间需要多长。 也许最实际的办法就是画出一些关键变 量随时间变化的散点图,然后观察系统在什么时候能达到稳定。为说明这一过程,取出 7.1 节中的模型 7-1,并且做如下的修改得到模型 7-2。  为了建立一个全局的性能指标,我们在 Statistics 模块中添加了一个变量用来统 计系统中三种零件总共的在制品(WIP)数量。变量名字和报告标签都是 Total WIP, 类型为 Time-Persistent。 为了输入随时间变化的表达式, 右键单击 Expression 区域,然后选择 Build Expression,单击树状目录 Basic Process Variables  Entity  Number in Process, 选择 Part 1 作为实体类型, 得到当前表达式 EntitiesWIP(Part

1),这是我们表达式中的一部分。然后键入一个“+” ,选择 Part 2 作为实体类 型;再键入另一个“+” ,选择 Part 3 作为实体类型。最后得到 EntitiesWIP(Part 1)+EntitiesWIP(Part 2)+EntitiseWIP(Part 3),这就是全部的 WIP。这将在 Category Overview 报告中的 User Specified 栏目下生成标号为 Total WIP 的平均 和最大在制品数目。  我们还想跟踪仿真过程中的 Total WIP 随时间变化曲线,而不仅仅是得到最后的 统计结果, 这是因为需要观察何时曲线趋于稳定, 从而可以确定一个合理的预热 期。和以前一样,我们可以在模型中放置一个散点图动画对象(Plot) ;但当按 下终止仿真按钮时,曲线就会消失,并且由于数值变动可能很大,使你无法有效 识别稳定点的位置。所以,我们需要保存曲线的所有历史记录,还要通过重复仿 真运行绘制多条曲线,以减少随机干扰。要做到这一点,需要在 Statistics 模块 中 Total WIP 条目下的 Output File 栏内输入文件名 Total WIP History.dat,它将保 存仿真过程中 WIP 变化的所有信息,仿真结束后,通过 Arena 输出分析器(见 6.4 节)可打开这个文件并绘制相应的散点图。文件的大小与模型运行的时间和 重复的次数有关, 由于要求它包含许多细节和运行中的信息, 文件有可能相当大 (运行上例生成的文件约为 176KB) Statistics 模块中 Total WIP 条目的输入见图 。 7-9。

P 306 图 7-9  Statistics 模块中完整的 Total WIP 条目

因为我们对这个例子的动画过程不感兴趣,所以可以通过 Run>Run Control 菜单 选择 Batch Run(没有动画)运行模式。也可以在 Run>Setup>Project Parameters 表页的 Statistics Collection 栏中清除所有的复选框,并清除在 Dispose 模块中的 Record Entity Statistics 选项,以加快速度。为了了解输出结果的变化情况,在 Run>Setup>Replication Parameters 中取重复运行的次数为 10。由于我们对长期 运行的稳态结果感兴趣,所以把重复运行时间长度从 32 个小时(1.33 天)增加 到 5 天。按以上设置,在一台主频为 2GHz 的笔记本电脑上的运行时间大约不到 2 秒。

现在在输出分析器中绘制 WIP 随时间变化的散点图(关于输出分析器的基本知识见 6.4 节) ,首先创建一个新的组群,并向其中添加文件 Total WIP History.dat。然后选择散点 图 (Plot) (按钮 选项 或菜单 Graph>Plot)加入.dat 文件 。 (在 Date File 对话框的 Replication

栏选择 All) ,在 Title 栏输入标题,然后在 Axis Label 栏加入对坐标轴的标号。结果如图 7-10 所示。

P 307 图 7-10 输出分析器的散点图对话框 图 7-11 显示了 10 次重复仿真运行得出的 WIP 散点图曲线。从图中可明显地看出, 对我们所关心的 WIP 来说,五天的运行长度(7200 分钟)已经足够了,并且显而易见, 模型中没有出现实体“爆炸”的情况,即由于加工速度跟不上零件的到达速度使得系统中 的零件数量极度膨胀。至于预热时间,可以看出“空且闲”的初始状态对于 WIP 前面几 百分钟的影响是很明显的,并且各次仿真的情况也比较相似,但在 2000 分钟后基本上就 开始稳定下来了。为保险起见,选择 2 天(2880 分钟)作为预热时间(Warm-up Period) 。

P 307 图 7-11 模型 7-2 的 WIP 散点图 如果仿真运行的时间长度更长、 或模型预热期相对较短的时候, 通过曲线的左边部分 来观察合理的预热期就比较困难了。这时,可以在散点图对话框的 “Display Time from… to…”栏中输入相应的显示范围来对图形作局部放大。 如果你对模型中的多个输出性能指标感兴趣, 就需要为每个输出性能指标绘制一张如 图 7-11 的散点图。对于不同的输出指标,它们需要的预热时间可能是不一样的,在这种 情况下,安全的做法是取它们的最大值作为总体的预热时间。

7.2.2 重复-删除法
如果可以确定预热期, 并且预热期相对仿真运行长度来说比较短, 那么稳态统计分析 是相当简单的:只需独立重复运行若干次即可,此时,除了在 Run > Setup > Replication Parameters 中对每次仿真运行指定一个预热期之外, 和第 6 章中终态仿真基本上是一样的。 统计分析过程也与第 6 章一样, 只不过由于增加了预热期, 所以得到的是稳态而不是终态 的结果。 这个方法适用于方案比较或备选方案选择(6.4 和 6.5 节) 、方案寻优(6.6 节) 、以及 单系统的输出分析。然而,由于不同的方案所需要的预热期和运行长度可能是不同的,而 在使用 OptQuest 寻优时你又无法控制这些参数(它们由 OptQuest 所控制) ,所以事先应 在一个较大的范围内尽可能对各种不同备选方案加以试运行, 从而找出各方案预热时间的 最大值作为模型参数。 对模型 7-2 做为期五天的重复运行, 我们通过 Run>Setup>Replication Parameters 输入 7.3.1 节所确定的 2 天的预热期,并设置重复运行 10 次。因为不再需要保存内部运行的历 史记录,所以我们在 Statistics 模块中清除 Output File 项,并且所得到的模型命名为模型 7-3。 这样就得到了 WIP 的一个期望均值为 16.39 的 95%置信区间[16.39-6.51, 16.39+6.51]。 而对没有设置预热期的模型 7-2, 我们得到的置信区间为[15.35-4.42,15.35+4.42],这表 明初始的空闲状态会使得输出性能指标偏低。 因为这些置信区间非常宽, 为了更清楚地看 到这个差异,我们做 100 次重复仿真运行(而不是 10) ,模型 7-3 得到的置信区间为 [15.45-1.18,15.45+1.18],而模型 7-2 得到的置信区间为[14.42-0.86,14.42+0.86]。注意 到我们采用了相同重复仿真次数,但模型 7-3 的置信区间要比模型 7-2 宽很多,这是因为 模型 7-3 的每次仿真运行只使用了最后三天的数据,而模型 7-2 的每次运行则使用了全部 五天的数据,因而模型 7-2 的结果具有较低的可变性。 更窄的置信区间意味着更高的精度,读者也可以通过增加重复仿真次数来提高精度。 不过另外一种选择是保持重复仿真次数不变, 而延长每次仿真运行的长度 (仍使用最初的 预热时间) 。用相同的仿真运行长度做更多次的重复仿真运行是最简单的,这实际上等价 于增加统计样本量。 需要注意的是, 通过保持重复运行次数不变而延长运行长度这一策略 来提高精度,并不是因为增加了统计样本量(即统计意义上的自由度) ,而是因为通过更 长时间的运行减少了每次运行得到的输出均值的可变性。而且,通过更长时间的运行,对 于用足够长的时间达到稳态来说就更有把握了。

如果可以近似地确定模型中的仿真运行长度和预热期, 并且预热期不是很长的话, 那 么重复-删除法是非常有吸引力的。与其他稳态分析策略相比,它非常简单,而且给出了 真正独立的观测值(每次删除初始状态后的重复仿真运行结果) ,对于统计分析而言这是 一个很大的优势。 它不仅适用于像刚才那样简单地确定置信区间, 而且对于备选方案的比 较和选择、以及其它一些统计目标来说也都适用。

7.2.3 批平均法
有些模型要花很长时间预热时间才能达到稳定状态, 所以 7.2.2 节中讲述的重复-删除 法的仿真运行策略会变得效率很低。在这种情况下,做单次长时间的运行可能会更好,这 样只需预热一次。修改模型 7-3,运行 50 天(其中 2 天为预热时间) ,得到模型 7-4。这 与做 10 次重复仿真运行、每次五天,有着相同的仿真效果,而且所耗费的计算时间也相 同。因为我们需要绘制 WIP 散点图,所以在 Statistics 数据模块的 Output File 栏输入一个 文件名:Total WIP History One Long Run.dat。图 7-12 给出了整个运行中的 WIP 图。 (先 不要理会图中的垂直粗线条。 )

P 309 图 7-12 在 50 天的单个运行中的总的 WIP 现在的困难是如何用一次仿真运行的结果来对各性能指标做分析, 而且也不清楚该如 何计算方差的估计值, 而方差对于作出统计推断是必需的。 如果把运行中的每个单独的观 测值或者时间持续量的统计值作为一个独立的样本点,那倒是可以计算出一个样本方差, 但这样做是非常危险的, 因为一次仿真运行中各观测点之间可能存在很强的相关性 (参看 附录 C 2.4 节) ,这将导致这个估计值严重偏离了观测值的真实方差。因此,我们必须考 虑到相关性问题。实际上,可以设法在单次长时间仿真运行的结果中“造”出一些独立的 观测值,这样我们就可以得到一个合适的方差估计了。 有几种不同的方法可用来对单次长时间仿真运行进行统计分析。 一个相对简单的方法 是尝试把运行结果分为一些较大的“批” (batches) ,每个批包含许多单个的观测点,可以 把一个批看作一个样本点,这样就造出了一些“几乎不相关”的观测值。接下来计算在每

一个批中观测点的平均值(称作批平均值) ,然后把它们当作独立同分布的观测值,这样 就可以做统计分析了(从估计方差开始) 。这就意味着用这些批平均值取代了重复-删除策 略中从每次重复仿真运行中得到的均值。在图 7-12 中,垂直粗线条表明了批的选取,对 分隔线之间的区域里的 WIP 观测值取平均(批平均) ,这些批平均值即为用于统计分析的 基本数据。为了得到方差的无偏估计,我们需要保证批平均值之间是近似不相关的,这就 是为什么我们要求每一个批次都包含较多的观测点; 另外, 虽然在相邻批边界附近的观测 点之间仍会有较大的相关性,但这些点相对于批次容量来说毕竟是少数,所以可以预计, 只要批量足够大,批平均值之间是几乎不相关的。实际运行中,Arena 会尽可能让批量足 够大,以保证批均值之间不相关。不难理解,如果单次仿真运行时间太短,所得到的批平 均值就可能相关(从统计检验的意义上来看) ,在这种情况下,必须要延长运行时间。 前面曾提过, Arena 自动使用批平均值法 “试图” 为所有统计输出的均值构建一个 95% 置信度的置信区间,并且在仿真输出报告中 Average 栏旁边的 Half Width(半长)一栏给 出置信区间的半长。如果只有一次重复运行,那得到的就是批平均值法的置信区间。另一 方 面 , 如 果 做 了 多 次 重 复 仿 真 运 行 , 则 将 在 重 复 仿 真 运 行 分 类 报 告 ( Category by Replications) 中看到每一次重复仿真运行下得到的结果; 而此时在分类汇总报告 (Category Overview)中的置信区间半长,则是根据每一次重复运行得到的均值结果构造出来的(见 6.3 节和 7.2.2 节) 。前面强调“试图构建” ,是因为在对输出统计量构建有效的批平均值置 信区间时, 系统内部会自动检查你的重复运行时间是否足够长, 只有足够长才能以足够的 数据来构建这样的一个区间。 如果数据不够的话, 你只能得到一条相关的信息, 而得不到该统计量的区间半长值 (这 是因为 Arena 认为错误的回答比完全没有回答还糟糕) 。如果读者指定了预热时间,那么 置信区间计算中就不会使用这个时段内的数据。 为了理解这个过程是如何起作用的, 可以 认为 Arena 不断地在尝试建立有效的置信区间(也就是说,随着仿真的运行,不断地把观 测到的输出数据分配到不同的批次里) 。 “足够的数据” 是什么意思呢?这里需要通过两个层次的检验, 而第一层检验是最基 本的,对于计数型(Tally)统计量来说,Arena 最少需要 320 个观测值。而对于时间持续 型(Time-persistent)的统计量,至少需要有 5 个单位的仿真时间,并且在这期间内离散 变量至少改变了 320 次。不可否认,这些值和条件好像有点随意,但这只是初步的检验, 通过后还要进行更具有权威性的统计检验。 如果运行时间不足以满足第一层检验, 输出报 告中变量的“置信区间半长” (Half Width)一栏将显示“Insufficient” 。只要重复运行足够

长的时间,就可以产生足够的数据以满足这个最基本的要求。 如果数据足够多可以通过第一层次检查,Arena 就把每个计数型或时间持续型统计量 采集的数据分成 20 批。 对计数型统计量来说意味着每批有 16 个连续的观测值; 而对于时 间持续型统计量则表示每批有 0.25 个单位的仿真时间。当仿真继续运行,新收集到的数 据累积达到一个批次的数量时,就作为第 21 个批次。继续仿真,将会得到第 22、23 个批 次等等,直到达到第 40 个批次。此时,Arena 会把批次 1 和批次 2 合并为一个新的(更 大的)批次,作为新的批次 1;批次 3 和批次 4 合并,作为新的批次 2,等等。这样又得 到新的 20 个批次,但是新的批量是原先的两倍。随着仿真过程的进行,Arena 又将继续 得到新的批次 21、22 等(按新的批量) ,直到再次形成 40 个批次,然后再次重新合并为 20 个新批次。所以,批次的数量会保持在 20 到 39 个;若最后一批数据达不到所规定的 批量大小,则将被舍弃。之所以选择“不断重新分批以得到大容量的批次”这一方法,是 基于 Schmeise(1982)的研究,他分析认为,若采用固定批量,而利用收集到的新数据 来不断增加批次的数量(而不增加每批的批量) ,除了能够降低置信区间的半长外,并没 有其他的优势; 而大容量的批次本身就具有较小的方差, 也具有降低置信区间半长的能力。 另一方面,如果每个批次的批量太小的话,即使有很多的批次,这也是很危险的,因为所 得到的批平均值之间很可能会相关,从而得到一个不可靠的置信区间。 第二层检验是看批量是否足够大到能够使批平均值之间满足独立性假设。Arena 所采 用的是 Fishman(1978)建立的统计假设检验方法。如果通过这个检验的话,输出报告中 将给出变量的置信区间半长;否则,在相应位置给出“Correlated”信息  表示因为输 出结果中存在过高的自相关性, 所以按当前的运行时间长度不可能得到近似不相关的批平 均值。此时,也可通过延长运行时间来解决这个问题,但根据具体问题情况,有时可能需 要延长很长一段时间。 回到模型 7-4,运行 50 天后,清除作为预热期的最初两天的统计数据,Arena 在分类 汇总报告中为 WIP 的期望均值建立了一个置信度为 95%的置信区间 13.6394  1.38366。 在大多数情况下, 自动得出的批平均值置信区间对于我们理解所得到的均值有多精确 已是足够的了,并且相当容易获得(读者自己根本不需要工作,Arena 会自动给出这个区 间) 。但是读者应该明白,首先,不要忘记这种方法只能用在稳态仿真输出分析中;如果 是终态仿真(见第 6 章) ,读者应该忽略这些自动生成的批平均值置信区间,而是做独立 的重复仿真运行,并对仿真做统计分析。其次,需要注意模型的预热期,如果不指定一个 预热期的话, 自动生成的批平均值置信区间将不会对初始状态带来的偏差加以修正。 最后,

读者可以通过计数型统计量 THALF(Tally ID)和时间持续型统计量(也被记作 Dstat) DHALF(Dstat ID)的值在仿真运行过程中来检查自动生成的批平均置信区间半长;之所 以对此感兴趣,是因为读者可以利用这些函数在 Simulate 模块中的 Terminating Condition 栏中设置仿真终止准则,更多的相关内容请参见 12.5 节。 应该提及的是,如果读者真的想要自己设置批次的话,也可以自己设定批量,并计算 和保存批平均值, 然后在统计分析中使用它们, 如建立置信区间或在两个可行方案中做出 选择(参见章节 6.3 和 6.4) 。自己确定批次时,先要保存运行中观察到的历史数据,其方 法与前面为绘制预热期散点图而收集数据的过程一样, 然后在输出分析器中打开所生成的 数据文件,使用 Analyze>Batch/Truncate 菜单命令来建立批平均值,然后再利用这些批平 均值来建立置信区间,正如我们在 6.3 和 6.4 节所做的那样。在建立批平均值时,输出分 析器会对所得到的批平均值进行相关性检验,如果批量太小的话 Arena 会给出相应的信 息。使用输出分析器的好处是我们可以获得置信度不是 95%时的统计分析结果,也可以 更有效地利用数据并减少最后的浪费,还可以在稳态情况下对两个备选方案进行统计比 较。

7.2.4 如何选择分析策略?
我们已经讲过如何使用不同的方法来解决同一问题, 并提到还有更多的方法。 那么到 底应该使用哪一种方法呢?与通常一样,没有一个显而易见的答案(我们曾告戒过,稳态 输出分析一般会比较困难) 。有时候需要在结果的科学性和概念的简化(及实用性)之间 加以权衡,这就是我们所面临的情况。 在我们看来,可以参照以下基本原则(按优先性递减排列) 1. 尽量避免做稳态仿真,让自己(或是资助人)确信,系统具有特定的初始状态 和结束条件这一建模假设是合理的。请参考第六章(这里就不再重复了) 。 2. 如果模型的预热期很短,那么可能最简单和最直接的方法是采用重复-删除运 行策略。它很容易实现(只要通过绘制散点图确定了合理的预热期) ,除了增 加预热期之外, 重复-删除法的统计分析过程和终态仿真的分析过程是一样的。 此外,读者还可以使用 PAN 和 OptQuest 中更加复杂强大的分析能力。 3. 如果发现模型预热得太慢, 则可以考虑批平均值法。 这种方法采用单次长时间 仿真运行,所以只需要做一次预热。读者可以接受 Arena 自动生成的批平均值

置信区间,也可以自己计算。但是,读者不能在 PAN 或者 OptQuest 的统计方 法中使用批平均值法。

7.2.5 稳态统计分析的其他方法和目标
我们已经介绍了进行稳态统计分析的两种不同策略(重复-删除法和批平均值法) ,在 Arena 中这两种方法都是可用的。很多研究人员越来越关注这个领域,提出了许多不同的 策略来解决这些问题:如经济计量时间序列建模,源于电子工程领域的谱分析法,源于随 机过程的再生模型,标准化时间序列,以及从批平均值法中衍生出来的一些方法(如可分 或加权批平均值法)等。如果对这些方法感兴趣的话,可以参阅 Law and Kelton(2000) 一书的第九章, Sargent,Kang,and Goldsoam(1992)的评述文章,或者查阅最近的冬 季仿真会议论文集(Proceedings of the Winter Simulation Conference) ,在论文集中会包含 关于这个主题最新进展的分析、评论和论文。

7.3 小结
现在, 读者应该已具备较强的能力来实现非常细致的模型了, 并且对模型确认和稳态 统计分析等问题有了较深的理解(也知道该怎么去处理这些问题了) 。接下来的一章中, 将向读者介绍如何模拟复杂的物料搬运系统。 后面的章节将更深入地探讨 Arena 的建模和 分析能力,并显示它强大而灵活的层次结构。

7.4 练习
7-1 在练习 4-7 中,是否需要运用批平均值法来生成平均系统逗留时间的稳态置信区间? 为什么? 7-2 修改练习 5-2 的方案,加入零件运送时间,包括从进入系统到机器 1、所有机器之间、 以及最后从机器 1 到退出系统。所有的零件运送时间为 UNIF(1.5,3.2) 。在零件传输过 程中加入动画,并让零件离开机器 2 时改变零件图形。运行 20000 分钟。尽可能多地为各 种稳态性能指标建立批平均值置信区间。 7-3 使用练习 7-2 的模型, 把工件第二次通过机器 1 的加工时间改为 TRIA (6.7, 13.6) 9.1, , 使用加工序列来控制实体通过系统的路线并为每台机器上加工时间赋值。运行仿真 20000

分钟。用批平均值法建立稳态性能指标的置信区间。 7-4 一个系统含有三个站点(A、B 和 C) ,每个站点有一台机器。零件到达间隔为 10 分 钟,第一个零件在时刻 0 到达。有四种类型的零件混合在一起进入系统,每种零件到达的 可能性相同。四种零件的工艺计划如下表所示。加工时间服从三角分布,参数如下(单位 为分钟) 。 零件类型 零件 1 零件 2 零件 3 零件 4 站点/加工时间 A 5.5,9.5,13.5 A 8.9,13.5,18.1 A 8.4,12,15.6 B 9.2,12.6,16.0 站点/加工时间 C 8.5,14.1,19.7 B 9,15,21 B 5.3,9.5,13.7 C 8.6,11.4,14.2 C 4.3,8.5,12.7 站点/加工时间

假设零件从进入系统到第一个站点之间、 在所有站点之间、 以及最后一个站点到离开 系统之间的运送时间均为 3 分钟。 使用加工序列控制零件通过系统, 并为每个站点的加工 时间赋值。使用集合形式来收集零件的系统逗留时间(按各零件类型分别收集) 。用动画 形式模拟模型的运行过程(包括零件传输) ,运行仿真 10000 分钟。 7-5 修改练习 7-4 的方案, 使用表达式来表示加工时间 (而不是在 Sequence 模块中赋值) 。 运行 10000 分钟, 并将结果与 7-4 的结果进行比较。 结果有什么不同吗?如果是, 为什么? 7-6 修改练习 7-5 的方案,让所有的零件以相同的顺序通过系统:站点 A站点 B站点 C。如果一个零件不需在某个站点加工,它也必须进入该站点的队列中等待,只不过它的 加工时间是 0。将这个结果与练习 7-4 和 7-5 得到的方案加以比较。 7-7 三种类型的旅客到达一个小型机场:需要检查行李(30%) ,先买票再登机(15%) , 和仅携带手提行李(55%) 。所有旅客的到达间隔时间分布是 EXPO(1.3) ,单位为分钟, 第一个旅客在时刻 0 到达。 需要检查行李的旅客先到行李检查柜台接受检查, 检查时间分 布为 TRIA(2,4,5) ,然后接受 X 射线检查,再进入登机口。先买票再登机的旅客先到 售票柜台买票,时间分布是 EXPO(7) ,接下来接受 X 射线检查,然后进入进入登机口。 仅携带手提行李的旅客直接去 X 射线检查处接受检查,然后前往登机手续柜台领取登机 牌,登机手续的时间分布为 TRIA(1,1.5,3) 。所有三个柜台一直开放,每处有一个工 作人员服务。X 射线检查的时间分布是 EXPO(1) 。携带手提行李的旅客前往 X 射线处的 行进时间分布是 EXPO(3),所有其它行进时间分布均为 EXPO(2)。运行模型 920 分钟,统

计资源利用率、 队长和所有旅客从进入机场直到登机口的系统逗留时间 (所有类型的旅客 混在一起统计) 。 7-8 零件以均值为 10 分钟的指数分布到达一个由四台机器构成的系统。这四台机器各不 相同,且每种一台。有五种类型的零件,到达率和工艺计划如下表所示。加工时间服从三 角分布(单位为分钟) 。 零件类型 1 2 3 4 5 % 12 14 31 24 19 机器/加工时间 1 10.5,11.9,13.2 1 7.3,8.6,10.1 2 8.7,9.9,12 3 7.9,9.4,10.9 2 5.6,7.1,8.8 机器/加工时间 2 7.1,8.5,9.8 3 5.4,7.2,11.3 4 8.6,10.3,12.8 4 7.6,8.9,10.3 1 8.1,9.4,11.7 机器/加工时间 3 6.7,8.8,10.1 2 9.6,11.4,15.3 1 10.3,12.4,14.8 3 6.5,8.3,9.7 4 9.1,10.7,12.8 3 8.4,9.7,11 2 6.7,7.8,9.4 机器/加工时间 4 6,8.9,10.3

零件从进入系统到第一台机器之间、 在所有的机器之间、 以及从最后一台机器到离开 系统之间的运送时间满足以 8,10,12 为参数的三角分布(单位为分钟) 。统计系统逗留 时间与机器利用率。用动画模拟加工过程(包括零件传输) ,并运行仿真 10000 分钟。如 果运行时间足够长,用批平均值法建立稳态输出结果期望值的置信区间。 7-9 修改练习 7-8 的方案,使它包括不同的运送时间。运送时间的三角分布参数如下表所 示(单位为分钟) 。比较所得的结果。这一比较在统计上可靠吗? 从 / 往 进入系统 机器 1 机器 2 机器 3 机器 4 11,13,17 8,10,15 9,13,20 10,13,21 机器 1 7,11,19 机器 2 7,11,16 9,13,20 机器 3 8,12,19 10,13,18 7,12,18 7,9,13 7,9,12 9,14,21 8,9,14 6,8,11 6,10,12 机器 4 离开系统

7-10 修改练习 4-21 的方案,使用加工序列来控制零件通过系统(提示:重新设置 Entity.Jobstep 或 IS 的值) 。 7-11 修改模型 7-1,假设已有的三种零件是由一个客户提供的,现又有一个新的客户,这 个新的客户将提供两种新的零件类型  类型 4 和类型 5。到达过程是另外加进来的,与 原来三种零件的到达无关。达到间隔时间服从均值为 15 分钟的指数分布,第一个零件在 0 时刻到达。到达的新零件中,40%为类型 4,其余为类型 5。下表为两种新零件的工艺

计划和平均加工时间(单位为分钟) 。 零件类型 4 5 加工单元/ 平均加工时间 1 6.1 2 3.5 加工单元/ 平均加工时间 3 5.2 3 4.1 加工单元/ 平均加工时间 2 1.3 4 3.2 加工单元/ 平均加工时间 4 2.4 1 2.0

人们只对加工时间的平均值有个较好的估计, 但不太清楚它们的分布, 所以只好假设 每种情况的分布为均值加/减 0.2 分钟的均匀分布。例如,如果均值为 6.1,则假设分布为 从 5.9 到 6.3 的均匀分布。对模型做必要的修改,包括模块、动画(对新的零件类型创建 新的实体图形) 、以及其它需要变动的地方。要保证动画合理(如要求所有实体和新零件 都按顺时针方向运动) 。 (a) 很显然,与原来的系统相比,增加新客户后将使系统变得更拥堵。用四个队 列的平均队长作为评价指标,看看与原先的系统相比会变得多糟糕。每个方 案都只做一次运行。 (b) 为了尽量减小由增加新客户带来的拥堵,现准备买一台新机器安装在 Cell 1、 2 或者 4(注意不装在 Cell 3) 。参照四个队列的平均队长,你觉得应把它安 装在哪里呢?假设新机器的工作速度与其所加入的那个加工单元的原有机器 相同。你可以参照 6.5 节定义自己的输出统计量,以使用 PAN 来加以分析。 把这个问题视作终态仿真,重复仿真运行 50 次,从而确定新机器安装在哪里 最合适(做方案比较时,要包括没有新机器时的情形) 。 7-12 修改练习 5-2 的方案,使用 Sequence 模块控制实体通过系统的顺序。假设零件从进 入系统到第一台机器、 在两台机器之间、 从最后一台机器到离开系统的运送时间均服从三 角分布(参数为 7,9,14;单位为分钟) 。视此问题为终态仿真,对新模型与练习 5-2 的 模型各重复运行 10 次, 使用 PAN 比较两个模型得到的平均系统逗留时间和各队的平均队 长。 7-13 修改练习 7-12 的方案,假设在零件回到第一台机器上做最后一次加工时,加工时间 增加 20%。视此问题为终态仿真,对新模型与练习 7-12 的模型各重复运行 50 次,使用 PAN 比较两个模型得到的平均系统逗留时间和各队的平均队长。

第8章

实体运送

到目前为止, 我们已经介绍了两种不同的引导实体通过模型的方式。 一种方式是直接连 接(Connections) ,实体可以在模块之间移动而不需要运送时间。另一种方式是通过定义运 送路径(Routing)在站与站之间输送实体,这种运送方式需要有运送时间。在这两种方式 里,对实体的运送没有任何约束,在运输路径上有足够的空间来容纳同时想要运送的实体。 当然,事情并不会总是如此的完美。运输路径上能同时运送的实体数量毕竟是有限的, 例如对一个通讯系统来说, 实体就是信息包, 而有限的带宽只允许同时传递一定数量的信息 包。在有些情况下,可能需要利用一些叉车或者工人抓起实体然后把它送走;在另外一些情 况下,实体必须通过输送机运走。我们将在本章中探讨这些问题。已有研究表明,运作过程 中的延误与低效率现象在很大程度上是由物料运送过程引起的, 所以精确地模拟实体的运送 过程往往是很重要的。 本章的 8.1 节将详细讨论不同类型的实体运输和输送, 以及怎样来模拟它们。 8.2 节, 在 将简要地说明怎样使用已有的 Arena 建模工具来限定同时运动的实体的数目 (虽然不需额外 的运送工具) 。而运送装置(如叉车、手推车、当然还有人)将在 8.3 节加以讨论。对不同 类型的输送设施的模拟将在 8.4 节进行描述。 在读完本章后, 读者就能够模拟各种各样的实体运动与运送了, 这将使我们的模型更加 有效,动画更加真切。

8.1 实体运送的类型
在模块间运送实体时,我们最初使用的是连接(Connect)类型(见第 3 章) ,目的是在 模块之间无时间延迟地直接运送实体。在第 4 章,我们介绍了路径(Route)的概念,它使 得实体在站与站之间按规定路线进行运送, 并且有运送时间发生。 我们首先介绍了怎样用路 径来把实体运送到一个指定的站, 然后我们在第 7 章利用序列 (Sequence) 拓展了这一概念。 虽然我们已经可以模拟大多数场景了, 但有时候我们发现有必要限定在某一时间内某一 点产生的运送事件的数量。例如,在模拟一个通讯网络时,链路的容量是有限的。因此,我 们必须设法限定同时传输的信息的数量 (这些信息将通过每一条链路或者整个网络来传递) 。 解决的方法相当简单, 我们把网络的链路看作是容量有限的资源, 它的容量等于允许同时传

递的信息包数量。 如果信息量是按信息包的大小来计算的话, 我们就可以用基本信息包的数 量来定义资源的容量, 并且要求每个信息在开始运送之前占用它需要的资源的数量 (用基本 信息包的个数来表示) 我们把这种类型的实体运送方式叫做资源约束 。 (resource constrained) 类型,并且我们将在 8.2 节对它做更详细的讨论。 对一个通讯网络来说, 用资源容量来限定同时运送的实体数量是很合适的, 但对另一类 我们称之为物料搬运(material-handling)的实体运送方式来说就不适用了。不同的物料搬 运系统,建模需求有很大差异,而且不同的物料搬运设施种类也非常多。事实上,有一整本 手册专门探讨这个问题(见 Kulwiec 1985) 。不过,从建模需求的角度大体上可以把这些设 施分为两个大类。  第一类是用物料搬运设施的可用数量来限定同时运送的实体数量。这一类型的物料 搬运设施有运货车(carts) 、手推车(hand trucks) 、叉车(fork trucks) 、自动导引车 (AGVs)和搬运人员等。对这类设施,需要规定一些具体位置。如果一个实体需要 被运送,首先必须把搬运设施移动到该实体所在的位置,然后才能开始运送实体。 从建模的角度看, 读者可以认为这些设施是一些可移动的资源 (moveable resources) , 在 Arena 里被称为运输设备(Transporters) 。  第二类是利用可用的空间来限定运送的能力。虽然这也是为了限定在两个站点之间 同时运送的实体的数量,但是这种限制主要源于有限的空间。这一类型的物料搬运 设施包括各种输送设备(conveyors) 、吊链运输设备(overhead trolleys) 、悬挂输送 系统 (power-and-free systems) 这种类型的搬运设施大家比较熟悉的是自动扶梯。 等。 如果有实体需要运送,我们必须首先确定在搬运设施相应的位置上有足够的摆放空 间,然后才能开始运送。显然,对这些设施的建模方法是不一样的,在 Arena 中称 之为输送设备(conveyors) 。 利用 Arena 中的运输设备和输送设备,我们能够很容易地模拟几乎所有的物料搬运系 统。但是,仍然有一些物料搬运设施因其独特的特征对建模提出了挑战,例如龙门起重机或 者桥式起重机。 利用运输设备不难模拟一台起重机。 但是如果在一个轨道上有多台起重机的 话, 那么如何控制起重机的移动将是精确模拟这些设施工作的关键。 而几乎所有的实际系统 都包含有多台起重机, 这些起重机都由坐在驾驶室里的操作员来控制, 这些操作员能够互相 看到对方,相互交谈,而且他们的决策可能是无法预计的。在这样的情况下,对起重机建模 并不困难;困难之处在于怎样结合人的思维逻辑来避免起重机发生碰撞或者拥堵。 如上,我们定义了三种实体运送类型:资源约束、运输设备、输送设备。我们将首先在

8.2 节简要讨论资源约束型的实体运送,然后在 8.3 节和 8.4 节以第 7 章的小型制造系统 (Model 7-1)为例,介绍运输设备和输送设备。

8.2 模型 8-1:运送资源约束下的小型制造系统
在原来的小型制造系统模型里(模型 7-1) ,我们假设所有的运送时间都是 2 分钟。但 是如果这些运送时间依赖于物料搬运设施, 那么在系统运作期间实际的运送时间将可能存在 很大的差异。正因为如此,早期的模型虽然能够对系统的加工能力给出一个合适的估计值, 但却不能对零件的完工周期加以精确估计。 要解决这个问题, 最简单的方法就是在运送过程 中引入资源约束。我们假设系统的运送能力为 2,并且每一次运送的时间都是 2 分钟,也就 是说系统最多可以同时运送两个零件, 如果其他的零件已经完成了加工, 但是由于运送资源 有限,它们必须要等到一个运送资源空闲后才能被运送。 很容易在模型里加入资源约束来限定同时搬运的实体个数。 我们只需要在系统中定义一 种新的运送资源, 当实体离开一个站点之前占用一个单位的运送资源, 然后在达到下一个站 点后释放该资源就可以了。虽然这也是一种普通的 Arena 资源,但在模拟运输工具时还是有 所不同的。 有两种不同的方法把运送逻辑加入到已有的模型中。 最简单的方法 (至少是对我们而 言)是在每一个已有的 Route 模块(当前模型里共有 5 个)前面插入一个 “占用” (Seize) 模块(该模块位于“高等操作” (Advanced Process)面板中) 。在每一个 Seize 模块中会请求 一个单位的运送资源(如 Transfer) 。此外,我们还需在 Resource 数据模块中把这项新资源 的容量改为 2。当读者在进行修改的时候,可能会考虑一个问题:每一个 Seize 模块应该有 一个独立的队列吗?如果对所有新插入的 Seize 模块都共用同一个共享队列,那么资源就必 须按照“先进先出” (FIFO)的规则加以分配;如果对每一个 Seize 模块都各有一个队列, 那么就可以采用实体优先级来进行分配。 例如, 读者可以给最新到达系统的实体指定最高优 先级, 这就能够使最新到达的实体尽可能早地被送去进行第一道加工, 读者可能会认为这样 的处理方式能够降低零件的系统逗留时间 (但如果多花一些时间考虑这个问题的话, 就会发 现这并不正确) 。如果所有的优先级都是相同的,那么其结果与共享队列的“先进先出”规 则效果一样。 不过这两种方法还是有差异的, 如果读者准备在动画里显示零件的等待过程的 话,使用各自独立队列的方法更加便利。 零件被运送到目的地后必须释放所占用的资源,我们可以通过在模型的每一个 Station

模块的后面插入一个 Release 模块来实现(其中唯一例外的是 Order Release Station,它仅仅 用来告诉 Arena 零件进入系统时的位置) 。 第二种方法是用 Leave 模块(该模块位于“高等操作”面板中)替换 Route 模块,并且 用 Enter 模块(位于“高等操作”面板中)替换 Station 模块。Leave 模块可用来占用运送资 源并运送实体。类似地,Enter 模块组合了 Station 模块和 Release 模块的功能。本模型中我 们将选择第二种方法, 因为这样可以介绍两个新模块, 并且易于把模型修改为使用其它运送 手段的模型。 利用 Leave 模块,实体在离开站点之前可占用一个运送资源,这个被占用的资源可以被 定义为一种指定的资源、一个资源集合、一个集合里的某个成员、或者是由一个表达式表示 的资源。 在有多个实体等待运送时, 读者也可以在 Leave 模块的 Logic 部分指定一个优先级, 以决定哪一个实体将被优先分配运送资源。优先权数值越小,优先级越高。在模块中,需要 选择 Seize Resource 选项,并输入运送资源的名称,以及相应的路径信息。 输入界面 8-1 描述了如何用 Leave 模块替换名为 Start Sequence 的 Route 模块。我们使 用相同的模块名字 Start sequence,在 Logic 部分的 Transfer Out 栏选择 Seize Resource 选项, 并在 Resource Name 处输入 transfer。最后我们在 Connect Type 栏选择 Route,在 Move Time 栏输入变量 Transfer Time,选择单位(Units)为分钟(Minutes) ,并在 Station Type 栏选择 Sequence,其它选项采用缺省值。应注意到,在这里为等待运送资源的零件设定了一个单独 的队列。 还应该注意到的是, Transfer Out 处选择了 Seize Resource 后, 在 一个队列名为 Start Sequence.Queue 的队列就出现在了模块的上面。这时,读者可以把这个队列移到所希望的位 置上。 接下来用 Leave 模块来替换剩下的四个 Route 模块,除了名字之外(我们使用 Route 模 块原来的名字) ,各输入对话框里的数据与输入界面 8-1 中一样。

原书 325 页 输入界面 8-1 定义运送资源的 Leave 模块

Enter 模块用于释放运送资源,并提供了卸载延时的选项。输入界面 8-2 描述了如何用 Enter 模块替换名为 Cell 1 Station 的 Station 模块。 首先删除现有的 Station 模块, 并加入新的

Enter 模块。我们将使用 Station 模块相同的名字,Cell 1 Station,并从 Station Name 的下拉 菜单中选择 Cell 1。在 Logic 部分,唯一要做的是在 Transfer In 栏选择 Release Resource,并 在 Resource Name(被释放的资源的名字)处输入 Transfer(必须与 Leave 模块中的资源名 称相同) 。 接下来用 Enter 模块替换剩下的四个 Station 模块 (但不包括 Order Release Station 模块) , 与前面的一样,除了名字之外(我们使用 Station 模块原来的名字) ,各输入对话框里的数据 与输入界面 8-2 中一样。

原书 326 页 输入界面 8-2 定义运送资源的 Enter 模块

把新得到的等待运送资源的队列移到动画部分后, 基本上就可以运行模型了。 在运行这 个模型之前别忘了还要定义运送资源的容量, 这个容量决定了在模型里能够同时运送的实体 的数量。Arena 默认的资源容量是 1,所以必须做相应的修改。打开 Resource 数据模块(在 “基本操作”面板里) ,把 Transfer 资源的容量(Capacity)改为 2。因为我们是一对一地替 换原来模型中的模块,并使用了相同的名字,所以最后得到的模型与模型 7-1 看起来是一样 的。在新的模型里,我们使用一样的动画画面,只是增加了 5 个新的等待运送的队列,这些 队列的位置如图 8-1 所示。

原书 326 页 图 8-1 修改后的小型制造系统动画部分 当读者运行这个模型并观察动画时, 很快就会发现很少有实体在等待运送。 如果读者对 模型的正确性存在疑问的话, 可以修改运送资源的容量为 1 并再观察动画。 如果读者把这个 ,就会发现 模型的结果与模型 7-1 的结果相比较(也可以与有 2 个运送资源的模型相比较) 由于在队列里等待运送资源需要耗费一定的时间, 零件在系统里的逗留时间会略有增加。 根 据零件类型的不同,这个增加量在 3 到 5 分钟之间。

8.3

使用运输设备的小型制造系统
现在我们假设所有物料都必须用各种运输设备来搬运,如运货车、手推车、叉车等(把

它们统称为运货车) 。进一步假设系统中有两辆运货车,无论是满载还是空车,每辆车的行 进速度都为 50 英尺/分钟,并且每辆车每次只能运送一个零件,装载和卸载的时间均为 0.25 分钟。把运货车加入系统之后,我们还需定义两个站点之间的距离。 Arena 里有两种运输设备:自由路径运输设备和导引运输设备。自由路径运输设备 (Free-Path Transporters)在系统里能够自由地移动,不会因为拥塞而停滞不前,从一个地 方移动到另一个地方的时间取决于运输设备的速度和两点间的距离。导引运输设备(Guided Transporters)将严格按照预先确定好的路线移动(典型设备如有轨车辆) ,这种设备行进的 时间取决于行进的速度、 行走的路线以及沿着这条路线的堵塞情况。 最常见的导引运输设备 是自动导引小车(AGV) 。在我们系统里的运货车属于自由路径运输设备。 使用运输设备搬运零件需要完成三个活动: 请求 (Request) 运输设备、 运送 (Transport) 零件、释放(Free)运输设备。请求运送活动(Request)与占用资源类似,就是请求为实体 分配一台可用的运输设备, 如果设备不在实体所在的位置的话, 就将设备移到该实体所在的 位置。运送活动(Transport)就是让设备把实体搬运到其目标位置,这与 Route 的功能类似, 不过在这里是实体与设备一起移动。释放活动(Free)就是使设备空闲,这与释放资源的活 动很像。 如果系统里存在多台运输设备,那么我们将面临如下两个问题。首先,我们在运行模型 时可能会碰到这样一种情况: 一个实体需要一台搬运设备, 但是系统里同时有多台可用的设 备。在这种情况下,需要利用运输工具选择规则来选定一台设备。在在大多数仿真系统里, 常使用最小距离准则(Smallest Distance) ,即将距离当前请求运送的实体最近的设备分配给 它。还有其他一些准则,包括“最大距离规则” (Largest Distance) (恐怕需要好好动动脑筋 才能想出什么情况下才会用到这一准则) 。第二个问题是当一台运输设备卸载完时,有多个 实体请求运送,这时应将运输设备分配给哪个实体。在这种情况下,Arena 应用实体优先级 来分配运输设备, 优先把设备分配给等待运送的实体中优先级最高 (优先权数最小) 的那个。 如果最高优先级的实体多于一个,则设备将分配给离它最近的那个实体。

8.3.1

模型 8-2:在模型 8-1 中引入运输设备

在小型制造系统模型里加入运货车之前,我们先对运货车进行定义,这可通过“高等运

送” (Advanced Transfer)面板中的 Transporter 数据模块完成。如果读者在跟着我们一起构 建模型,建议你们先复制模型 8-1,然后在这个复制品上开始建模。这样的话,我们就只需 输入运输设备的名称(Name) 、容量(Capacity,运货车的数量)和速度(Velocity)即可(参 见输入界面 8-3) 。利用“高等运送”面板中的模块定义的运输设备为自由路径设备,我们 将接受一些系统的缺省值, 包括距离集合 (Distance Set) 的名称 (后面我们将讨论这个概念) 、 时间单位(Unit) 、运货车的初始位置(Initial Positions)以及统计报告(Report Statistics) 等等。

原书 328 页 输入界面 8-3 Transporter 数据模块

我们在定义速度时, 需要注意输入的数字要与当前模型里所用的时间与距离的单位相一 致。缺省的时间单位是分钟,这与前面我们表示速度时所用的单位一致,但是我们需要确定 所用的距离单位为英尺(feet) 。 在定义了运输设备之后, 我们现在可以设计表示运货车的图形, 这与绘制一个实体或者 资源的方式是一样的。首先在 Animate Transfer 工具栏上点击 transfer 按钮( )打开“运

输工具图形布局” (Transporter Picture Placement) 用一个白色矩形图 窗口 , (长宽各为 5-point 宽度的直线)替换原来缺省的图形,并且当运货车空闲的时候,矩形边线为绿色,忙的时候 矩形边线为蓝色。当运货车正在运送零件的时候,Arena 需要知道把零件放在运货车的什么 位置上,这与资源图形上的占用点(seize point)很类似。对于运输工具,我们称这个点为 骑点(ride point) ,在编辑“忙态”图形时,可以在 Arena 图形编辑窗口下的 Object 菜单里 找到有关命令, 选择 object > ride point 后鼠标指针会变成一个十字交叉线, 移动这个指针到 运货车图形的中心位置然后单击鼠标, 骑点就会以图标⊕显示在运货车 “忙态” 图形的中心, 而且在动画过程中实体将被放置在运货车图形的这个位置上。 读者编辑完图形之后, “运 关闭 输工具图形布局” 窗口就接受了所做的修改。 然后把已经变为十字交叉线的鼠标指针移动到 动画部分的某个地方单击, 就把运货车图形放置到模型窗口里了。 读者并不需要担心放置运 输工具图形的位置是否合适, 因为它在模型窗口里的位置仅仅是为了稍后重新编辑它时方便 找到。在运行期间,这个图形将被隐藏,它在动画里的出现位置将另加定义。

原书 329 页 输入界面 8-4 定义运输设备的 Leave 模块

为了在模型逻辑中表示对运货车的请求, 我们将使用与前面表示运送资源占用功能相同 的模块  Leave 模块,输入界面 8-4 展示的是名为 Start Sequence 的 Leave 模块,除了名称 之外,其他的 Leave 模块所输入的内容都是一样的。为了处理装载活动消耗的时间,我们在 Delay 选项下输入 0.25 分钟作为装载延时, 并且在 Transfer Out 栏的下拉菜单中选择 Request Transporter 选项。当多余一辆运货车处于空闲状态时,Selection Rule 栏中的选项将决定哪 一辆运货车被分配给等待运送的实体,这些规则包括:循坏规则(Cyclic) 、随机规则 (Random) 、优先顺序规则(Preferred Order) 、最大距离规则(Largest Distance) 、以及最小 距离规则(Smallest Distance) 。循环规则将尽量交替使用运输设备,从而使它们的利用率保 持平衡。 优先顺序规则总是会选择按序号排在最前面的可用运输设备。 在这里我们选择的是 最小距离规则,按照这个规则,将把离请求运送的实体最近的运输设备分配给它。在 Save Attribute 栏还定义了一个新的属性 Cart #,其作用是把所分配的运货车的编号保存在实体属 性中(后面将详细讨论) 。在 Connect Type 栏中选择 transport 选项。需要注意的是,当读者 选定这一选项后,原先的 Move Time 栏就消失了,此时的行进时间将通过行进的距离和车 辆行进速度自动计算出来。 Leave 模块完成如下四个活动:分配运输工具、把空闲的运输工具移到请求运送的实体 处、产生装载延时、把实体运送到目标位置。Arena 还有其它方式来模拟这些活动,例如, 可以把 Request-Delay-Transport 模块结合起来实现这些活动。Request 模块(位于“高等运 送”面板)实现前两个活动;Delay 模块实现装载活动;Transport 模块(位于“高等运送” 面板)实现最后一项活动。虽然这需要三个模块,但这样可以增强建模的灵活性。可以对运 输设备的空驶移动过程和装载后的运送过程定义不同的行进速度, 事实上, 可以把行进速度 表示为包含某个实体属性的表达式(例如零件的重量) 。还可以用 Process 模块来替换 Delay 模块,不过这样的话就需要一个操作员或者物料搬运员(也用资源来模拟)来装载零件。最 后,还可以用 Allocate-Move 模块的组合替换掉 Request 模块。Allocate 模块(位于“高等运 送”面板)的作用是分配运输设备,而 Move 模块(位于“高等运送”面板)的作用是把空 闲的运输设备移动到请求运送的零件所在的位置。此外,如果要更精确地模拟系统行为,还

可以在这两个活动之间插入其它的逻辑。 当零件到达目的位置时, 需要释放运货车以使其能够再去运送其他零件。 要释放运货车, 我们可使用与前面模型中用来释放资源的相同模块  Enter 模块。 输入界面 8-5 展示了 Cell 1 station 里的 Enter 模块。除了名称之外,其它 Enter 模块的输入数据都是一样的。以分钟 为单位输入卸载时间延时,并且在 Transfer In 栏下选择 free transporter 选项。同样在 Transporter Name 一栏输入 Cart, 并且在用于存储运货车编号的实体属性栏目 (Unit Number) 下输入 Cart #。其实我们可以不给最后这两栏输入数据,这时 Arena 会自动跟踪哪辆运货车 被分配给了实体,并且释放那辆运货车。但是如果读者输入了 Transport Name,并且系统里 存在多个运输设备的话,那么读者就必须输入 Unit Number。加入只输入了 Transport Name 而没有输入 Unit Number,Arena 将总是试图释放第一个运输设备。

原书 331 页 输入界面 8-5 定义运输设备的 Enter 模块

和 Leave 模块一样,Enter 模块也完成了多个活动:定义站点、产生卸载延时、释放运 输设备。同样,Arena 也有其他方式来实现这些功能,我们可以用 Station-Delay-Free 模块组 合实现相同的功能。Station 模块完成站点的定义;Delay 模块完成了卸载延时活动;而 Free 模块(位于“高等运送”面板)则释放运输设备。如果有进一步要求的话,还可以在这三个 模块间插入附加的逻辑过程或用别的模块替换。 例如, 可以用一个 Process 模块来替换 Delay 模块,不过这样的话需要一个操作员或者物料搬运工(用资源来模拟)来卸载零件。 到目前为止, 我们已经定义好了运货车, 而且按照利用运输设备在系统中运送零件的要 求,将原逻辑过程修改为“请求运货车、运送和释放运货车”的过程。实际的行进时间取决 于我们在定义运货车时所输入的速度和运送的距离。在我们定义运货车的时候(输入界面 8-3) ,我们接受了一个缺省的距离集(Distance Set) ,其(缺省的)名称是 Cart.Distance 。 我们现在需要提供这些距离值。 首先, 我们先考虑在没有运输设备的情况下零件从一个站点 移动到下一个站点的距离值(参见表 7-1) ,表 8-1 给出了这些信息。表中包括一些站点或位 置之间的距离 (单位为英尺) 例如, 。 第一行第一列的数据项表示从 Order release 站点到 Cell 1 站点的距离为 37 英尺。而表 8-1 中的空白栏则表示该点对之间没有运送发生发生(参见 表 7-1) 。

表 8-1 零件运送距离 目的地 Cell 1 Order release Cell 1 Cell 2 Cell 3 Cell 4 37 139 92 Cell 2 74 45 Cell 3 92 55 Cell 4 Exit system

出 发 地

147 55

155 118

可以利用“高等运送”面板里的“距离” (Distance) 数据模块定义距离值,以上 11 个距离值的输入如输入界面 8-6 所示。实际上读者只需要键入相应的距离值即可,因为其前 面两列可以从列表中选出。读者应该也注意到了,行进的方向已经隐含在以上数据中,例如 输入界面 8-6 的第一行表示的就是从 Order Release 出发到 Cell 1。与应用 Route 模块的情况 一样,如果从 Cell 1 到 Order release 的距离或路线与从 Order release 到 Cell 1 不一样的话, 我们也需要对其加以定义 (不过在这个模型里没有实体按照这个路线行进, 所以这是不需要 的) 。

原书 332 页 输入界面 8-6 零件运送距离的定义

接下来看看与这些距离相关的动画组件, 虽然已经定义好了运输设备图形, 但是还需要 在动画里加入距离元素才行。 如果读者一直跟着本书一起构建这个模型的话, 那么在加入距 离之前,可先删除动画部分所有的路线轨迹(注意别把站点符号给删了) 。可应用 Animate Transfer 工具栏里的 Distance 按钮( )添加距离轨迹。单击这个按钮,按照表 8-1 加入

相应数量的距离动画元素。在运送零件的时候,动画里的运货车(以及车上的零件)将沿着 这些距离路线行进。在读者单击 Distance 按钮以后,会出现一个如输入界面 8-7 所示的对话 框,可以在其中定义距离路线的属性。在这个例子中,当运货车和其运载的零件沿着路线行 进的时候,我们并不要求对它们的图形加以旋转(Rotate)或者翻转(Flip) ,因为它们的图 形都是正方形的或者圆形的,而且为了易于辨识,我们还在零件上标出了编号。 加入 11 个距离动画元素,读者可以激活 View 工具栏里的 Grid 和 Snap 命令,以便借助 网格来使距离图形的绘制比较容易。我们建议读者按照距离值出现在 Distance 数据模块电

子表格里的顺序来加入这些距离元素, 这样做将可以避免产生混淆并减少遗漏的可能性。 如 果读者发现距离元素出现的位置不合适,那很容易修改它们。点击并选中距离路线,在这个 过程中要着重注意鼠标指针的形状。 当选中某条路线的时候, 在该路线上将会出现一些小方 块(转折点) ;当读者直接把鼠标指针移动到某个转折点上的时候,鼠标指针将会变成十字; 此时单击并按住鼠标左键不放可以拖动该点。 如果指针处于箭头形状的时候单击并按住了某 条路线不放,那么该条线上所有的点将会一起移动。如果读者碰巧作了这个动作,别忘了可 以用 Undo 按钮来撤销。如果读者觉得需要增加或减少距离路线上的转折点数量,可以双击 该距离路线,打开对话框,然后改变点的个数(# Points) 。当读者增加或者减少距离线上的 点的时候,它们总是在连接目标站点的最后一段线上增加或者减少。 如果读者现在运行模型并观察动画的话,就会看到运输设备在系统中运送零件的过程, 但是一旦运输设备被释放,它就会从动画里消失,直到下次开始运送时才出现。这是因为我 们没有告诉 Arena 当运输工具空闲的时候它们应该停在哪里,这很容易修改,只须在动画部 分加入停车位置就可以了。在 Animate Transfer 工具栏里点击 Parking 按钮( ) ,打开如

输入界面 8-8 所示的“停车区” (Parking Area)对话框,接受对话框输入数据后,指针变为 十字形状,把鼠标移到动画部分的站点符号左下角附近,然后单击;此时,当读者移动鼠标 的时候, 会看到一条线从该工作站伸出并连接到鼠标所在的位置上, 如果没有看到上述现象, 则继续在站点符号左下角附近点击鼠标,直到成功为止。现在,把鼠标指针移到读者想要表 示停车位置的地方,单击一次;再继续移动鼠标到第二个运货车停泊的地方,双击;此时完 成泊位定义, 鼠标指针将恢复到正常的箭头状态。 如果读者感觉所创建的泊位太多 (或太少) , 可以双击相应的停车区, 重新打开停车区对话框。 用对话框中的 Points 按钮来增加或减少泊 位的数量。在我们的模型里,同一时刻同一位置最多可能停泊两辆空闲的运货车,所以我们 需要两个泊位。对每一个站点重复上面的操作,即可完成停车区的定义。

原书 334 页 输入界面 8-8 “停车区” (Parking Area)对话框

Order release 和 Cell 1 站点的最终定位描述情况如图 8-2 所示。

原书 334 页 图 8-2 距离与泊车动画对象

现在可以运行模型并观看动画了, 但是如果读者此时就运行话, 那么运行一会儿就会暂 停,并弹出 Arena 的“错误/警告”窗口。屏幕上的警告信息会告诉读者有一对工作站之间 的距离没有指定,这就迫使 Arena 假定其距离为 0,并提醒读者加以确认(Arena 会对读者 忘记输入的值给出一个轻率的假设值) 。读者可以关闭这个窗口,继续运行,不过这个警告 信息还会再次弹出。之所以出现这个问题,是因为当运货车停在 Exit System、Cell3、或者 Cell 4 的时候, Order Release 站点发出了运送请求, 在 而我们又没有定义从这些站点到 Order release 的距离。 事实上, 还存在更多的类似问题, 当运货车在 Cell 1 或者 Cell 2 站点被释放, 而运送请求又发生在 Order release 站点的时候, 运货车将不是按照我们希望的依顺时针方向 行进,而是逆时针回到 Order release 站点。为了避免这一现象,我们必须为所有可能发生的 装载或空闲的运送过程定义距离。 一般来说,如果有 n 个位置,那么就有 n(n-1)个可能的距离。读者可以把它看成一 个对角线上元素为 0 的 nn 的矩阵, 这个矩阵假设任意两个站点之间的移动都是可能的, 并 且任意两个站点之间的距离值还可能与行进的方向有关。例如我们有六个位置,则有 30 个 可能的距离值(在本章的模型里,两点间的距离在不同行进方向上确实不同) 。如果距离与 行进方向无关的话,距离值的个数将减少一半。还应注意到,有一些站点之间的行驶是不可 能出现的,例如(空的)运货车有可能被请求从 Exit system 处移动到 Order Release 处(装 载新到的零件) ,但是决不可能有相反方向的运动发生(请思考这个结论!。表 8-1 的数据 ) 仅仅是为了装载零件的运货车而设定的, 如果我们考虑到所有可能的空车行驶情况, 就可以 得到表 8-2 所示的完整的距离值。表中加阴影的值是来自于表 8-1。加入空车行驶情况后, 共计有 25 种可能的运动。 表 8-2 运货车的各种可能运动距离值(包括空运行驶) 目的地 Order release 出 发 地 Order release Cell1 Cell2 Cell3 Cell4 155 118 71 34 Cell 1 37 139 92 55 Cell 2 74 45 129 92 92 55 139 129 147 45 45 Cell 3 Cell 4 Exit system

155 118

Exit system

100

121

158

37

74

如果距离的数量太多时, 我们建议考虑改用导引运输工具, 这种工具将使用运送网络而 不是一对一对的运送距离。有关导引运输工具的概念和使用,读者可以参阅第 9 章内容,以 及 Pegden,Shannon,and Sadpwski(1995)一书中的“先进制造特征”部分。 虽然最后的模型动画部分与我们最初的动画部分看起来很像, 但当模型运行的时候, 读 者会看到运货车不断地运动, 而零件也随着运货车一起移动。 有时可能会看到两辆运货车叠 在一起, 这是因为我们使用的是自由路径运输工具的缘故, 不过比起前面使用资源约束的模 型来说,出现这种现象的可能性要低得多。运行时间约为 643 时的动画画面如图 8-3 所示。

原书 336 页 图 8-3 带有运输设备的小型制造系统

8.3.2

模型 8-3:运输工具动画的改进

当运行模型并仔细观察动画时, 你可能会经注意到当零件在等待运货车搬运时, 有时会 突然看不见了。不过这仅仅是暂时的,因为运货车过来装载以后,零件又会突然出现在运货 车上。看到这一现象后,那么读者可能会对模型的正确性产生疑问。模型实际上正精确的, 以上现象仅仅是由于动画中的缺陷所造成的。 当一个新零件到达时, 或者零件在工作单元里 完成了其加工过程后,它就会进入一个请求队列,等待轮到它被运送。一旦一辆运货车被分 配给实体,在这辆运货车移动到该实体所在位置期间,该实体就不再呆在请求队列里了(我 们就不必深究实体所在位置的细节了)用动画来模拟这一活动的最简单的方法就是使用 , “暂 存处” (Storage)功能。定义了 Storage 后,当实体在等待运输工具到达它所在位置时,动 画中就会显示它正处于“暂存处”中。实体每进入暂存处一次,暂存处变量就加 1,而当实 体离开暂存处时,暂存处变量就减 1。所以我们也可以统计暂存处中实体个数的信息。 不幸的是, Storage 不能用于 “高等运送” 面板中的模块。 但是, 如果使用 “操作块”Blocks) ( 面板里的模块, 那么就可以使用 Storage 功能了 (不过对 Blocks 面板或 Elements 面板里的模 块来说,是无法使用电子数据表格视图的) 。我们将简要介绍对模型的必要改变。先把模型 8-2 另存为模型 8-3。要做的第一件事就是从模型里删除全部的五个 Leave 模块,并用如图

8-4 所示的 Queue-Request-Delay-Transport 模块组合来替代(图 8-4 所示的模块组所替换的 是名为 Start Sequence 的 Leave 模块) 。这四个模块均位于 Blocks 面板(后面将称 Blocks 面 板中的模块为操作块) 。

原书 336 页 图 8-4 Queue-Request-Delay-Transport 操作块组合

下一步需要选择 Queue 数据模块( “基本操作”面板) ,并且在零件等待运货车的地方 加入如下五个队列: Start Sequence.Queue, Route from Cell 1.Queue, Route from Cell 2.Queue, Route from Cell 3.Queue,和 Route from Cell 4.Queue。这时,读者也许会想到,我们应该已 经添加过这些队列了!一点也没错,但是它们是添加在我们刚刚删除掉的 Leave 模块里的。 添加完毕后,需要在 Storage 数据模块( “高等操作”面板)里添加十个暂存处,如输入界 面 8-9 所示。

原书 337 页 输入界面 8-9 Storage 数据模块

删除 leave 模块不仅丢失了相应的队列,也丢失了属性 Cart #的定义,所以我们需要在 名为 Assign Part Type and Sequence 的 Assign 模块中重新定义。这个附加的赋值如输入界面 8-10 所示。我们仅仅是用这个 Assign 模块来定义一个属性,至于所赋的值是没有什么意义 的。我们也可以使用“构模元素”面板(Elements panel)里的 Attributes 模块来添加这个属 性。

原书 337 页 输入界面 8-10 定义 Cart #属性

最后,我们来编辑图 8-4 所示的四个模块的组合。我们将只展示零件到达系统位置的数 据输入情况,然后其余四个加工单元的输入值就由读者自己解决了。从 Queue 数据模块开 始,如输入界面 8-11 所示,我们只需要输入队列的名字即可。这是一个零件等待所分配的 运货车到来的队列。假如我们没有设置这样一个队列,Arena 将会使用一个内部的队列来保 存正在等待运送的实体。 这样做虽然并不影响模型的准确性, 但我们在动画里就看不到这条 队列了,而且也不能统计在此等待运送的零件的数量。

原书 337 页 输入界面 8-11 定义 Start Sequence.Queue 的 Queue 数据模块

在 Queue 操作块后面的是 Request 操作块。这个模块的作用是为实体分配空闲的运货 车,然后把它移动到零件所在的位置。这个模块还允许我们指定一个暂存处,这样在运货车 移动到发出请求的零件所在位置的期间, 动画将显示这一零件被存放在该暂存处中。 Storage ID 和 Entity Location 的输入项可以在输入界面 8-12 中的下拉列表中选择, Transporter Unit 而 的输入值则需要加以进一步的说明。 首先, 读者也许已经注意到了那个选项框是以阴影来显 示的,这表明这是个必须输入数据项的区域。可以用三种不同形式来指定运输工具。第一种 形式是 Transporter ID (Number),其中 Transporter ID 是运输工具的名字,本例中就是 Cart。 其中的数字是所请求的运输工具的单元编号。在我们的例子里,有两个运货车,所以单元编 号可能是 1 或者 2。因此,如果选择这种形式的话,实际上就是在请求一个指定的运货车。 如果遗漏掉了这个数字,则 Arena 会默认它为 1。第二种形式是 Transporter ID(TSR) ,其 中 TSR 是一个运输工具的选择规则,在我们的例子里选择的是最短距离规则,即 SDS (Smallest Distance to Station 的简称) 当使用 Request 操作块时, 。 必须使用 Arena 所指定的 名称来定义这些规则。 最后一种形式是 Transporter ID (TSR , Attribute ID) 其中 Attribute ID , 是某个属性的名称,该属性是 Arena 用来储存被选中的运输工具的编号的。在本例中,这个 属性为 Cart #。因此,我们的输入值为 Cart(SDS,Cart # ) 。

原书 338 页 输入界面 8-12 Request 操作块(Request Block)

当运货车到达被搬运实体所在站点时, 零件将离开 Request 操作模块进入 Delay 操作块。 在操作块中,设定装载延时为 0.25,在 Storage ID 处输入 Order Release Pickup,如输入界面 8-13 所示。在修改动画时我们将讨论为什么还要加入这个暂存处。

原书 339 页 输入界面 8-13 Delay 操作块(Delay Block)

零件被装上运货车后, 将被送往随后的 Transport 操作块。 在该操作块中, Transporter 在 Unit 栏中输入正被使用的运货车 Cart Cart #) 并且在 Destination 栏输入 SEQ (这是 Arena ( , 的里对 Sequence 的专用缩写) ,如输入界面 8-14 所示。在这个例子中,我们将特意地跟踪 所分配的运货车,这样才能够确保到达目的地后释放正确的运货车。 对于其它几组操作块,除了 Entity Location 和 Storage ID 的输入值外(针对具体站点位 置而定) ,其余的输入值与上述一组操作块的输入值均相同。 下面修改动画部分。首先,读者可查看一下你们模型里的等待队列是否不见了(在我们 的模型里是这样的) ,这是因为它们是已删除的 Leave 模块的一部分。在原来的动画里,我 们当时是把与 Leave 模块相关联的队列移到了动画部分的适当位置上。 假如读者当时是使用 Animate Transfer 工具条里的 Queue 按钮( )添加的队列,那么它们仍应该在那里。如

果不是,那么就继续用 Queue 按钮来添加这五个等待队列。

原书 340 页 输入界面 8-14 Transport 操作块 )

现在需要添加十个暂存处, 我们可使用 Animate Transfer 工具条上的 Storage 按钮 (

来添加。 当在动画部分放置等待队列时, 要注意在装载点和队列之间留出适当的空间来放置 “装载暂存处” (pickup storage) 。每个要装载的地方需要两个位置,因为最多会有两辆运货 车同时来到同一个装载处。 我们把装载暂存处直接放置在停车泊位上, 这个位置是运货车装 载零件时停留的地方。 尽管在同一时刻同一位置可能有两个零件被装载上车, 但是在装载位 置上我们仍然只用一个装载暂存处。 如果这种情况发生的话, 第二辆运货车和零件将会被放 在在第一辆的上面。如果读者想确切了解我们是如何做的,建议读者看看模型 8-3。如果读 者运行你所建立的(或者我们的)仿真模型,将会发现零件最初是在等待队列中的;一旦某 个运货车可用且被分派给该零件, 这个零件的图形将移入装载暂存处, 直到运货车抵达所在 站点。然后,零件出现在运货车上,直到装载延时完成后与运货车一起离开。 有一个更简单的动画创建方法可以使零件在运货车移动和延时活动期间不会消失。 也即 使用 Store-Request-Delay-Unstore-Transport 的模块组合来替换 Leave 模块。其中 Request 和 Transport 模块来自“高等运送”面板;而 Store 和 Unstore 模块来自“高等操作”面板,使 用这两个模块可以增加或减少暂存处中的实体数。 如果读者使用这个方法, 就不必再为等待 队列创建动画, 所有的零件都将被放置在一个暂存处中, 在这个暂存处里等待被分配运货车、 等待运货车开到零件所在位置、以及完成装载零件的延时。我们不再讲述具体细节,读者可 随意尝试。 在运行模型之前,读者应该使用 Run > Setup 菜单命令选中 Transporter 选项(在 Project Parameters 表页中的 Statistics Collection 部分) ,以收集运输工具的统计信息。如果读者观察 动画, 会很少看到有一队零件在等待运货车, 所以将不容易看出这个运行过程与原来的运行 过程(模型 8-1)之间有什么任何重大的差别。这是因为只有 60%的运行时间里在使用运货 车。另外,我们也要告戒读者不要轻易地认定这两个系统没有什么显著差异,因为运行时间 相对较短,我们可能还处在启动过程中的过渡状态(如果我们对稳态性能感兴趣的话) ,更 不用说还存在统计意义上的随机波动对比较结果的影响。 如果把运货车的速度改为 25(原来速度的一半) ,再运行模型,我们将会看到在两次运 行结果之间并没有重大的差异。仔细思考一下,确实是这样。每辆运货车运动的平均距离不 到 100 英尺,而且运货车越忙,其空车行进的可能性越小(有时称为空返) 。如果一个运货 车被释放时,同时有几个请求,此时运货车将会运送离它最近的零件。所以零件的平均运送 时间仅约 2 分钟。加之装载和卸载时间保持不变,仍为 0.25 分钟,所以最后结果的差异并 不显著。我们建议读者通过改变运货车的速度、装载和卸载的时间、运货车的选择规则以及 运货车的数量来对这个模型继续做实验,以观察系统性能指标会有什么变化。当然,读者应

该做适当次数的重复仿真运行,以进行正确的统计比较(如第 6 章所描述的那样) 。

8.4

输送设备

前面介绍了如何模拟各种运输设备(如各种运货车辆) ,本节将介绍如何在系统中引入 输送设备(如各种输送机等)来搬运物料。假设我们要模拟一个环形回路的输送系统,它按 照零件的工艺路线摆放,并依顺时针方向运送物料。系统中包含六个站点(包括进入系统与 离开系统站点,以及四个加工单元) ,在每个站点所在位置都有一个输送设备的入口点和出 口点。输送设备将以每分钟 20 英尺的速度移动,输送的距离以英尺为单位,如图 8-5 所示。 同样地,我们假设装载和卸载活动需耗时 0.25 分钟。我们进一步假设零件为每边长 4 英尺 的方形物体, 在输送时需要 6 英尺的输送设备空间, 以便留出在拐角处所需的空隙并避免可 能的碰损。 在 Arena 对输送设备的定义里,直到输送设备上有足够的空间经过等待运送的实体时, 该实体才能登上输送设备。Arena 的输送设备是由许多不断移动的等长的单元所组成的。当 一个实体试图登上输送设备时, 它必须要等到输送设备上有一定数量的连续空单元经过它所 在的位置才行。为便于理解,我们还可以想想机场中的旅客自动扶梯,每一个阶梯就对应一 个输送单元,而不同的人可能需要不同的阶梯数量。例如,一个带有几个包的旅行者可能需 要两到三个阶梯的位置, 而一个没有带包的人可能只需要一个阶梯的位置。 当读者观察自动 扶梯的时候,会发现运输单元(每级阶梯)的大小是很明显的。但如果使用带式输送机或者 辊筒式输送机的话,每个单元的尺寸就不那么明显了。

原书 342 页 图 8-5 输送设备的长度 为了尽可能灵活地模拟输送设备,Arena 允许用户定义输送单元的尺寸,也就是说,把 输送设备的长度分为一系列连续的、等长的单元,每一个单元容纳不多于一个实体。这里有 个权衡问题,一方面,希望单元尽可能小以获得最大的模拟精度,另一方面希望单元尽量大 以获得高的计算效率。我们将以一个简单的例子来说明这个困难的抉择,假设有一个 100 英尺长的输送机, 我们想要输送的零件有 2 英尺长。 读者的第一反应可能是把单元大小设为

1 英尺,这就意味着读者的输送机可看作包含了 100 个输送单元,并且每个零件需要占用两 个单元的空间。我们也可以把单元的大小设为 2 英尺(共 50 个单元) ,甚至 1 英寸(共 1200 个单元) 。有了现代的计算机,为什么我们还要关心是有 50 个还是 1200 个单元呢?在模型 的计算速度上这难道还不是一个可以忽略的因素吗?在 100 英尺时当然可以, 不过, 如果我 们研究的是个 5 英里长的输送设备, 并且我们也很关心模型的速度, 此时单元尺寸取 1 英寸 还是 100 英尺对模型运行时间的影响可就太大了。 那么, 为什么不让输送单元的尺寸尽可能大呢?当实体试图进入输送设备时, 只有在当 前一个输送单元的末端或者下一个单元的前端与实体所在位置并排时, 实体才能够进入输送 设备。考虑如下情况:当一个实体正准备进入输送设备时,加入读者指定输送单元尺寸为 100 英尺,并且一个空输送单元的末端刚好已通过实体位置 1/2 英寸远,那么实体只能等待 当前单元的末端到达,也即还有 99 英尺 11-1/2 英寸(1 英尺=12 英寸 ) 。但是如果读者指 定的单元尺寸为 1 英寸的话,那零件将只需等待 1/2 英寸的输送空间通过即可。 所以在建模时, 必须要考虑输送单元尺寸的影响。 如果实际中输送设备没有被充分利用, 或者在时间上的少量延迟不会影响到系统性能的话, 那就可以用一个较大的单元尺寸。 如果 以上因素对系统的性能很关键的话,那么就需要用较小的单元尺寸。当我们做决定的时候, 必须考虑两个约束。一是实体的尺寸,它是用输送单元的数目来表示的,而且必须是整数, 因而不能出现需要 1.5 个输送单元的实体。 读者必须用 1 个或 2 个输送单元的大小来描述实 体的尺寸。同样,输送设备上的区段(从一个位置到另一个位置的输送设备部分的长度)也 必须由整数个输送单元组成。所以,如果输送设备的长度是 100 英尺,那么就不能把输送单 元的尺寸定义为 3 英尺。 在开始向模型添加输送设备之前, 我们先看几个概念, 它们在建立输送设备模型时会有 帮助。 类似于资源和运输设备, 在对输送设备建模时需用到以下几个关键词: (Access) 进入 、 输送(Convey)和退出(Exit) 。Arena 在使用输送工具运送一个实体时,实体必须首先进入 到输送工具的空位上,然后被输送到目的地,最后退出输送工具(并释放所占空间) 。为了 表示实际的布局,Arena 的输送工具是由一系列连结在一起的区段所形成的一条输送带。每 一个区段都起始并结束于一个 Arena 站点。 只需要连结这些区段就形成了直线形和环形的输 送系统。因此,在单条输送设备上不能有分岔点使其出现两个或者更多的分支路线,也不能 有聚合点将两个或者更多个路线汇聚在一起。 但是, 我们可以为这一类型的系统定义多个输 送设备。例如,在一个有分岔的系统里,我们可以输送实体到分岔点,进入另一个输送设备 并退出当前的输送设备, 然后将实体输送到它的下一个目的地。 我们的小型制造系统将使用

单条环型回路输送设备。 Arena 有两种输送设备:不可聚集式(Nonaccumulating)和可聚集式(Accumulating) 。 两种输送设备都只按单一的方向行进, 不能反向运转。 不可聚集式输送设备的典型例子是桶 式或皮带式的传送带,还有自动扶梯。在这一类型的输送设备上,被输送的实体之间的空间 间隔不会改变,除非一个实体退出或另有一个进入。由于有这些限制,不可聚集式输送设备 将以一种特定的方式运行。 当一个实体进入这类输送设备的时候, 整个输送设备会停止移动 或暂停工作。当实体开始被运送的时候,输送设备再重新启动运行,并将实体送往目的地。 当实体到达目的地的时候,输送设备暂停移动,实体退出,然后输送设备又重新开始运行。 如果在进入输送设备与开始输送之间, 或者实体在到达目的地与退出输送设备之间所消耗的 时间均为零,那么输送设备看起来就像一直连续不停地运行。然而,如果需要耗费一定的时 间,例如装载或者卸载活动需要一定的持续时间(本例的系统就是这样) ,读者就能观察到 当装载或卸载发生时,输送设备会有一个短暂的停止。 与不可聚集式输送设备不同, 可聚集式输送设备在整个运行过程中不会停下来。 如果某 个实体在可聚集式输送设备上停下来,输送设备上的其它所有实体将仍然继续行进。不过, 这个停下来的实体会阻碍其它实体越过它所在的位置, 这样, 那些不断到达的实体将会在这 个引起堵塞的实体后面聚集起来。 只有当这个引起堵塞的实体退出输送设备时, 那些聚集在 一起的实体才能移向它们的目的地。然而,由于模型里会规定实体的间隔空间,所以不是所 有的实体都能够同时开始移动。 读者可以想象堵塞在高速公路上的汽车, 当汽车被迫停下来 的时候, 它们会尽量地紧挨在一起 (这主要是为了防止那些不顾及别人的司机偷偷地钻到他 们的前面) 。当堵塞被疏通后,为了保持彼此间一定的间隙,汽车会一辆接一辆地开始移动。 我们将在这一章的后面更加详细地加以描述。

8.4.1

模型 8-4:带有不可聚集式输送设备的小型制造系统

现在我们准备把不可聚集式输送设备加入到系统中。 如果读者正和我们一起构建模型的 话,你也许会考虑需要补充另一种变更。在加入输送设备并运行模型以后,你可能会发现相 对于其它时间来说, 装载和卸载时间实在太小, 以至于我们很难看出输送设备是否在正确地 运行。同样地,你也许想通过做进一步的实验来验证装载和卸载活动对系统性能的影响。所 以,我们建议读者定义两个新变量:Load Time(装载时间)和 Unload Time(卸载时间) , 并且把他们的初始值都设为 0.25 分钟。然后用相应的变量名替换当前的常量值;这样一来,

读者只需在一个地方对这些时间值加以修改, 就能改变系统中所有用到这两个量的地方。 到 现在,读者应该已经知道该怎么实现以上变更了(如果不知道,请参考 5.2.3 节) ,所以我们 就不再用更多细节来烦你们了。 我们将从模型 8-1 开始,删掉所有路径。使用“高等运送”面板上的 Conveyor 数据模 块来定义输送设备,如输入界面 8-15 所示。

原书 344 页 输入界面 8-15 Conveyor 模块

在以上输入值中,需要对 Cell Size(单元大小)和 Max Cells Occupied(所需最大单元 数)做一些解释。根据前面模型得出的结果,我们知道在系统里不会有很大的交通量。同样 地, 如果在零件进入输送设备上之前需要有少量的延时, 唯一的影响就是会略微增加零件的 系统逗留时间。 所以我们决定把输送设备的输送单元大小设置得尽量大一些。 我们把单元大 小选定为 3 英尺,这样的话,输送设备的每一段长度都能表示成整数个单元数量(事实上, 为了得到这个结果我们需要对这些长度值稍微做一点调整) 。因为每一个零件需要 6 英尺的 空间,所以每个零件最多占用两个单元。这个值是 Arena 用来确保当实体到达输送设备的末 端时有足够的存储空间来容纳它。因为我们的输送设备是环形的,没有末端,所以对这个模 型来说是没有什么影响的。 但是一般情况下, 需要输入一个在输送期间任何实体可能占用的 最大单元数目。 把输送设备加入模型的过程与把运输工具加入模型是很相似的, 所以我们将不加以详细 讨论。 与加入运输设备一样, 我们需要改变每一个 Leave 和 Enter 模块。 在名为 Start Sequence 的 Leave 模块中,各输入项如输入界面 8-16 所示,这是在模型 8-1 的基础上修改的。读者 可能注意到,每个零件需要占用输送设备上的 2 个单元(每个单元的大小为 3 英尺) ,并且 我们使用了在前面提议的变量 Load Time(装载时间) 。

原书 345 页 输入界面 8-16 输送设备的 Leave 模块

原书 346 页 输入界面 8-17 输送设备的 Enter 模块

在名为 Cell 1 Station 的 Enter 模块中,各输入项如输入界面 8-17 所示。 接下来我们准备在动画部分放置输送设备的区段。如同在上一个模型中使用的距离一 样,首先需要定义模型与动画里需要的区段数据。我们可以用“高等运送”面板中的“区段” (Segment )数据模块来加以定义。输入界面 8-18 显示了 Segment 数据模块的电子数据表 格(主要部分)中的第一个数据项。我们任意选取 Order release 站点作为我们的输送设备 Loop Conveyor 的起点。

原书 346 页 输入界面 8-18 Segment 数据模块

原书 347 页 输入界面 8-19 Segment 数据模块

输入界面 8-19 所展示的是六个区段的数据项的电子数据表格。需要注意的是,这里的 长度是实际的区段长度值而不是单元数目。这些值是直接来自图 8-5。 现在我们开始在动画部分添加区段。 首先, 需要把每一个站点的符号移到主回路中央的 相应位置上,零件将在该处进入或者退出输送设备。添加区段时,可使用 Animate Transfer 工具栏中的 Segment 按钮( ) 。我们需要在这个模型里添加六个区段,添加区段与添加

距离的过程很相似。Segment 对话框如输入界面 8-20 所示,我们将简单地接受缺省值即可。

原书 347 页 输入界面 8-20 Segment 对话框

在这个模型中, 需要在动画部分放置 6 个区段, 如图 8-6 所示。 在放置区段动画对象时, 为了使区段对象被放在回路的中央部分,可能需要重新调整站点符号的位置。

原书 347 页 图 8-6 输送设备的区段

现在基本上已经做好准备来运行动画模型了。不过,还应该先进入 Run > Setup 菜单命 令,勾选 Conveyor 复选框(在 Project Parameters 表页中)以收集输送工具的统计信息。完 整运行模型后, 就会在输出报告里发现有关输送设备的两个新统计量。 第一个统计量告诉我 们,输送设备被堵塞或者停止的时间大约占整个运行时间的 17.65%。虽然这个值看起来好 像较大, 但是读者要考虑到, 每一次零件进入或者离开一个站点都会发生一次装载或者卸载 延时, 在这期间输送设备是被堵塞或者停止运行的。 再考虑一下每个零件移动的次数和已经 完成加工的零件数,那么你将会感觉这个数字还是合理的。如果对此仍有怀疑,读者可以根 据所得到的所有数据来近似估计一下这个值应该是多少。 第二个统计量告诉我们,输送设备仅被利用了大约 6.6%的时间。这个数字表示的并不 是零件在输送设备上停留的时间值, 而是输送设备上被零件占用空间的平均数量。 这是很容 易验证的。读者可以利用图 8-5 所示的长度来确定输送设备的长度(168 英尺) 。已知单元 大小为 3 英尺,所以我们可以以此确定单元的数量(56) 。每一个零件占用两个单元,也就 是说输送设备最多只能同时容纳 28 个零件。因此,如果我们用平均利用率(0.066)乘以 28 个零件(输送设备的输送能力) ,可以得到在输送设备上大约平均有 1.85 个零件。如果读者 仔细观察动画的话,就会发现这个结果看起来是正确的。 如果读者把当前零件在系统里的逗留时间与模型 8-1 里的结果做一个对比, 就会发现当 前模型的系统逗留时间会稍微大一些。 考虑到输送设备的堵塞情况和运动速度, 这看起来也 是合理的。 如果在装载和卸载期间读者看不到输送设备停下来的情况 (即使读者把动画的速度设定 为最低) ,那么就把装载和卸载时间变量值改为 2 或 3 分钟,在新值下,停止的状态应该会

非常明显! 在进行仿真时有几种可选的方式来改变变量的值。 如果读者想要在仿真运行过程中经常 改变变量值的话,可以考虑使用 Arena 的 VBA(Visual Basic for Application)接口(参见第 10 章) 。第二种方法是使用 Arena 中由命令驱动的“运行控制器” (Run Controller) 。首先开 始运行模型,在运行了一会儿之后(运行到时间大约为 445 的时刻) ,点击 Run > Pause 命 令或者 Standard 工具栏上的 Pause 按钮( ) ,暂停模型的运行。然后点击 Run > Command ) ,打开命令窗口。在这个文本窗

菜单或者 Run Interaction 工具栏上的 Command 按钮(

口里显示有当前的仿真时间,并且其后跟着一个提示符“>” ,表示 Arena 准备接受用户输入 的命令。此时可以用 SHOW 命令来显示变量 Load time 的当前值,然后用 ASSIGN 命令来 修改这个值,如图 8-7 所示。再对变量 Unload time 重复上述的两个步骤。然后,关闭这个 窗口,点击 Run > Go 菜单命令或者点击 Standard 工具栏上的 Go 按钮( 时间开始以新变量运行仿真模型。 现在再观察动画的话, 在很短的时间内就会发现输送设备停停动动得很频繁, 并且其上 很快就会出现 10 个以上的零件。 在任何时候读者都可以暂停仿真运行, 并修改这些变量值。 但是在运行控制里所做的修改只是临时性的, 它们将不会保存进模型中, 在下次运行该模型 时,仍然会使用这些变量的初始值。 ) ,系统将从当前

原书 349 页 图 8-7 用运行控制器(Run Controller)来修改变量值

观察动画并在运行中的模型里按以上方式进行修改, 是检验模型的一种很好的方式。 但 是,当读者的最终目的是为了评价模型时,就不应该在运行过程中改变模型的条件。因为这 些修改可能会在结果中得出误导性的指标值,而且在本质上是不可重复的。

8.4.2

模型 8-5:带有可聚集式输送设备的小型制造系统

很容易把我们的模型改为可聚集式输送设备的情况。首先用 File > Save AS 菜单命令把 模型 8-4 另存为模型 8-5。我们仅需要在 Conveyor 数据模块上做两处小改动就可以了:把

输送设备的类型(Type)改为 Accumulating,然后把聚集长度(Accumulation Length)设定 为 4,如输入界面 8-21 所示。所定义的聚集长度规定了在聚集情况下一个零件在输送设备 上仅占用 4 英尺的空间。 注意, 只有当某个实体在输送设备上停下来的时候这个值才被使用, 而且不需要是输送单元大小的整数倍。 当堵塞被疏通后, 零件会自动再次占用 6 英尺的空间 或者 2 个单元(这是在输送过程中所需要的空间) 。

原书 349 页 输入界面 8-21 可聚集式 Conveyor 数据模块对话框

完成这些修改以后运行模型, 读者会发现基本上没有聚集发生。 通过查看总结报告里的 输送设备统计量可以确认这种情况:平均的聚集长度小于 1 英尺,平均的利用率低于 6%。 为了更好地查看聚集效果,简单地把装载时间和卸载时间改为 4 或 5 分钟就可以了。 除了零件的系统逗留时间外,读者所看到的结果与不可聚集式系统的结果是很相似的。 从结果中看到, 可聚集式系统中零件的系统逗留时间较长, 我们强烈怀疑这是由于模型的运 行时间较短的缘故。我们把确认(或反驳)这个结论的问题留给感兴趣的读者。

8.5

小结

对大部分仿真模型来说, 实体搬运是其中很重要的一部分。 为了有效模拟不同环境下的 这种运动,本章举例说明了几种 Arena 运送工具。 这是关于使用 Arena 建模仿真一般知识的最后一章。 我们现在已经能够在底层建模结构 上对问题的各种细节进行描述,并实现相应的调试及动画细节。有关调用 SIMAN 仿真语言 的问题,读者可以参阅 Pegden,Shannon,and Sadonwski(1995)一书。到现在为止,读者 应该已掌握了一个强大的模拟工具库, 你可以在各种建模层次里选择合适的构件用以解决各 类实际问题。 但坦率地说, 还有更多的建模构件和窍门需要读者亲自动手去发现, 我们将在第 9 章介 绍其中的一部分。

8.6

练习

8-1 修改习题 7-4 的模型,使用叉车在各站点之间运送零件。假定有两辆叉车,并且每辆的 行进速度为每分钟 85 英尺。叉车装载和卸载零件的时间为 0.25 分钟。站点之间的距离如下 表所示(单位:英尺) ;注意所给出的距离是有方向的:

目的地 Arrive Arrive WS A WS B WS C Exit system 0 100 100 250 350 WS A 100 0 150 100 250 WS B 100 150 0 100 225 WS C 200 100 100 0 100 Exit system 300 225 200 100 0

出 发 地

运行模型 100000 分钟(在确认运行进展顺利后,可以通过 Run > Run Control > Batch Run

(No Animation)命令关闭动画) 。当叉车卸下零件时若没有新的运送请求,就假设它停在
当前位置上。如果有两辆叉车同时可用,则假设最接近零件的一辆被选中。 8-2 修改习题 7-4 的模型,使用不可聚集式输送设备在各站点之间运送零件。假定现有单台 输送设备,从进入系统的位置开始一直连接到到离开系统的位置:Arrive-WSA-WSC-Exit。 假定在输送设备上, 连接所有相邻站点的长度都是 100 英尺。 进一步假设该输送设备的输送 单元大小为 2 英尺, 而且每个零件需要 4 英尺的输送空间。 装载和卸载零件的时间均为 0.25 分钟。输送设备的运行速度是每分钟 20 英尺。 8-3 修改习题 5-2 的模型,使用叉车(45 英尺/分钟)在系统里运送零件。假设零件从“入 口”位置抵达并从“出口”位置退出系统。假定入口位置与机器 2 之间的距离是 200 英尺, 所有其它的距离都是 100 英尺。以动画形式给出解决方案。 8-4 使用习题 8-3 的模型,设定运输设备的数量为 4,分别按以下的运输工具选择规则运行 模型:最小距离规则(Smallest Distance) ,最大距离规则(Largest Distance) ,循环规则 (Cyclical) 。比较三种情况下的系统逗留时间。 8-5 修改模型 4-3,加入一辆卡车从两个预处理区域运送零件到封装台。假定三个工作站中 任意两个之间的距离是 100 英尺, 并且卡车运行的速度为每分钟 75 英尺。 以动画形式求解。 8-6 修改模型 4-3,加入两台输送设备分别从两个预处理区域向封装台运送零件。两台输送 设备都是 100 英尺长, 20 个长 5 英尺的输送单元组成。 由 输送设备的速度为每分钟 30 英尺。

以动画形式求解。 8-7 下图所示是一个正在设计中的新机场的行李检查系统模型。 行李到达系统的间隔时间是 EXPO(0.25) (所有的时间单位是分钟) ,然后被装到“运载”输送设备上(75 英尺长) , 运到初始扫描区。在初始扫描区,行李落入滑槽等待扫描,扫描时间为 TRIA(0.1,0.25, 0.35) 。根据扫描的结果,被接受的行李(79%)被装到“运出”输送设备上(40 英尺长) 运出系统,而被拒绝的行李则被装到“二区”输送设备(20 英尺长)上运往第二扫描区。 在第二扫描区,行李首先落入滑槽等待目视检查,检查时间为 TRIA(0.6,1.2,1.4) ;目视 检查后,行礼被送去通过第二扫描器,该扫描器长 10 英尺。这次扫描需 1.2 分钟,而且一 次只能扫描一件行李。 在第二扫描器的末端, 另有一个检测器再次对行李检查, 时间为 EXPO (0.4) 。根据第二次扫描的结果,10%的行李被送往拒绝区接受进一步检查,被接受的行李 被装上“运出 2”输送设备(20 英尺长)运出系统。所有的输送设备都是速度为每分钟 40 英尺的不可聚集式输送设备。 每件行李在每个输送设备上需要 1 英尺的空间。 构建这个系统 的模型并运行 2000 分钟。用资源约束路径来模拟第二扫描器。

到达的行李

滑槽

初始扫描

退出系统

退出系统

滑槽

目视检查

第二扫描

被拒绝的行礼

原书 351 页 (插图) 在当前设计中,要求初始扫描区滑槽的容量为 20,第二扫描区的总容量为 25(不包括 正在进行目视检查的行李) 。按照这个设计,你预计将有百分之多少的时间会出现容量不足 的情况?提示:添加两个持续时间型的统计量来收集信息,统计量用逻辑表达式来计算:当 行李的数量小于容量时,表达式为 0;当行李数量超出容量时,表达式为 1。 8-8 建立一个物流转运系统模型, 该系统通过对物料的组织和搬运, 为进一步的运输作准备。 这个系统有 5 个进入作业台(incoming dock)和 3 个离开作业台(outgoing dock) 。卡车装

载着放在托盘上的物料抵达每个进入作业台。卡车抵达每个进入作业台的间隔时间为 UNIF (30,60) (所有时间单位为分钟) 。每辆卡车上装载的托盘数服从 UNIF(10,22)分布(舍 入取整) ,这些托盘需要运送到其中的某个离开作业台。假定任一进入的托盘都以相同的概 率前往 3 个离开作业台中的某一个。 当卡车抵达时, 一个自动卸载设备将在进入作业台处卸 载托盘。假定卸载过程不需要耗费时间,因此托盘可以立即运送。有 5 辆叉车被用来把托盘 运送到其中的一个离开作业台, 所有离开作业台都位于转运系统的另一面。 任一进入作业台 到任一离开作业台之间的距离都是 75 英尺, 并且叉车以每分钟 75 英尺的速度行进。 一个叉 车装载一个托盘的时间是 UNIF(0.3,0.4) 。系统的性能指标是托盘在系统中的平均逗留时 间。 (提示:如果一开始把所有的叉车放置在离开作业台,作为它们的初始位置,这样就不 用再定义进入作业台之间的距离) 。设定运行时间为 720 分钟,并作为终态仿真模式。分别 按以下两个条件建立模型,并加入相应的动画。 (a) 假设运送优先级如下:首先运送等待时间最长的托盘。 (提示:在 Transfer Out 对话 框的“优先级” (priority)栏内输入实体的到达时间属性名称。 ) (b) 因为要保证到达的卡车总能够被卸载,所以修改上面的(a)模型,把运送优先规则 设定为:当前托盘数最多的进入作业台优先装运。 (提示:用 NQ 来表示优先级。 ) 以上两种选择哪一个更好一些?注意使用有效的统计分析方法来证明你的结论。此外, 对每一种情况,研究增加叉车(最多到 7 辆)的效果。

第9章

建模问题与技术的进一步探讨

通过第四章到第八章一系列逐步复杂的实例, 我们引导读者较为全面地了解了如何模拟 各种不同类型的系统。 我们选择这些实例有几个目的, 包括展示应用系统的实用性和重要性、 各种不同问题的建模方法, 以及指导读者如何简单快速地运用适当的方式在 Arena 中表示各 种事物。掌握了这些技能后,读者就能正确而有效地建造各种仿真模型了。 尽管人们有些时候会考虑在一个模型中同时使用多种手段, 但毕竟不可能在一个实例里 面够包括所有的模型特征,而且一个模型中所包含的建模特征远远少于 Arena 所提供的数 量。在这一章里,我们准备探讨其它一些较为重要的建模问题与技术,以及如何利用 Arena 去实现。 本章中我们将建造更多的实例,这些实例更加关注一些细节方面的技术和 Arena 特性。 在 9.1 节我们将改进第八章中开发的输送设备模型;在 9.2 节讨论对第八章运送设备建模的 改进;在服务系统中,特别是那些含有排队现象的系统中,可能经常要考虑顾客的中途退出 (reneging)问题(也就是说,在某一时刻顾客从队列中离开) ,我们将在 9.3 节考虑这种情 况,以及受阻离开(balking)的概念;在 9.4 节,将探讨在某一时刻把实体组合成一批、而 且过后还可以再拆分的方法;9.5 节讨论如何表示紧密耦合(tightly coupled)系统,在这种 系统中, 实体只有在当前位置就被分配好了后续处理所需的资源时才能继续前进, 从实体的 角度看,这叫做重叠资源(overlapping resources) ;最后,在 9.6 节简要介绍一些其它专题, 包括导引运送设备、并行队列、复杂的决策逻辑和循环等。 本章在结构上与以前的章节有所不同, 因为本章不必按顺序阅读, 本章的目的就是提供 一个建模技术和 Arena 特征的集萃,它们在各种不同的应用项目中被证明非常有用。

9.1 使用“高等运送”面板模拟输送设备
这一节我们对第八章建立的基本输送设备模型提出一些改进。

9.1.1 模型 9-1: 站点的有限容量缓冲区
在第八章我们介绍了 Arena 的输送设备,在 8.4.1 节我们使用了不可聚集式输送设备作 为运送零件的方法,建立了小型生产系统的模型 8-4。在那个模型中,我们假设每个加工单

元前有无限容量的缓冲区用于存储等待加工的零件。这个假设使得我们能够在 Enter 模块和 Leave 模块里使用输送设备的功能,不过我们需要从“高等运送”面板里添加 Conveyor 和 Segment 数据模块来定义相应的输送设备。 现在我们将修改这个假设, 也即假设 Cell 1 和 Cell 2 只有有限容量的缓冲区用于存储尚 未加工的零件,事实上,我们假设每个单元只能存储一个未加工的零件。对于这类模型,我 们需要定义零件到达 Cell 1 或 2 时,已经有一个零件占据了有限的缓冲区的情况。假如我们 能使用 Enter 模块来限制缓冲区的话(这是不可行的) ,那就可以很容易地让到达的零件等 待,直到缓冲区内的零件进入加工单元中的机器。当然,这将会在这些加工单元处造成明显 的堵塞现象, 不仅到本单元加工的零件进不去, 而且要前往其它加工单元的零件也会排在它 们后面等待,从而引发了另外的问题。我们知道,完成加工的零件在被输送到下一个目的站 点之前, 需要先占据输送设备上一定的可用空间, 而这些空间此时却被正在等待进入这个单 元的其它零件所占用,这就形成了所谓的“死锁”(deadlock 或 gridlock)。 因此,对于到达 Cell 1 或 2 的零件,我们采用下面的策略。如果单元的缓冲区内目前没 有等待的零件,则允许到达的零件进入缓冲区;否则,零件就沿环形输送设施继续前进,并 被再次运送到这个位置试第二次(第三次、第四次等) 。要做到这一点,就需要改变模型, 以便我们能更好地控制零件什么时候退出输送设施。 “高等运送”面板为输送设施提供了五 个新的模块,分别是“进入” (Access)“输送” 、 (Convey)“退出” 、 (Exit) 、启动(Start) 和“停止” (Stop) ,这些模块可以帮助我们更加细致地模拟输送设施的活动。Exit 模块使实 体退出输送设备,释放其所占用的输送单元。这个功能与在 Enter 模块的 Transfer In 部分选 择 Exit Conveyor 选项本质上是一样的。Access 模块使实体在某一位置(通常是当前它所在 站点的位置) 请求或占用输送设备的可用空间。 一旦实体成功地占用了输送设备的一定空间, Convey 模块就将实体输送到它的目的地。在 Leave 模块的 Transfer Out 部分选择 Access Conveyor 选项,实质上与 Access 和 Convey 的组合具有一样的功能。Start 模块和 Stop 模块 的作用分别是启动和停止输送设备运行。 这两个模块可用于建立用户自己的故障逻辑, 或者 控制输送设备什么时候运转或停下来。 在开发新的模型时,可以以模型 8-4 为基础,在 Cell 1 中用新模块取代原来的 Enter 和 Leave 模块,如图 9-1 所示。

原书 P357 图 9-1 Cell 1 新的模型逻辑

被我们替换掉的 Enter 模块所完成的功能包括:定义了名为 Cell 1 的站点,实体退出输 送设施。站的定义很关键,因为 Arena 必须知道把需要输送到 Cell 1 的实体送到哪个具体位 置。因此,我们需要用“高等运送”面板中的 Station 模块来定义 Cell 1 的进入点。我们也 可以用 Enter 模块来实现, 但我们希望在此为读者展示一下 Station 模块的使用。 Station 模块 仅仅定义了运送至该站点的实体的逻辑入口。本例在对话框中唯一需要提供的就是站点名 称,如输入界面 9-1 所示。

原书 P357 输入界面 9-1 Station 模块

当一个实体或零件到达 Cell 1 时,需要先检查等待队列的状态。我们可通过 Decide 模 块来实现这个功能,利用 Decide 模块查看队列 Cell 1 Process. Queue 中的实体数量是否等于 0,如输入界面 9-2 所示。队列名称和模型 8-4 中的一样,是在 Process 模块里定义的。如果 队列当前被另外一个实体占据,则到达的实体将前往模块的 False 分支。

原书 P357 输入界面 9-2 Decide 模块

在这种情况下, 我们不让零件离开输送设备, 而是把零件留在环形输送设备上继续向前 移动,直到再次回到同一站点。如输入界面 9-3 所示,我们把实体送到“输送” (Convey) 模块,并将它输送回 Cell 1。

原书 P358 输入界面 9-3 Convey 模块

此时,读者也可能会想到“可是实体已经在 Cell 1 处了! 实际上,此时 Arena 假定读 ” 者就是要输送实体,因而会将实体放到它的输送路径上。当然,Arena 还假定它能够把实体 输送到指定的目的地。因此,Convey 模块将用指定的输送设备将实体送到指定的目的地。 不过,如果实体当前没有处于该输送设备上,Arena 将显示错误信息并终止运行。 如果 Cell 1 的队列中没有别的实体,则所到达的实体按“条件成立”的分支被送到其后 的 Delay 模块,如输入界面 9-4 所示。此时实体将在该模块中延时以完成卸载过程,然后实 体被送到 Exit 模块, 在那里从输送设备上移除实体,并释放实体所占用的输送单元,如输 入界面 9-5 所示。 实体离开 Exit 模块后被送到 Process 模块,它表示的是实际的机器加工过程,如图 9-1 所示。一旦零件完成了加工操作,就离开 Process 模块,并被送到随后的 Access 模块以获取 输送设备上的可用空间,如输入界面 9-6 所示。 Access 模块的作用是为实体分配输送设备上的可用单元,以便实体能够被输送到它的 下一个目的地。需要注意的是,Access 模块本身并不输送实体,因此当实体获得输送单元 后,如果不能立即输送该实体,则整个输送设备将停下来,直到开始输送这个实体为止。

原书 P358 输入界面 9-4 卸载延时模块

原书 P359 输入界面 9-5 Exit 模块

如果此时输送设备上没有足够的可用单元来容纳实体,则实体将停留在队列 Access Conveyor at Cell 1. Queue 中,直到有足够可用单元为止。这一过程将会在动画中显示出来。 如果有足够的可用单元容纳实体, 则首先产生由装载活动带来的延时, 然后再将其送入 Convey 模块,根据指定的序列将实体输送到它的下一站。到此就完成了对模型 8-4 中 Cell 1 部分的修改工作。 对 Cell 2 需要进行相同的操作,读者可以简单地重复以上步骤,或先拷贝这些模块再各

自进行编辑修改。我们只替换 Cell 2 的 Enter 模块,而保留 Leave 模块,如图 9-2 所示。我 们认为到目前为止读者已经熟悉了进行相应改动的操作。

原书 P359 输入界面 9-6 Access 模块

原书 P360 图 9-2 Cell 2 的新模型逻辑

当删除 Enter 模块和 Leave 模块的时候,读者会发现部分动画也被删除了,这是因为读 者接受了 Leave 模块“自带的”的动画队列。当读者按这种方式编辑或修改模型时,可使用 Animate 工具栏里的一些动画构件来补充新的动画特征。所以在建立模型时,我们删除了新 模块所带的动画元素,然后自己动手添加新的动画元素。在这个模型中,我们删除了 Cell 1 的队列和暂存处, 然后添加了新的 Access 队列 (等待获取输送单元) 当我们运行新模型时, 。 能够看到在大约 275 分钟时零件受到阻滞而不能进入 Cell 1。

9.1.2 模型 9-2: 零件在加工过程中停留在输送设备上
读者已经掌握了新的输送设备模块, 现在让我们研究另一个问题。 我们先从可聚集式输 送设备模型(8.4.2 节提出的模型 8-5)着手,尝试一种新的布局,即在 Cell 2 进行加工的时 候,零件仍然停留在输送设备上。也就是说,零件被输送到 Cell 2 后并不离开输送设备,而 是在输送设备上完成加工操作, 然后再被输送到下一个目的地。 由于输送设备是可聚集类型 的,所以其上的零件将继续向前移动,直到被 Cell 2 处正在加工的零件阻滞为止。 我们可以用一组与模型 9-1 相似的模块取代 Cell 2 当前的 Enter 模块和 Leave 模块来实 现这一改动。不过,由于到达 Cell 2 的实体不离开输送设备,所以可以采用一种更为简单的 解决方案,即只需在 Enter 模块的 Transfer In 部分选择 None 选项即可,此时实体将不离开 输送设备。这样,当在 Process 模块中执行操作时,实体将仍然停留在输送设备上。但是,

如果我们只在这里做了修改, 那么在实体试图离开 Cell 2 的时候将会发生错误。 因为在 Leave 模块的 Transfer out 部分,我们以前曾选择了 Access Convey 选项,这个选项使实体要求分 配输送设备上的可用空间,而此时实体已经在输送设备上了,因此 Arena 会产生困惑,系统 将因错误而终止运行。 这可通过在 Leave 模块的 Transfer out 部分也选择 None 选项就能解决 了。 通过观察动画, 读者可以检验一下新的模型逻辑是否正确。 我们建议读者在观察动画之 前先用“快进”方式将仿真推进到第 700 分钟左右,这时能看到十分明显的改动效果。

9.2 关于运送设备的更多知识
在第 8 章,我们介绍了使用“基本操作”面板中的高层模块来模拟 Arena 输送设备和运 送设备。9.1 节中,我们使用“高等运送”面板中的模块进一步拓展了输送设备的功能,从 而对第 8 章提出的模型进行了改进。 运送设备中也存在同样问题, 尽管我们不准备用这些模 块建立一个完整的模型, 但还是准备简要概括一下这些模块的功能, 并通过模拟几种不同的 情况来展示一些模块组合。 这对于读者在模型中成功地使用这些建模构件来说应该已经足够 了。另外,别忘了可随时查看在线帮助。 让我们从 8.3 节介绍的基本功能开始。 Enter 和 Leave 模块中的 Transfer In 和 Transfer 在 Out 部分,基本的运送设备选项仍然是可用的。接下来考虑请求运送以及随后把运送设备和 实体运到下一站点的过程, “高等运送”面板中的 Request 模块和 Transport 模块也能够提供 这一功能。 Request 模块实现的是 Leave 模块中 Transfer Out 域的第一部分的功能。在 Request 模块 里能够指定与默认值不同的速度,但不能指定装载时间,不过可以通过后接一个 Delay 模块 来定义装载时间。Request 模块实际上完成两种活动:为实体分配运送设备,并将空的运送 设备移到实体当前位置 (如果运送设备没在实体当前位置的话) Transport 模块执行 Transfer 。 Out 域的下一部分功能,即把运送设备和零件运至它的下一个站点。现在我们考虑把两种功 能分开的建模情况。假设当运送设备到达实体位置时,需要由操作人员来完成装载操作,这 就需要使用以上的新模块。完成此项功能的模块序列(Request-Process-Transport)如图 9-3 所示。

原书 P361 图 9-3 由操作人员完成的运送设备装载

使用 Allocate 和 Move 模块能够把 Request 模块实现的功能分成两个活动。Allocate 模 块给实体分配运送设备(如运货车) ,但车辆仍留在其当前所在位置;而被分配了运货车的 实体则可通过 Move 模块将相应的空车移动到模型中的任何位置。当使用 Request 模块时, 运送设备将被自动移到实体所在的位置上。 考虑如下这样一种情况, 空的运送设备必须先从 供给处取一件夹具来运送实体。此时,我们需要分配运送设备、把运送设备送到供给处、挑 选夹具、然后再把运送设备运到实体所在位置。用于模拟以上活动的模块序列 (Allocate-Move-Process-Move)如图 9-4 所示。

原书 P362 图 9-4 需要夹具的实体运送

当然,读者还可以对各种活动进一步加以完善。假如只有一部分实体需要夹具,这时我 们可以很容易地在模块之间添加一个 Decide 模块来检查这种情况,如图 9-5 所示。 在我们使用 Allocate 和 Move 模块的两个例子中,运送设备最后都是移动到实体所在位 置。现在让我们假设无论何时运送设备被释放,它都围绕着系统运动以寻找工作。当然,读 者应预先定义一条路径让运送设备沿着它运动。这一路径非常类似于一系列站点组成的序 列,只不过它是一个闭合回路。当尚未分配实体的运送设备到达路径上的某一站点时,会检 查一下当前某处是否有运送请求。如果没有,它将继续“漫无目的”地运动;如果有请求, 则立刻前往发出请求的位置。 要模拟这种情况,需要创建一个单独的实体(称之为循环实体) 。这个实体将以非常低 的优先级(权值很大)被分配运送设备。一旦它得到了空的运送设备,就会沿着相应的路径 移向下一站点,到达站点后,运送设备被释放,以响应任何当前的运送请求。然后循环实体 被送到最初的 Allocate 模块,在这里它将试图再次请求分配运送设备。这种情况假设当前任 何运送请求都比循环实体的优先级高。记住默认优先权值是 1,权值越低则优先级越高。 一旦运送设备到达目的地,就必须被释放。可以用 Free 模块实现这项功能,仅需要在 对话框内输入运送设备名称,有时候要输入单元数量。另有两个模块 Halt 和 Active,允许

用户改变处于活动状态或可用状态的运送设备的数量, Halt 模块可以使一个运送单元变成非 活动或不可用状态,而 Active 模块则可以使处于非活动状态的运送设备变为活动或可用状 态。

原书 P362 图 9-5 检查是否需要夹具

9.3 实体中途退出
9.3.1 实体受阻离开与中途退出
当到达的实体或顾客因为没有空间而不能进入队列时,将发生受阻(balking)现象,此 时实体或顾客将离开或去其它地方。 而若实体或顾客在到达时进入了队列, 但是后来又跳出 或者决定离开队列,这种情况称为中途退出(reneging) 。显然,排在第一位的实体只可能发 生中途退出而不可能出现受阻。 我们接下来将考虑可能存在顾客受阻和中途退出这两种现象 的复杂情况。首先定义实体受阻和中途退出的不同方式。 大多数服务系统的等待空间所能容纳顾客的数量是有限的,当所有空间都被占满的时 候,新顾客将不能进入系统,也即受阻。这是最简单形式的实体受阻,不幸的是大多数发生 受阻现象的系统会更加复杂。 考虑一条简单的服务队列, 该队列长度或排队容量在理论上是 无限的。虽然大多数实际情况下,由于空间的限制,其排队容量是有限的,但有些服务队列 很可能排到了建筑物的外面, 或者一直沿着街区排下去 (例如求购世界职业棒球大赛或超级 杯大赛门票的等待队列) ,在这种情况下,就没有具体的容量限制了,顾客是否决定加入队 列完全取决于他们对当前情况的评价。因此对于不同的顾客,其受阻离开的队长临界值(顾 客根据该值决定是否进入队列)通常也是不同的,当某个顾客到达的服务队列时,可能认为 当前队列太长而决定离开(受阻) ;但下一个顾客反而有可能愿意进入队列等待。 对实体中途退出现象的建模和表达将更加复杂。 每个进入队列的实体或顾客对离开队列 前的等待时间都有不同的容忍程度, 是否离开队列通常取决于每个顾客对接受服务的渴望程 度。 一些顾客无论等待多久都不会中途退出, 而另外一些顾客等了一段时间后就会离开队列,

因为他们意识到不能及时得到服务来满足要求。 通常说来, 顾客决定是继续排队还是离开队 列基于两方面的考虑: 他们已经花费的等待时间和他们在队列中的当前位置。 一个顾客可能 决定进入队列后等待十分钟,如果到时仍没有得到服务则可能离开。但十分钟后,如果下一 个即将轮到他接受服务,那他也可能选择继续等待。 换队是一种更加复杂的中途退出形式, 经常发生在超市、 快餐店和没有采用单一等待队 列的银行的服务队列中。 顾客先选择一条队列进入, 后来会根据当前队列的长度重新评估他 的决定。毕竟我们都有可能进入移动最缓慢的一条服务队列,但如果我们改换队列,那么所 离开的那条队列将会加速, 而我们进入的队列又会减慢。 我们将不探讨所有可能的换队过程。

9.3.2 模型 9-3:含有受阻离开和中途退出的服务模型
让我们用一个非常简单的模型来看看受阻离开和中途退出的情况。顾客以时间间隔 EXPO(5)到达一个单服务台的服务系统。服务台的服务时间为 EXPO(4.25) ,所有时间 单位为分钟。假设等待队列的容量无限,但每个到达的顾客都会查看当前队列的长度,并与 他的等待容忍度(tolerance)相比,如果队列的长度大于他的容忍度,他将受阻离开系统。 我们用三角分布 TRIA(3,6,15)产生的随机数表示受阻顾客的容忍度。由于我们产生的 随机数来自于一个连续分布,故不一定是整数,我们可以使用 Arena 的相关函数把该随机数 转换为整数。我们所关心的是等待队列的长度是否大于生成的容忍度。 有两种方法模拟受阻离开活动,一是先创建到达实体,用三角分布产生容忍度,并将其 赋值给实体的某个属性,然后我们把到达实体送到 Decide 模块,对比容忍度值和当前队列 长度(利用 Arena 变量 NQ) 。如果容忍度小于等于当前队列长度,则阻止实体进入系统, 否则,实体进入等待队列。另一种方法是把容忍度赋值给一个变量,同时用这个变量表式服 务台的队列容量。如果当前队列长度大于或等于容忍度(此时等同于队列容量) ,则到达实 体被自动阻止进入。使用第二种方法时,可能赋给队列容量的数值会小于当前队列长度。当 一个新实体试图进入队列时,Arena 仅检查队列容量值,即使队长大于新的队列容量值,当 前队列中的实体也不会丢失。在建立模型时,我们将使用第二种方法。 为表示中途退出活动,假设决定进入系统(而不是受阻离开)的到达实体希望只在队列 中等待有限的一段时间。 我们用 ERLA (15, 产生中途退出实体的容忍时间 2) (均值为 30) , 并在 Create 模块里把该数值赋给实体的某个属性。模拟中途退出活动的逻辑结构可以说是 一种挑战。当实体进入队列、到达中途退出的时间后,我们需要找到实体并把它从队列中删

除。此时可以考虑如下方法来处理这种情况,例如,我们可以定义一个变量,用来跟踪下一 次服务台在什么时候可用。首先我们生成实体的加工时间,在 Assign 模块里将它赋给实体 的属性,然后把实体送到 Decide 模块,在这里决定是否受阻;如果实体没有受阻,则在同 一 Decide 模块内检查在中途退出时间之前实体是否能够得到服务;如果不能则中途退出, 否则的话把实体送到 Assign 模块,在这里更新变量,这个变量将告诉我们服务台在什么时 候可用,然后把实体送入队列。模型逻辑看起来似乎很复杂,但可以简要归纳如下:

原书 364,365 页 (程序) 注意取最大值函数(MX)的使用。 现在的模型逻辑里有一个问题, 就是当前队列的长度是不准确的, 因为它不包括还没有 中途退出的实体,不过这个问题很容易解决。我们可以把中途退出的实体送到一个 Delay 模 块中, 在这里实体将被延时, 延时长度为其中途退出时间的大小; 此外再定义一个暂存处 (例 如 Renege_Customers) 。现在把第一条 Decide 语句改为: If Balk Limit > Number in queue + NSTO(Renege_Customers) 我们需要对统计结果很谨慎, 不过这种方法可以精确地描述中途退出的过程, 并且不必修改 队列。 在开发模型之前我们补充最后一点说明, 假设在实际中, 中途是否退出的决策不仅取决 于中途退出时间,而且取决于顾客在队列中的位置。例如,顾客虽然已经到了要中途退出的 容忍时间限度,但是他目前正处在等待队列的前面,则他可能仍希望继续等待服务。我们称 顾客即使到了中途退出时间但仍选择继续等待的队列位置为停留区(stay zone) 。因此,如 果停留区是 3,意味着即使顾客的等待时间已经超过了中途退出时间,但如果他是接下来的 三个服务对象之一,那么就会继续停留在队列中。 我们用 POIS(0.75)产生这个位置值,使用泊松分布是因为这种分布可以合理地近似 描述这一过程,而且产生的是整数值,对于那些没有接触过泊松分布表的人来说,以上泊松 分布近似等价于如下的离散经验分布:DISC(0.472,0,0.827,1,0.959,2,0.993,3, 0.999,4,1.0,5) ,关于离散经验分布的细节可以参阅附录 D。 采用新的决策过程后, 上面的逻辑将不再有效, 我们现在必须把到达实体放到等待队列

中,在过了中途退出时间后再评估是否退出。可是,如果直接把实体放到队列中去,就没有 相应机制来检测实体是否已经超过中途退出时间了。 为了解决这个问题, 我们需要对每个实 体制作副本,并且对实体副本加以延时(延时长度等于中途退出时间) 。而原始实体(代表 实际顾客)则被送到服务队列中。经过了长度为中途退出时间的延时后,用实体副本检查原 始实体在队列中的位置。如果顾客不在服务队列中(即顾客已经得到服务) ,则仅清除实体 副本;如果顾客仍在队列中,则检查顾客是否应中途退出。如果顾客在队列中的当前位置处 在停留区内, 则同样仅清除实体副本; 否则, 将利用实体副本把原始实体从服务队列中移除, 并清除实体副本和原始实体。模型的逻辑可概括如下:

原书 366 页 (程序) 为了实现这一逻辑,显然我们需要几个新的功能,例如搜索队列并从队列中移除实体。 在“高等操作” (Advanced Process)面板和“操作块” (Blocks)面板里可以找到能够实现 这些功能的模块,完整的 Arena 模型(模型 9-3)如图 9-6 所示。 首先,我们用 Create 模块产生到达的顾客,然后顾客被送到 Assign 模块,后面所需要 的数据将在这里被赋值,如输入界面 9-7 所示。

原书 P366 图 9-6 服务模型的逻辑结构

原书 P367 输入界面 9-7 Assign 模块

我们把新到达的实体送到 Separate 模块,在这个模块中可以对进入的实体制作副本。原 始实体通过模块右边的出口离开,而实体副本则通过模块下方的出口离开。在这里,我们只 需要输入模块的名称,其余的数据接受默认值即可。

实体副本是原始实体的精确复制(在属性与属性值方面) ,而且能够制作任意多个。如 果制作了多个副本, 可以把它们当作是从同一个出口离开模块的一批实体。 注意, 如果在 “副 本数量” of duplicates)处输入 n,则实际上有 n+1 个实体离开模块,即从模块下面出口 (# 点离开的 n 个实体副本和从上面出口点离开的 1 个原始实体。 原始实体(顾客)被送入 Queue-Seize 模块序列(位于 Blocks 面板) ,在这里实体试图 进入队列 Server Queue 等待服务。为了实现这个方法,需要将 Seize 模块前的队列容量设置 为变量 Server Queue Capacity。首先,在模型中添加 Blocks 面板,然后选择并放置 Queue 模块(注意,当点击 Queue 模块时,不会出现相应的电子数据表格视图,来自 Blocks 面板 和 Elements 面板的模块都是这样) 。在打开队列对话框之前,读者可能注意到在模块右边只 有一个出口点。现在双击模块,输入模块标识、队列名称和容量,如输入界面 9-8 所示。关 闭对话框之后, 在模块右下角读者将看到第二个出口点, 这个出口点是用于受阻实体离开的。

原书 P368 输入界面 9-8 Blocks 面板中的 Queue 模块

在队列容量(Capacity)部分输入变量 Server Queue Capacity,这个变量被设置为到达 实体不受阻离开的容忍度值,这在前面已经讲过了。如果当前队列长度小于 Server Queue Capacity 的当前值,则顾客将会进入队列,否则将受阻进入 Record 模块。在 Record 模块中 记录受阻顾客数量,然后受阻顾客被送到 Dispose 模块,在这里退出系统(见图 9-6) 。进入 队列的顾客则等待资源 Server。 紧跟 Queue 模块后面的是 Seize 模块,注意这里添加的 Seize 模块是操作块(Blocks) 面板中的操作块,而不是“高等操作” (Advanced Process)面板中的模块,这是因为“高等 操作”面板中的 Seize 模块本身也带有一个队列,而如果实体在占用资源之前发现有两个队 列,Arena 将会“十分困惑” 。双击 Seize 操作块,将出现如输入界面 9-9 所示的对话框。 当顾客占用服务台后,将被送入下一个 Process 模块,在 Process 模块中完成延时(服 务)并释放服务台资源,完成服务的顾客被送到 Record 模块,记录系统逗留时间,再进入 第二个 Record 模块,记录实体数量,最后被送到 Dispose 模块。

原书 P369 输入界面 9-9 “操作块”面板中的 Seize 操作块

实体副本被送到 Delay 模块,实体在这里根据属性 Renege Time 中的中途退出时间进行 相应的延时。延时后,实体进入 Assign 模块,将属性 Customer # 的值赋给一个新的变量 Search #。属性 Customer # 包含了顾客进入系统时被赋予的唯一编号。然后实体被送到“高 等操作”面板中的 Search 模块,利用 Search 模块可以搜索某个队列,从中找到满足所定义 条件的实体在该队列中所处的排位(rank) 。排位为 1 意味着实体处在队列最前面(即下一 个服务对象) 。在我们的模型中,我们需要找到这个实体副本所对应的原始实体,该原始实 体的属性 Customer # 和我们刚刚赋值的变量 Search # 具有相同的值。 Search 模块(见输入界面 9-10)根据所定义的搜索条件在规定的范围内搜索。通常说 来, 会搜索从 1 到 NQ 的整个队列 (注意, 也可以通过把范围定义为从 NQ 到 1 来反向搜索) 。

原书 P370 输入界面 9-10 Search 模块

读者也可以按模型逻辑的要求搜索某一指定范围, 但是如果所规定的范围超出当前队列 的长度,Arena 将会终止运行并给出错误信息。Arena 会把搜索到的第一个满足条件的实体 的排位赋值给变量 J,并让实体从正常出口点(标注为 Found)离开。如果搜索条件中包含 了 MX(取最大值)或 MN(取最小值)函数,则搜索整个范围;如果搜索条件中用到了属 性,则将它当作搜索队列中实体的属性值;如果队列是空的或没有满足条件的实体,则实体 将从下面的出口点(标注为 Not Found)离开。通常说来,我们只关心找到的实体排位,以 便能够从队列中移除那个实体(Remove 模块)或制作该实体的副本(Separate 模块) 。利用 Search 模块还可以搜索通过 Batch 模块建立的临时组里的实体。此外,也可以搜索任何表达 式。 对于我们的模型来说,我们想从 1 到 NQ 搜索整个队列,以寻找与实体副本有相同 Customer # 值的原始实体。如果原始实体不在队列中,实体将通过 Not Found 出口点退出, 然后进入 Dispose 模块;如果找到了原始实体,则将它的排位被保存在变量 J 中,然后实体 进入后面的 Decide 模块,检查 J 的数值是否小于或等于 Stay Zone 属性值。如果条件为真,

则表明顾客在队列中的排位比较靠前,所以顾客将选择继续留在队列中,在这种情况下,我 们将清除实体副本;如果条件为假,则原始实体将中途离开,因此需要把实体副本送到随后 的 Remove 模块中。 利用 Remove 模块可以从队列中移除实体,并把实体送到模型中的其它地方。Remove 模块通过队列的名字和实体在对列中的排位来确定所要移除的实体, 如果试图从一个未定义 的队列中移除实体,或者实体的排位值大于指定队列中的实体数量,Arena 将终止运行并给 出错误信息。在本例的模型中,我们将把排位为 J 的顾客从队列 Server Queue 中移除,如输 入界面 9-11 所示。

原书 P371 输入界面 9-11 Remove 模块

观察 Remove 模块,读者会发现右边有两个出口点。在本模型中,进入 Remove 模块的 实体将从上面的出口点离开,并被送到与 Decide 模块第一个分支相连的 Dispose 模块中。 而从服务台队列中被移除的实体则从下面的出口点离开,并被送到 Record 模块中记录中途 退出的顾客数,然后进入 Dispose 模块。 设置重复仿真运行的周期为 2000 分钟,仿真输出报告的结果显示,有 8 个顾客受阻离 开(balking) ,41 个中途退出(reneging) ,332 个得到服务。

9.4 实体的滞留和按批组合
在这一节, 我们将处理因各种原因需要将实体滞留在它的路径上的情况, 还将讨论如何 将实体组合在一起以及如何再将它们分开。

9.4.1 建模选项
当模拟更加复杂的系统时,可能需要把实体暂时滞留(或保持)在模型的某个地方,直 到某些系统条件允许这些实体继续前进为止。 读者可能觉得我们已经考虑过这种情况了, 因 为在排队等待可用资源、输送设备和运输设备时都允许我们就地保持实体,直到资源可用。 不过在这里我们考虑的是更一般的情况, 实体滞留与否并不是基于资源、 输送设备或运输设

备是否可用,而是基于一定的系统条件,例如时间、队列长度等。有两种方法可以释放所保 持的实体。 第一种方法是把实体保持在队列中,直到系统中另外一个实体对其发出允许离开的信 号。例如,一个由警察指挥交通繁忙的十字路口,可把到达十字路口的汽车当作等待前进的 滞留实体,把警察看作是为汽车发出通行信号的实体,可能有十辆车等待通过,但警察仅允 许最前面的六辆汽车通过。我们在模型 5-2 中使用过这一方法,用以保持没有按时到达的实 体。 第二种方法是让滞留的实体自己评估系统条件并决定何时前进。 例如, 考虑一辆汽车想 从一条交通繁忙的街道转弯进入另一条车道, 不幸的是既没有交通灯也没有警察。 如果汽车 是实体,则它将等待直到在街道上适当的距离内没有车辆行驶而且将驶入的车道空闲为止。 在这种情况下,实体会不断地评估以上条件,直到确认可以安全转向。假如有另外一辆汽车 紧跟着第一辆车也要转弯, 那它必须到了路口的最前面才能评估是否满足转弯条件。 我们将 在模型 9-4 中说明两种方法的使用。 还有一些情况下,实体在前进之前需要组成批(batches) 。例如,在模拟一条生产饮料 的罐装生产线最后的包装操作时, 需要把六瓶饮料组合在一起装入一个纸箱内。 当然还可以 进行进一步操作,再把 4 个六瓶装的纸箱组合在一起装入一个大纸箱中。以上过程中,所组 合的实体是相同的,而且形成了永久组合(permanent group) 。因此,六个实体进入组合过 程,只有一个实体(六瓶装的纸箱)离开这个过程。然而,如果在模拟过程中先前组合的实 体后来又被分开,则称该组合为临时组合(temporary group) 。在第一种情况下,将丢失每 个实体各自的属性信息;在第二种情况下,当组合实体被分开后,每个实体仍保留了它进入 组合前的属性信息。因此,当模拟组合操作时,需要决定是形成临时组合还是永久组合。我 们将在下面的模型 9-4 中讨论这两种方法。

9.4.2 模型 9-4:按批组合的实例
随机到达的实体在处理前先要形成批次, 例如在熏制食品时, 一般是一批一批地将它们 放入烤箱中。 一起处理的最大批量取决于设计容量。 假设每个实体必须要放置在一种特殊的 夹具上进行处理,而这些夹具很昂贵,则夹具的数量就决定了处理的容量。进一步假设这些 夹具是成对购买的,因此处理容量可为 2、4、6、8 等,另外假设批量最小为 2,才能处理。 到达的实体被送到分批区等待处理。 当可以处理时, 我们必须要决定所处理的批量大小,

或等待足够多的实体到达从而形成一个满足要求的批次。下面是相应的的决策逻辑:

原书 373 页 (程序) 只要有已到达的实体,就可以开始处理它们,但是如果批量不够( Setup > Replication Parameters 菜单开始,然后进入到模型逻辑,最后讨论 Statistic 数据模块。 我们使用 Variable 模块定义 OptQuest 中将用到的两个参数: 最大批次数或处理能力 (Max Batch)以及重新启动所需的批量(Restart),这两个变量的初始值分别设定为 10 和 4,在 Run > Setup > Replication Parameters 对话框内指明重复仿真运行的时间长度为 10000(所有 的时间均以分钟计) 。 现在让我们看看实体的到达过程,也即图 9-7 左上角的 Create-Hold 模块。Create 模块 用于产生间隔时间服从指数分布的到达实体,平均间隔时间为 1.1,模块中的其它栏目不需 输入。然后,到达实体被送到“高等操作”面板中的 Hold 模块,Hold 模块将实体保持在相 应的队列中,直到收到模型某处所发出的匹配信号为止。信号可以基于表达式或属性值,不 同的实体可以等待不同的信号,也可以都等待相同的信号。当收到匹配信号后,Hold 模块 将释放相应数量的实体,最大释放数量由 Limit 值(默认为无限)决定(除非信号中包含其 它的释放限制信息) 。我们在介绍 Signal 模块时再详细解释。

原书 P374 图 9-7 批操作模型

在我们的模型中,所有实体等待相同的信号。我们可随意地把该信号的值指定为 1,默 认限制(Limit)为无限,因为我们将在 Signal 模块里设置限制值。我们还需要定义一个队 列 Hold for Signal. Queue,以便获得有关队列的统计数据,并绘制队长的散点图动画。 现在让我们考虑仿真开始时的条件。根据变量 Restart 的初值,在第四个实体到达之前, 什么也不会发生。 由于到达的实体不会引起信号的发送, 所以必须引入其它一些机制来启动 第一批实体的操作和处理。 图 9-7 中间部分的 Create-Hold-Delay-Record 等模块序列提供了这种机制。名为 Create Scan Entity 的 Create 模块中,最大到达实体数量定义为 1,因而它在时刻 0 时仅释放一个实 体,这个实体被直接送到紧跟其后的 Hold 模块中。 Hold 模块 Scan for Condition 中,定义模块类型(Type)为 Scan for Condition,实体在 该模块中将被保持到用户所定义的条件成立为止, 然后离开这个模块。 等待的实体被放置在 用户自定义的队列(默认的)或内部队列中。如果实体进入 Hold 模块时没有其它实体等待, 则立刻检查条件是否成立,若成立则继续前进;如果 Hold 模块内有其它等待实体,则该实 体根据所定义的排队规则(默认为 FIFO)进入队列。如果有实体等待,则系统在触发离散 事件时间推进之前的最后一道工序时检查扫描条件是否成立。 如果条件成立, 则扫描队列中 的第一个实体将被送到下一个模块。到下次时间推进时,再次检查条件。因此,Hold 模块 中的等待实体是有可能被同时释放出来的, 尽管一个实体在被完全处理之后才能开始处理下 一个实体。 对于我们的模型, 所输入的条件是在 Hold 模块前的等待队列中至少有4个实体。 注意, 读者可以在 Condition 栏中通过单击右键使用 Arena Expression Builder 来输入条件。然后, 实体会被送到名为 Delay for 8 Minutes 的 Delay 模块。 当读者开始完全理解整个模型的时候, 就会意识到我们这样做的目的是为了让扫描队列中的实体个数不大于 1。

原书 P375 输入界面 9-12 Hold 模块(Scan for Condition)

现在开始运行仿真,首先创建第一个到达的实体并将它送到队列 Hold for Signal. Queue 中。 同时, 第二个 Create 模块产生一个到达实体, 并进入到队列 Scan for Condition. Queue

中。在第一个队列有四个实体之前不会发生任何事情。到那时,第二个 Hold 模块中的实体 将被释放,并被送到 Delay 模块,在其中延时 8 分钟(也即重新启动时间) 。注意在延时过 程中,其它的实体有可能到达。然后这个实体被送到 Record 模块,在这里记录启动次数的 计数器 Startups 加1。在接下来的 Assign 模块中计算新的批量大小(Batch Size) ,如输入界 面 9-13 所示。回想一下,至少对于第一个实体的处理来说,我们知道在等待队列中至少会 有四个实体存在,因此,我们的批量大小要么是等待队列中的实体数,要么是所允许的最大 批量值(如果等待的实体数量大于处理能力的话) 。

原书 P376 输入界面 9-13 为下一处理批量赋值

计算完下一批量的大小并把它赋给全局变量 Batch Size 后, 我们把实体送到 Signal 模块, 如输入界面 9-14 所示。这个模块向整个模型发出数值为 1 的信号,从而使得队列中的实体 (至多为 Batch Size 个)被释放出来。然后,这个实体进入 Record 模块,在这里记录下一 批量值,最后将其清除。

原书 P376 输入界面 9-14 Signal 模块

在模型中可以有多个 Signal 模块和多个 Hold 模块。在这种情况下,一个 Signal 模块会 向每一个类型为 Hold for Signal 的 Hold 模块发送信号,释放所有与此信号匹配的 Hold 模块 中相应数量的实体。 现在处理过程已经经历过了启动延时, 第一批实体已经被释放进入了名为 Batch Entities 的 Batch 模块。在 Batch 模块中,我们可以将多个实体聚集起来,形成只用一个单独的实体 表示的临时或永久的批组合。在本例中,我们将创建一个永久的批组合。因为组合成批的原 有实体被清除了,所以它们各自的属性值也丢失了。所形成的这个代表“批”的实体的属性

值可以根据所指定的准则 (Save Criterion) 用构成批组合的最后一个 , (Last) 第一个 、 (First) 、 或者多个实体的属性乘积(Product)或者总和(Sum)来表示。如果所形成的是临时批组合, 则组合成批的这些实体会从队列中被移除, 但所有特征会在内部保存, 从而可以在以后通过 Separate 模块来恢复。实体也可以根据匹配准则值来形成批组合。如果所形成的是永久性批 组合,今后仍然可以用 Separate 模块来重新创建出相同数量的实体,但这些实体的属性值都 会丢失掉。 通常, 到达 Batch 模块的实体需要等待, 直到凑够了所规定的批量。 但在我们的模型中, 我们定义的批量大小恰恰就等于刚刚释放到这个模块里的实体数量, 如输入界面 9-15 所示。 因此实体不必在这个模块里等待。

原书 P377 输入界面 9-15 形成批组合

代表批组合的实体被直接送到名为 Delay for Process 的 Delay 模块,在这里完成处理活 动所需的延时。注意,延时的长度取决于所处理的批量大小:3 分钟加上批中每个对象所需 的 0.6 分钟。 处理完毕的批组合被送到名为 Wait Queue Less Than 2 的 Decide 模块,在这里检查等待 队列中的对象是否少于两个。如果是,则需要停止处理过程,等待更多的对象到达。要实现 这一逻辑,可以把实体送到我们前面讨论过的 Hold 模块 Scan for Condition 中等待足够多的 对象到达以重新启动处理过程; 如果队列中至少有两个对象, 则实体被送到名为 Assign Batch Size 的 Assign 模块中,在这里设置下一个批量的大小,以重新开始下一批的处理。 由于前面几段内容相当复杂, 所以我们还是再回顾一下形成批组合的控制逻辑。 要记住 到达的实体首先被放置在 Hold 模块内,直到收到信号后再前进。第一个处理过程是通过第 二个 Create 模块所产生的唯一一个控制实体来启动的,这个实体被保持在扫描队列中,直 到最初的四个实体到达为止。变量 Restart 的初始值是 4,这个控制实体引发第一个批组合 被释放并进行处理,然后该控制实体被清除。之后,那个已完成处理的批组合实体变成了控 制实体,用来决定下一个批量的大小以及何时对下一个批组合加以释放并进行处理。 在准备好使用 OptQuest 运行模型之前, 我们需要在 Statistic 数据模块内定义输出项, 也 即队列 Hold for Signal. Queue 的最大长度,它将被用作优化过程中的约束项。我们将其命名

为 Max Batch Value,相应的表达式为 DMAX (Hold for Signal. Queue. NumberInQueue)。函数 DMAX 将返回 Arena 时间持续型统计量的最大值。定义后,这个量的统计信息将作为输出 报告的一部分被自动生成。 这个统计量的名称是队列名称后面加.NumberInQueue, 感兴趣的 读者可以在帮助主题“Statistics (Automatically Generated by SIMAN)”内找到相关信息。 最后,我们对 OptQuest 加以设置,令变量 Max Batch 从 4 变到 14,每次增量为 2(离 散增加) ,变量 Restart 从 2 变到 10,每次增量为 1(离散增加) ,目标是使重新启动的次数 最小化,同时要求 Max Batch Value 统计量的值不超过 25,所得到的最好的解如下: Max Batch = 10 Restart = 8 Max Batch Value =24.9 Startups =30.6

9.5 重叠资源
在第 4 到第 8 章,我们主要使用“基本操作”面板、 “高等操作”面板和“高等运送” 面板中的模块建模。 虽然我们已经在几个不同的模型中使用过这些模块, 但还没有充分挖掘 出其所有的性能。 我们在前面章节开发模型时,不仅向读者介绍一些新的 Arena 构件,而且还尽量介绍许 多有用的建模技术。 我们一直借助一些例子来阐明各种建模能力, 而有时候构想出一个好的 例子并不容易。我们将要介绍的一个实例可能有点长,不仅仅在模型描述方面,而且在开发 模型的方式方面。 可是如果读者跟我们顺利完成模型的建立以后, 你们一定能增添几手建模 技巧。

9.5.1 系统描述
我们将要建模的系统是一个具有三个工作站的、紧密耦合的生产系统。我们说“紧密耦 合” ,是因为系统独特的零件到达过程,以及工作站之间存在有限的零件缓存空间。 我们假设原材料供应无限制, 并按需求数量送到系统中。 当一个零件进入第一个工作站 后,自动向临近的仓库发出继续补充零件的请求。由于仓库正还有其它的任务,所以所补充 的零件并不能总是及时运到。 我们不在细节上模拟这种活动, 而是假设在补充零件的请求被 执行之前,有一个均值为 25 的指数交货延迟(所有的时间均为分钟) ,可以认为这个时间是

交货准备时间。而货物运送时间则服从均匀分布 UNIF(10,15) 。为启动仿真,我们假设 已经有两个零件准备好交付到第一个工作站。 所补充的零件到达第一个工作站时被保存在缓冲区中, 直到工作站可用为止。 零件进入 第一个工作站后会立即请求一名调整人员前来调整设备,假设调整时间为 EXPO(9) 。完成 调整后,工作站开始加工这个零件,加工时间为 TRIA(10,15,20) 。加工完后零件被送 到工作站 1 和 2 之间的缓冲区中。这个缓冲区只能容纳 2 个零件,如果缓冲区空间满了,则 工作站 1 将停止加工(也即被阻塞) ,直到缓冲区空间被释放。我们假设在工作站之间的运 送时间可以忽略不计,或者为 0。 在工作站 2 内有两台几乎相同的机器, 它们唯一的区别在于加工零件的时间不同, 机器 2A 的加工时间为 TRIA(35,40,45) ,机器 2B 的加工时间为 TRIA(40,45,50) 。等待 的零件将在先空闲下来的机器上加工,如果两台机器都空闲,则选择机器 2A。在这个工作 站内不需要调整设备,加工完的零件被运送到工作站 3。工作站 2 和 3 之间没有缓冲区,因 此只有在工作站 3 空闲时,才能把零件运送过去。 (这确实会影响系统的性能! )如果机器 2A 和 2B 上都有加工完的零件等待运往工作站 3,则首先运送机器 2A 上的零件。 当零件进入工作站 3 时,需要一名调整人员(和工作站 1 是同一个调整人员)来调整设 ,工作站 3 的加工时间为 TRIA(9,12,16) ,加工完毕后 备,调整时间假设为 EXPO(9) 零件离开系统。 每个工作站都可能发生故障, 工作站 1 和 3 的平均正常运行时间为 600 分钟, 平均故障 时间为 45 分钟(也即修理时间) 。工作站 2 的机器 2A 和 2B 的平均正常运行时间为 500 分 钟,平均故障时间为 25 分钟,所有的正常运行时间和故障修理时间都遵从指数分布。有一 点细微但很重要的地方是正常运行时间是按机器加工零件的时间来计算的, 而不是所有的时 间均计在内。 现在考虑更加复杂的情况, 假设我们感兴趣的是每个工作站中机器处于不同状态的时间 百分比,这可以让我们更进一步了解如何改进系统性能。例如,如果工作站 1 的机器被阻塞 了很长时间,我们可能需要考虑增加工作站 2 的加工能力。 下面是不同机器的各种可能状态: 工作站 1:加工(Processing) 、空闲(Starved) 、阻塞(Blocked) 、故障(Failed) 、等待 调整人员(Waiting for setup operator) 、以及调整(Setup) 。 机器 2A 与 2B:加工(Processing) 、空闲(Starved) 、阻塞(Blocked) 、故障(Failed) 。 工作站 3:加工(Processing) 、空闲(Starved) 、故障(Failed)、等待调整人员(Waiting for

setup operator) 、以及调整(Setup) 。 我们也想了解一下调整人员花在工作站 1 和 3 上的时间百分比, 相应的状态包括: 在工 作站 1 调整(WS 1 Setup)(在工作站 3 调整)WS 3 Setup、以及空闲(Idle) 、 。 这些都是用于确定耦合系统有效性的典型测度, 为找出真正的系统瓶颈位置提供了大量 信息。既然我们已经探讨了这样一些测度,为什么不做得更彻底一些!假如我们想知道零件 处在所有可能状态中的时间百分比, 确定这个可是一件相当困难的事情。 首先我们要确定系 统逗留时间,即从零件交付运送开始,到在工作站 3 上完成加工为止。可能的零件状态有: 运往工作站 1(Travel to WS 1) 、等待工作站 1(Wait for WS 1) 、在工作站 1 等待调整(Wait for setup at WS 1) 在工作站 1 调整设备 、 (Setup at WS 1) 在工作站 1 中加工 、 (Process at WS 1) 、被阻塞在工作站 1 中(Blocked at WS 1) 、等待工作站 2(Wait for WS 2) 、在工作站 2 中加工(Process at WS 2) 、被阻塞在工作站 2 中(Blocked at WS 2) 、在工作站 3 等待调整 (Wait for setup at WS 3) 、在工作站 3 调整设备(Setup at WS 3) 、以及在工作站 3 中加工 (Process at WS 3) 。当我们在建立模型时,将会直接加入各种资源状态。但只有在建完模型 后才会考虑各种零件的状态。请相信我们,我们知道在做什么。

9.5.2 模型 9-5:紧密耦合的生产系统
在建立模型时,我们会用到各种不同模块。首先,先来建立描述零件到达过程和工作站 1 的模块,如图 9-8 所示。

原书 P380 图 9-8 到达零件与工作站 1 因为下面将用到的模块读者几乎已经全部见过, 所以我们不再提供所有的输入界面, 但 会提供足够的信息,以方便读者自己重新创建这个模型。当然读者也可以打开 model 09-05.doe,一步步地跟着做。 首先, 为系统提供的最初两个零件到达, 所有其它零件的到达由零件进入第一个工作站 后所发出的补充请求来确定。 9-8 左上角的唯一的一个 Create 模块中需要输入三个数据项: 图 名称(Name) 、批量大小(Batch Size)处输 2、最大到达数量(Max Arrivals)处输 2。即

Create 模块在时刻 0 将创建两个实体(零件) ,然后就没什么作用了  在余下的仿真过程 中,这个 Create 模块不再创建实体。这两个初始实体被送到 Assign 模块,在这里给实体赋 两个属性值:把当前时间赋给属性 Enter System,即零件进入系统的时间;把从 UNIF(10, 15)中产生的随机数赋给属性 Route Time,即零件从仓库到第一个工作站的运送时间。由于 我们对详细的零件状态信息感兴趣,故把这些零件实体送到 Record 模块,在这里根据表达 式 Route Time 的值统计运送时间(命名为 De1ivery Time) 。然后实体被送到随后的 Station 模 块,这个站的站名被定义为 Warehouse(仓库) 。接下来,利用 Route 模块定义从仓库 (Warehouse)运送到工作站 1(WS 1 Station)的路径,并用我们前面赋过的属性作为 Route time。 在完成运送后, 零件到达名为 Station for WS 1 的 Station 模块, 并在其后的 Seize 模块中 试图占用 WS 1(工作站 1)的一个单位资源。现在我们需要考虑三个额外的需求。首先, 需要指明资源的状态,从而确保正确地保存相关统计量;其次,我们需要请求补充零件;最 后在零件加工之前需要调整设备。 首先,利用 Resource 数据模块定义资源。我们需要输入六种资源:WS 1 (工作站 1) 、 WS 2A(工作站 2 中的机器 A) 、WS 2B(工作站 2 中的机器 B) 、WS 3(工作站 3) 、Setup Operator(调整人员)和 Buffer(缓冲区) ,前五种资源的容量为 1, Buffer 的容量为 2。 回忆 4.2.4 节, 我们向读者展示了如何利用 Frequencies 生成关于队列长度的频率统计量。 为了获得关于资源的频率统计量, 我们先要定义状态集。 可利用 “高等操作” 面板中的 StateSet 数据模块来定义状态集,我们建立五个状态集:WS 1 StateSet、WS 2A StateSet、WS 2B StateSet、WS 3 StateSet 和 Setup Operator StateSet。输入界面 9-16 显示了工作站 1 的状态集 (WS 1 StateSet) 。

原书 P381 输入界面 9-16 WS 1 StateSet 中的状态

我们使用 Failure 数据模块定义两种故障(WS 1_3 Failure 和 WS 2 Failure) 。然后返回 Resource 数据模块,添加所定义的 StateSet 和 Failure。添加 Failure 时,选择 Ignore 作为故 障规则(Failure Rule) 。 现在回到图 9-8 的模型逻辑。实体进入工作站 1 后,需要占用资源 WS 1,如输入界面

9-17 所示。

原书 P382 输入界面 9-17 工作站 1(WS 1)的 Seize 模块

接下来, 我们考虑零件补充和设备调整活动。 已经占用了工作站资源的零件会进入紧接 其后的 Separate 模块, 在其中创建一个实体副本。 这个实体副本被送到名为 Warehouse Delay 的 Delay 模块,在这里按照补充零件请求的处理时间进行延时,直到零件开始运送为止,延 时的时间为 EXPO(25) 。然后我们把这个实体副本送到最初的两个零件所经过的一系列模 块中,而原始实体在离开 Separate 模块后被送到其后的 Assign 模块中,在这里把资源 WS 1 的状态赋为 Waiting for Setup Operator,如输入界面 9-18 所示。

原书 P382 输入界面 9-18 资源状态赋值

接下来,实体进入名为 Seize WS 1 Setup 的 Seize 模块,在这里实体请求占用调整人员, 如输入界面 9-19 所示。注意,我们指定调整人员的资源状态为 WS 1 Setup,这样我们就可 以获得关于资源 Setup Operator 的频率统计。

原书 P383 输入界面 9-19 占用设备调整人员

到目前为止,读者可能会有些疑惑地问: “这是在干什么啊?”其实我们已经提前告诫 过读者,这个问题有点绕。等我们完成了对工作站 1 的建模后,我们将对整个的事件顺序再 总结一下。所以还是让我们先继续吧。 在接下来的名为 Assign Setup for WS 1 的 Assign 模块中,我们把资源 WS 1 的状态设置 为 Setup, 然后在名为 Delay WS 1 Setup 的 Delay 模块中实现对调整活动的延时。 在完成调整

后,释放资源 Setup Operator,并将资源 WS 1 的状态改为 Processing,并完成对加工过程的 延时。加工完毕后,将资源 WS 1 的状态改为 Blocked,此时我们还不知道在工作站 2 的缓 冲区中是否还有空间,因此需进入名为 Seize Buffer 的 Seize 模块请求缓冲区空间, 一旦有了 缓冲区空间则释放资源 WS 1,并前往工作站 2。 现在让我们总结一下零件在工作站 1 的一系列活动。 在时刻 0 创建两个零件实体, 让我 们只跟踪其中一个零件。 零件被贴上了到达时间的标记, 生成相应的运送时间并赋给某个属 性。然后,记录零件的运送时间,并把它运送到工作站 1。进入工作站 1 后,零件加入队列 等待资源 WS 1。占用资源后,零件退出 Seize 模块,然后复制一个用于继续补充供货的零 件,这个补充供货零件被送到第一个零件进入系统的地方。接着,零件将服务器资源的状态 赋值为 Waiting for setup,并排队等待调整人员。占用调整人员后,将零件状态设置为 Setup, 并将资源 WS 1 的状态改为 Setup。完成调整延时后,释放调整人员,并将资源 WS 1 的状态 改为 Processing,并进行加工延时。加工完毕后,零件排队等待占用资源 Buffer(容量为 2) 的一个单元,在排队等待期间将服务器状态设置为 Blocked。占用缓冲区资源后,释放资源 WS 1,退出工作站 1,并占据着一个单元的 Buffer 资源。 图 9-9 显示了包含两台机器的工作站 2 的模块组成。 零件到达工作站 2 后,进入名为 Seize WS 2 的 Seize 模块,等待工作站 2 中的一台机器 可用。我们首先创建资源集合 WS 2 Set,其中包括资源 WS 2A 和 WS 2B。从集合中选择了资 源后, 将相应的集合下标保存在实体属性 WS 2 Resource 中。 我们根据优先顺序准则 (Preferred Order rule)选择资源,所以当两台机器都空闲时,较快的机器(WS 2A)将被选中。

原书 P384 图 9-9 工作站 2 的模块组成

回忆一下,到达工作站 2 的零件已经占据了缓冲区的一个单元。因此,只要零件占用了 两台机器中的一台, 就会释放缓冲区。 这一过程在随后的 Release 模块 Release Buffer 中完成。 零件占用了一台可用机器并释放缓冲区资源后,将进入 Decide 模块 Have WS 2A。这个 模块根据属性 WS 2 Resource 的值来决定占用哪台机器,而这个属性值是在前面 Seize 模块 中把资源分配给零件时赋的。如果集合中的第一个资源 WS 2A 被分配给了零件,则这个属 性值会被赋值为 1。我们利用这一逻辑来决定分配哪台机器给零件,然后把零件送到 WS 2A

或 WS 2B 的逻辑结构中。图 9-9 中间部分的五个模块是 WS 2A 的,下面五个模块是 WS 2B 的。 由于工作站 2 不需调整, 故在第一个 Assign 模块中给机器资源的状态赋值为 Processing, 然后零件被送到 Delay 模块,完成对零件的加工延时。在最后一个 Assign 模块中将机器资 源的状态改为 Blocked。 然后,零件在随后的 Seize 模块中试图占用资源 WS 3。如果资源不可用,则零件在队列 Seize WS 3. Queue 中等待。在 Queue 模块中,我们定义这个队列为两个 Seize 模块的共享队 列。现在,如果有两个等待零件(每台机器一个) ,而我们希望让机器 WS 2A 上的零件排在 队列的前面,则可以通过选择排序规则为“属性值 WS 2 Resource 小的优先” (Low Attribute Value)来实现。这样,队列中的所有实体将根据它们的 WS 2 Resource 属性值排列,从而确 保 WS 2A 上的零件具有优先权。 一旦一个零件分配到了资源 WS 3,就会被立刻运送到那台机器上,图 9-10 展示了用于 模拟工作站 3 的模块。 读者可能注意到了, 这些模块看起来与工作站 1 的那些模块非常相似, 它们本质上是相同的。实体进来后首先将工作站资源的状态赋值为 Waiting for setup,然后 试图占用调整人员。实体得到了调整人员后,资源 WS 3 的状态被改为 Setup。接下来完成 对零件的调整延时,然后释放调整人员,将资源 WS 3 的状态改为 Processing。然后完成对 零件的加工延时,加工完毕后释放资源 WS 3,记录零件的系统逗留时间,最后清除零件实 体。

原书 P385 图 9-10 工作站 3 的模块组成 现在, 模型的逻辑部分已经完成了, 我们还需要收集工作站和调整人员的频率统计数据。 这些频率统计数据是根据资源状态来采集的,输入界面 9-20 给出了为采集这些频率数据而 需要在 Statistic 模块中定义的内容。 我们在一开始描述问题时, 提到想要得到零件在所有状态上所花费时间的百分比。 要获 得资源在所有状态下的这些信息是相当简单的,只要定义好资源状态,Arena 将自动使用 Frequencies 功能来收集这些信息并形成报告。不幸的是,Frequencies 只对资源有效。

原书 P385 输入界面 9-20 用于收集频率数据的 Statistic 模块

对于零件或实体来说, 收集这些同类信息是很困难的, 因为零件的状态可能跨越了在好 几种资源上的活动。 这就带来了一个建模方面的问题: 怎么样才能以最好的方式来获得这些 信息呢?在介绍我们的方法之前,先来讨论几种可选的方案,并分析一下它们的不足。 第一种想法是引入一种变量,这个变量随着当前零件的状态而改变。然后,我们针对这 个变量来统计其各种情况的频率,就像在 4.2.4 节的模型 4-2 中统计返工区域里的零件队长 变化频率那样。当然,这需要我们在建立模型时,无论何时零件状态发生了变化,都要对变 量赋值。虽然这听起来挺不错,可是当系统中同时存在多个零件时,这个方法就靠不住了。 如果我们把系统中的零件数量限制为一个, 这种方法会很好, 但是在我们的问题中是有多个 零件的,所以我们只能考虑采用其它的方法来收集这些信息。 第二种想法是假设所有需要的信息都已经收集好了(这是可以做到的) ,这样我们只需 要在运行结束后汇集这些信息,并计算出我们想要的统计量。在每次运行结束后,Arena 自 动调用一个汇总信息的程序,我们也可以编写用户代码(参见 9.2 节)来实现这种功能。这 种方法的缺点是, 如果我们想在运行结束之前去看仿真总结报告的话, 是看不到这些信息的, 而且这种方法所需要的工作量很大,所以我们还是寻求其它的方法。 我们所采用的第三种方法,是考虑在 Statistic 数据模块中添加附加的输出统计量,这并 不是说读者还需要额外再去收集统计数据, 而是在模型已经收集的统计数据基础上计算一些 额外的输出值。 由于当前模型已收集了所有的信息, 虽然在形式上还不是我们所需要的那样, 但我们可以利用这些信息得出关于零件状态的数据。首先,我们在 Run>Setup>Replication Parameter 对话框内输入重复仿真运行的时间长度为 50000 个时间单位。 如果我们现在运行模型的话,就会得到如图 9-11 所示的结果。让我们暂时先把注意力 集中在 WS 1 Resource 的频率统计量上,从中可以看出,工作站用于加工零件的时间仅为 50.21%,在 Waiting for setup 状态和 Setup 状态上花费了大量的无效时间。

原书 P386 图 9-11 紧密耦合系统的频率报告

9.5.3 模型 9-6:添加零件状态统计量
在继续建立模型之前, 让我们先考虑一下要想获得关于零件状态信息的话我们需要做些 什么。我们所要统计的是零件处于各状态上的时间百分比,零件状态在前面已经定义过,包 括:Travel to WS l(运送到工作站 1) 、Wait for WS 1(等待工作站 1) 、Wait for Setup at WS 1(在工作站 1 等待调整) 、Setup at WS 1(在工作站 1 调整设备) 、Process at WS 1(在工作 站 1 加工) 、Blocked at WS 1(在工作站 1 被阻塞) 、Wait for WS 2(等待工作站 2) 、Process at WS 2(在工作站 2 加工) 、Blocked at WS 2(在工作站 2 被阻塞) 、Wait for Setup at WS 3 (在工作站 3 等待调整) 、Setup at WS 3(在工作站 3 调整设备) 、以及 Process at WS 3(在 工作站 3 加工) 。 我们计算这些数值所需要的所有信息都已经包含在输出总结报告里了。 让我们先考虑第 一个零件状态 Travel to WS 1, 平均运送时间为 12.517, 总共记录了 1672 个零件; 而根据 1665 个零件记录得出的平均系统逗留时间为 225.07。读者可能注意到了,在仿真终止时仍就有 7 个零件(1672-1665)在系统中,关于这一点我们将在后面加以讨论。因此,若要得到零件 处于“运送到工作站 1”状态的平均时间百分比,可以利用下面的表达式来计算:

原书 P387 第一个公式 我们可以利用这种方法计算所有需要的数值。 也即, 用花费在某个活动上的所有零件的时间 之和,除以零件花费在所有活动上的时间总和,再乘以 100。因为计算过程中的最后两步都 是一样的,所以可以先定义一个表达式 Tot 来表示这个数值。表达式的形式如下:

原书 P387 第二个公式 TAVG 和 TNUM 是 Arena 系统变量,分别返回计数型统计量(Tally)的当前平均值和观测 值数量,自变量是计数型统计量的标识符。此处使用的是在 Record 模块里定义的计数型统 计量名称。若在 Arena 的某个模块里已经定义过计数型统计量名称(例如排队时间统计量) , 当再次使用时我们建议读者通过查看模块中的下拉菜单或者帮助文件来获取其确切的名称。

利用计数型统计量可以计算我们所需的三种零件状态的统计信息:即 Travel to WS 1、 Wait for WS 1 和 Wait for WS 2,计算这三个数值的表达式如下:

原书 P387 第三组公式 其余的零件状态信息包含在频率统计量中。 正如读者所期待的, Arena 也提供一些能够返回有关频率信息的系统变量。 变量 FRQTIM 能够返回指定资源处于指定类别或状态的总时间,这个变量的完整表达式为

原书 P387 第四个公式 其中 Frequency ID 是所要统计频率的资源名称, Category 是类别或状态名称。因此, 关于状态 Setup at WS 1 的表达式为

原书 P388 第一个公式 其中,WS 1 Resource 是我们先前在 Statistic 数据模块中定义的频率统计量的名称,Setup 是 资源 WS 1 的设备调整状态的名称(这是我们在 StateSet 数据模块中定义的) 。 如果我们按这种方式来定义所有的表达式,则其余 9 个表达式为:

原书 P388 第二组公式 读者应当注意到了,在工作站 2 可能有两个零件在加工或被阻塞,因此在工作站 2 用 2A 和 2B 表示两种资源。 现在, 我们已建立了一种方法及相应的表达式来计算零件平均花费在每个状态上的时间 百分比,我们将使用 Statistic 数据模块来把这些信息添加到总结报告中去,输入界面 9-21

显示了添加到 Statistic 数据模块中的新统计量。

原书 P388 输入界面 9-21 统计零件状态的统计量

在继续进行之前,让我们先讨论一下总结报告中运送时间(Delivery Time)观测值和系 统逗留时间(Cycle Time)观测值个数不一致的问题。由于我们所采用的数据采集方法的特 点、以及仿真运行开始时系统处于“空且闲”的状态,这种不一致总是存在的。有几种方法 可以处理这种不一致问题,一种是在我们终止仿真运行时,停止零件进入系统,同时让系统 中的所有零件都完成处理过程。 虽然这样可以得到相同数量的观测值, 可实际上相当于在仿 真中添加了一个停工时间, 这意味着在仿真开始和结束时存在潜在的瞬态条件, 从而会影响 资源统计的结果。 我们也可以延长仿真运行周期, 直到这些观测次数之间的差别很小, 从而减小对我们结 果的影响。 这对于小规模的问题很容易实现, 但对于大规模的问题则可能导致相当长的运行 时间。 如果我们想要确保所有的零件状态统计都是基于相同的零件集合, 则可以把所有零件 花费在每个活动上的时间全都存储在实体属性里, 当零件退出系统后, 再根据相应的记录来 统计这些时间。虽然这种方法是可行的,但需要对模型做大量的改动,我们认为不值得这么 做。 如果退一步想,读者可能会意识到,这种不一致问题并不仅仅只存在于这个问题中,几 乎所有的稳态仿真都存在这一问题。 我们建议读者在这种情况下采用与稳态仿真分析相同的 方法,通过添加一个预热时间来消除初始瞬态问题。因为我们的系统是紧密耦合的,不会有 很长的队列, 而且系统中的零件数量一般不会有很大的变化。 因为采用了指数分布来模拟从 仓库补充供货所发生的延时, 所以有可能存在系统中没有零件的情况, 尽管这种情况极为罕 见。另外一种极端的情况是系统中(最多)可能有 8 个零件。因此,通过添加一个预热时间, 当系统已经进入了正常运行后再开始收集统计数据, 这样就可以减小计数型统计量的观测次 数差异。现在,让我们假设有一个 500 分钟的预热期,可通过 Run>Setup>Replication Parameter 对话框来定义。加入我们所模拟的系统规模很大,则在系统中有可能会存在很长 的队列,这是就需要重新考虑处理方法了。 如果现在运行模型,则总结报告中就会增加图 9-12 所示的新信息。

原书 P389 图 9-12 总结报告中的新信息

9.6 建模中的其它问题
我们写这本书的目的并不是想完整介绍 Arena 仿真系统中所有可用的功能。在“基本操 作”面板和“高等操作”面板中,仍有几个模块我们没有讨论,而且在“操作块”面板和“构 模元素”面板中,还有更多的模块没有涉及到。因此,我们鼓励读者在闲暇时自己尝试使用 这些模块,并利用联机帮助来了解更多的内容。在多数情况下,读者可能根本用不到这些额 外的功能。在结束本章之前,我们再简要讨论几个前面没有涉及到的功能,对这些专题不需 要更深入地去理解了,只须知道就行了。

9.6.1 导引运输工具
Arena 有一套设计完整的功能来应用导引运输工具。这些功能不仅对于模拟自动导引车 辆(AGV)系统有用,而且对于使用移动运货车、夹具和支架等工具的仓储系统和物料搬 运系统也很帮助。有意思的是,这些功能也可以很好地表示游乐园中的游览车。要详细说明 这个专题的话恐怕需要一两章的篇幅,所以本书就不介绍了,可读者可以参阅 Pegden, Shannon, and Sadowski (1995)一书的第 9 章。

9.6.2 并行队列
在“操作块”面板中有两个很特殊的模块 Qpick 和 PickQ,虽然很少使用它们,但有时 能大大方便建模过程。Qpick 模块能够用于表示这样一种过程:根据某种决策准则从两个或 更多的不同队列中选出下一个处理或移走的实体。Qpick 模块一般位于一系列彼此分离的 Queue 模块和一个分配某种有限资源的模块(例如 Allocate、Request、Access 或 Seize 模块) 之间。假设有三种不同的实体流汇集到一点,并在这里试图占用一种相同的资源,此外,假 设读者希望保持各实体流中的实体是彼此分开的。图 9-13 显示了需要引入 Qpick 模块的这

部分模型,每个实体流中的实体分别进入各自的队列,Qpick 模块与这些 Queue 模块之间通 过模块标号(Labels)建立联系。当资源可用时,Qpick 模块决定从哪个队列中选择实体分 配资源。注意,这里使用的 Seize 模块来自“操作块” (Blocks)面板,而不是“高等操作” (Advanced Process)面板。当使用“操作块”面板中的模块时,Arena 不会自动定义队列和 资源等,因此必须从“基本操作” (Basic Process)面板或“构模元素” (Elements)面板中 取出相应的模块来定义这些对象。

原书 P391 图 9-13 Qpick 模块的使用 PickQ 模块可用于表示如下一种过程:只有一个到达实体流,而读者需要根据某种决策 准则在两个或多个队列中挑选一个来放置实体。假设有一个到达实体流,有两个输送设备, 实体到达后将被放到其中一个输送设备上运走,图 9-14 显示了需要 PickQ 模块的这部分模 型(Access 模块来自“高等运送”面板) 。注意,不能给 Access 模块指定内部队列,而且 有关用哪个输送设备来运送实体的决定取决于队列的特性,而不是输送设备。可利用 PickQ 模块把实体送到 Access、Seize、Allocate、Request、Queue 模块,或其它任何前面带有队列 的模块中。

原书 P391 图 9-14 PickQ 模块的使用 现在让我们探讨一下有关 “分离” 队列的问题。 如果读者使用 “操作块” 面板中的 Queue 模块,则可以选择把队列定义为“分离” (Detached)的形式,这意味着这个队列没有直接 连接到下游的模块上。这种队列可以间接地连接到后续模块上(例如通过 Qpick 模块) ,也 可以不需要明显的连接。例如,读者可能想要用到一组实体,这些实体的属性中所包含的信 息需要在仿真过程中加以访问或修改。 假如你想要做的仅此而已, 则可以很容易地使用定义 成矩阵形式的变量(Variable)或外部数据库来实现。使用队列的优势在于,你可以改变实 体在队列中的排列位置,而且可以通过 Arena 内部变量来访问或修改实体的属性值,还可以

使用“操作块”面板中的 Search、Copy、Insert、Pickup 和 Remove 模块(或“高等操作” 面板中的 Search、Remove、Pickup 和 Dropoff 模块)作用在队列中的实体上。注意,Arena 只在实体进入队列时根据相应的规则把它安排到适当的位置上, 如果你修改了用于确定排列 位置的实体属性,则必须把这个实体从队列中移除出来,然后再放回去,这样才能生效。

9.6.3 决策逻辑
有时,根据具体情况可能需要在模型中引入更复杂的决策逻辑,Arena 在“操作块”面 板中提供了几种有用的模块。 第一种是用于建立 if-then-else 逻辑的模块组合, 包括 If、 ElseIf、 Else 和 EndIf 模块,此处我们就不详细解释这些模块了,但我们鼓励读者通过阅读帮助文件 来使用这些模块实现这一逻辑。 虽然这些模块可以帮助建立功能强大的逻辑结构, 但使用时 需要非常小心,以确保逻辑结构的正确。在使用 If 和其匹配的 EndIf 模块时,要保证它们之 间的所有模块在 Arena 中是以图形方式连接在一起的 (包括它们内部的任何 ElseIf 或者 Else 模块组) 。在 If / EndIf 逻辑结构中可以使用很多模块,例如 Assign、Seize 和 Delay 模块等, 但不包括那些无法以图形方式连接的模块,如 Route、Convey 和 Transport 模块。还有可以 实现 do-while 逻辑结构的模块组合,包括 While 和 EndWhile 模块,前面提到的注意事项同 样适用于这些模块。 如果读者真的需要建立这类逻辑结构,可以有几种选择方案。最简单的就是使用标号 (Label)和下一站标号(Next Label)来建立模块间的联系,而并非采用直接的图形连接。 虽然这样没什么问题, 但是无法把逻辑流程显示出来。 另外一种方案就是把逻辑结构写成外 部的 SIMAN .mod 文件,然后使用“操作块”面板中的 Include 模块把定义好的逻辑结构导 入你的模块中去。不幸的是教学版软件不能使用这种方法。最安全、也是使用最多的方法是 采用 Decide 模块和 Branch 模块来实现这种逻辑结构,虽然这种形式看起来不是很优雅,但 却总是有效的。

9.7 练习
9-1 包裹到达一个卸载设施,到达时间间隔为指数分布 EXPO(0.46) 。一共有五种不同类型 的包裹,每种包裹到达的可能性相等,且每种都有自己的卸载站。卸载站位于一个环形的输 送设备旁边, 每个卸载站的队列只能容纳 2 个包裹。 到达的包裹首先进入一个无限容量的队 列等待输送设备上的可用空间,每个包裹需要 2 英尺的空间。在进入环形输送设备后,包裹

被输送到其相应的卸载站,如果卸载站的队列中还有空间,则包裹被自动转移到队列中去, 转移不需要花费时间, 然后等待专门的卸载人员卸载 (所谓专门的卸载人员是针对卸载站的, 而不是针对包裹) ,卸载时间服从 EXPO(2)分布。如果包裹到达其卸载站时,发现队列已 满,则继续停留在输送设备上运行,并尝试再次被卸载。每个卸载站相隔 10 英尺,输送速 度是每分钟 12 英尺。建立动画模型。

包裹到达站

卸载站 1

卸载站 2

卸载站 5

卸载站 4

卸载站 3

原书 P393 图形 (1)运行仿真 500 分钟,统计系统逗留时间(所有类型的包裹合一起,不按类型区分) 和包裹到达站的队列长度。 (2)以下哪一种方案对平均系统逗留时间的影响更大一些:提高输送设备的速度到每 分钟 15 英尺,或者把每个卸载队列的容量增加到 4? 9-2 一个组合输送系统由一个包含三个区段的主输送设备和两个辅助输送设备组成, 如下图 所示。不同的包裹流分别到达各输送设备的输入端,到达时间间隔为 EXPO(0.75) 。到达 的包裹首先要等待输送设备上的可用空间。 到达主输送设备输入端的包裹将被直接输送到系 统的退出点; 而到达两个辅助输送设备输入端的包裹则先要被输送到主输送设备处, 并在那 里等待获得所需的运送空间, 一旦有了足够的可用空间, 包裹将退出辅助设备并登上主输送 设备,被输送到系统的退出点。所有的输送区段长 20 英尺(注意,主输送设备有三条这样 的区段) ,所有的输送设备都是可聚集的,且以每分钟 15 英尺的速度传送,每个包裹需要 2 英尺的输送设备空间。当包裹到达系统退出点时,需要 0.2 分钟的卸载时间,在这期间包裹 仍将占用它在输送设备上的空间。

原书 P394 第一个图形

建立以上系统的模型并制作动画, 运行模型 300 分钟, 统计输送设备状态的有关信息 (例 如每个区段上正在输送和聚集的包裹数量)和系统逗留时间。 9-3 一个小型自动悬挂输送系统包含 6 个工作站,零件被放置在托盘上,托盘在系统中的移 动,并在每个工作站处停下来完成一道工序,系统中共有 12 个托盘。在工作站 1 处把零件 毛坯放在一个空托盘上,然后零件和托盘一起向前移动,直到完成所有的操作,最后装配好 的零件在工作站 6 被移下托盘。 这个悬挂输送系统以每分钟 4 英尺的速度移动, 每个托盘需 要 2 英尺的空间。除了工作站 6 和工作站 1 相隔 20 英尺外,其余相邻工作站间隔均为 10 英尺。下图给出了工作站的布局,在每个工作站的操作时间均为 WEIB(3.31, 4.2)分钟。

原书 P394 第二个图形 建立以上问题的模型并制作动画,运行模型 1500 分钟,统计每小时的产量。 (提示:用 可聚集式输送设备模拟悬挂输送系统。 在仿真开始的时候, 在工作站 6 把空的托盘载入系统, 这些托盘被载入后将成为系统的永久部分。 )分析托盘数量对每小时产量的影响,是不是多 于 12 个托盘会更好?有没有最优的托盘数量?要用有效的统计分析来支持你的观点。 9-4 零件到达一个小型生产系统,到达时间间隔服从 TRIA(6, 13, 19)分布。所有零件从装 卸区进入系统,先被运送到工作站 1,然后运送到工作站 2、再被运送到工作站 3,最后被 运回装卸区,如下图所示。所有的运送都是通过两辆运货车完成的,每辆运货车的运送速度 均为每分钟 60 英尺, 从装卸区到工作站 1 和工作站 3 的距离为 50 英尺, 工作站之间的距离 也是 50 英尺。在工作站 1 和工作站 3,零件先要从车上卸下后才能加工;而在工作站 2,零 、UNIF 件直接在运货车上加工。在工作站 1、2 和 3 的加工时间分别为 8 + WEIB(4.4, 4.48) (8, 11)和 TRIA(8, 11, 18)分钟。假设忽略所有的装载和卸载时间。

原书 P395 图形 建立以上问题的模型并制作动画, 运行模型 10000 分钟, 统计运货车和工作站的利用率, 以及零件的系统逗留时间。 9-5 订单到达车间的时间间隔为 EXPO(30) ,所有时间均为分钟。每个订单所订的零件数

量服从分布 UNIF(3, 9) (截断取整) 。收到订单后,零件被立刻从仓库中取出并送到准备 区(运送时间为 0) ,在这里对每个零件单独进行准备操作,准备操作的时间为 TRIA(2, 3, 4) 。经过准备操作后,零件被运送到集结区(运送时间为 4 分钟) ,等待最终订单核准。最 终订单核准所需时间为 UNIF (180, 240) 然后零件被投放加工。 , 加工时间为 TRIA (3, 4, 6) 。 加工完毕后,零件被组合成批,送到包装人员那里进行包装(运送时间为 0) ,每批零件的 包装时间为 TRIA(8, 10, 14) 。零件包装完毕后退出系统。在订单核准过程中,有 4%的订 单被取消,把这些订单上的零件从集结队列中移除并送回仓库(运送时间为 0) 。建立以上 问题的仿真模型,并运行 20000 分钟(预热运行 500 分钟) ,统计所取消的订单数量、取消 的 零 件 数 量、 交 付 订 单的 系 统 逗 留时 间 、 以 及资 源 利 用 率, 另 外 , 利用 频 率 统 计量 (Frequencies)确定集散区所需的用于存放零件的挂架数量(每个挂架可存放 25 个零件) 。 (提示:利用 Hold/Signal 模块进行订单核准,利用 Search/Remove 模块取消订单。 ) 9-6 一个食品加工系统加工每批 25 磅的原料,加工时间为 1.05+WEIB(0.982, 5.03)分钟。 假设原料供应是无限的。一批原料加工完毕后,就从加工机器上拿下来,放到分割机上,将 其分割成 1 磅的单元,分割机的分割操作时间为每磅 0.05 分钟。注意,在这里不是按批处 理,而是每 0.05 分钟分割出 1 磅单元。然后,这些一磅的单元被送到 3 个包装机器中的一 台。每个包装机器都有自己的队列,单元将被送到队列最短的队列中去。这些包装机器功能 是相同的,但包装操作的时间不同,其包装时间分别为常量 0.20、0.22 和 0.25 分钟。完成 包装后的产品在包装机器上被组合成批,每批六个单元,并准备运走完成最后的封装。一旦 凑齐了六个单元的批量, 就将它们送到封装人员那里进行封装, 封装时间为 0.18+WEIB (0.24, 4.790)分钟。最后,封装好的产品离开系统。假设忽略所有的运送时间。 (1)建立以上问题的仿真模型并制作动画,运行 1000 分钟,统计资源利用率、队长和 封装运走的产品数量。 (2) 修改模型, 使其包括包装机器故障情况, 假设包装机的正常运行时间为 EXPO (20) , 维修时间为 EXPO(1) 。 (3)在(2)的基础上添加质量检查,每半小时检查一次,首先从第一台包装机的队列 开始,寻找在队列中超过 4 分钟的产品,也就是说,寻找那些离开加工机器超过 4 分钟的产品,把这些产品从队列中移除并丢弃。找到并移除每个这样的产品需花 费 3 秒钟。跟踪被移除的单元数量。 9-7 一家糕点厂利用小型自动系统生产面包,和面机器每 UNIF(0.5, 1.0)分钟排出一块生 面团。 生面团进入一个投料漏斗中等待烤箱的可用空间。 漏斗中的生面团将以 4 个一组从漏

斗中投出,并被放置到烤箱装载区,等待烤箱输送带上的可用空间。每个烤箱装载区只能容 纳一组生面团, 烤箱输送带上有 10 个料盘, 每个 1 英尺长, 以每分钟 0.35 英尺的速度移动。 (1)建立以上问题的模型,使用 Hold(扫描条件) 、Signal 和 Hold(等待信号)模块来 建立控制生面团组的逻辑,运行模型 3000 分钟,统计漏斗中的生面团数量、烤箱 利用率和每小时的面包产量。 (2)在(1)的基础上修改模型,用基于 Decide 模块建立的逻辑取代 Hold(扫描条件) 模块。 9-8 顾客到达一个小型服务中心,到达时间间隔为 EXPO(5) 。服务中心有两个服务台,每 个服务台各自有一个队列,服务台 1 和 2 的服务时间分别为 EXPO(9.8)和 EXPO(9.5) 。 到达的顾客进入最短的队列, 当队长之差为 3 或更大时就换队, 这时较长队列中的最后一名 顾客转移到较短队列的最后,此后的至少 30 秒钟之内不会再发生其它的换队活动。建立此 问题的模型并制作动画,运行 10000 分钟,统计换队次数、资源利用率和队长信息。 9-9 一个小型的配送中转系统有 3 个运入站和 4 个运出站,卡车以时间间隔 UNIF(35, 55) 到达 3 个运入站中的一个,每辆卡车包含的托盘数为 UNIF(15, 30) ,假设卸载时间为 0。 每个托盘以相同的概率被送至其中一个运出站, 站间的运输由 3 个叉车来完成, 叉车的运送 速度为每分钟 60 英尺。 假设任意一对运入站和运出站之间的距离均为 50 英尺, 同时假设相 邻的运入站之间或相邻的运出站之间的距离为 15 英尺。 (1)建立以上问题的仿真模型。如果没有新的运送请求,假设叉车停留在最后卸载的 地方。 (2)修改模型,使空叉车都返回到中间的运入站(运入站 2)等待下一次装运。 (3)修改模型,为每个运入站分配一辆叉车,当没有运送请求时,叉车都返回到所分 配的运入站去。 将托盘的系统逗留时间作为主要性能指标,比较以上三种系统的结果。要使用恰当的 统计分析来支持你的结论。 9-10 建立一个模型并制作相应的动画来模拟小型乡村集市上的弗累斯大转盘。兴高采烈的 游客们以时间间隔 EXPO(3)到达转盘,并进入队列等待。当上一轮转动结束后,第一位 顾客准备下来时,队列中的下 5 个等待顾客(也可能会更少,假如在队列中已不足 5 个顾客 的话)被允许进去转盘区。当一个顾客下来时,一个新的顾客上去。注意,当前转盘里的顾 客可能比等待的顾客要多, 也可能等待的顾客会比当前转盘里的顾客多。 当前转盘中的顾客 离开需要 UNIF(0.05, 0.15)分钟,而一名新的顾客进入需要 UNIF(0. l, 0.2)分钟。弗累

斯大转盘仅有 5 个单独的座位,每个座位相隔 10 英尺。转盘以每分钟 20 英尺的速度转动, 每名顾客转 5 圈, 只有当本轮回转结束后才允许新的顾客登上转盘。 从转盘上下来的顾客需 要 2 分钟跑到出口处,但我们不能确定他们是离开还是又排在下一轮队列中。 (提示:使用 输送设备表示弗累斯大转盘,使用 Wait / Signal 来实现进入和离开轮盘的准则。 )顺便说一 句,弗累斯大转盘是由美国工程师 G..W.G. Ferris 发明的,他死于 1896 年。转盘的德文名字 是 Riesenrad,可粗略地译为“巨大的轮子” 。

第 10 章 Arena 的集成和定制
本章我们将介绍 Arena 和其他应用程序的集成问题以及如何构建定制的 Arena 模块。 我 们将通过一个非常简单的呼叫中心的模型来阐述这些概念。 第一节介绍第一个主题, 在这里我们设计了一个模型, 从一个外部文件中将预定的到达 时间读入模型, 然后将性能测度数据写入一个文件中。 这说明可以采用多种不同方法从外部 数据源 (如文本文件) 将数据集成到 Arena 模型中来; 第二节我们将介绍两种微软的 Windows 操作系统技术,即 ActiveX 自动化技术和 VBA(Visual Basic for Applications)技术。Arena 利用这些技术直接和其它程序集成。 在这一节中我们还将介绍 Arena 是如何与 VBA 集成的。 我们假定读者已经熟悉 VBA 编程,或者读者会通过学习其它有关资料来达到这一要求,本 节的重点只是阐明在 Arena 中如何使用 VBA;第三节介绍怎样使用这些技术来创建一个定 制的用户界面;第四节继续讨论 VBA,并对呼叫中心模型进行了扩充,使其能够纪录有关 呼叫数据并且在微软的 Excel 中将呼叫周期信息用图像表示出来; 最后一节即第五节我们将 从整体上介绍如何设计读者自己的模块,从而增加 Arena 的标准建模结构。通过这一章的学 习,读者将对 Arena 的核心特点有一个初步的了解,并且能够将 Arena 和其它桌面应用程序 相集成,以及采取多种方式创建定制的 Arena 界面。

10.1 模型 10-1:读写数据文件
我们先从一个非常简单的呼叫中心模型开始, 然后在多个我们感兴趣的方面逐步对它进 行扩展。 我们的呼叫中心有一个随机产生的呼叫到达流和一个处理呼叫的事务中心, 呼叫在 经过事务中心处理之后即离开系统。呼叫中心经理估计,呼叫的到达服从均值为 1.1 的指数 分布,呼叫的处理时间服从均值为 0.75、最小值为 0.3、最大值为 1.1 的三角分布。如图 10-1 所示, 建立本系统的仿真模型, 我们使用了一个 Create 模块、 一个 Process 模块和一个 Dispose 模块。

原书 P401 图 10-1. 简单的呼叫中心模型

这三个模块的数据如图 10-2 所示,仿真实验的参数通过菜单 Run>Setup>Replication Parameters 设置成图 10-3 所示。建好模型之后,我们就可以运行并察看仿真结果了。

原书 P402 图 10-2. Create、 Process 和 Dispose 模块

原书 P402 图 10-3. 仿真实验参数

尽管这个呼叫中心模型很简单, 我们依然可以使其更加符合实际。 呼叫中心经理正好告 知我们, 他有某天呼叫到达时间的历史数据。 那就让我们使用收到的这一段时间的实际呼叫 记录来产生模型实体, 而不是使用概率分布的抽样数据, 这样可以更好地确认我们所构建的 模型。 通过这些实际数据驱动模型进行仿真运行, 如果其仿真结果和那段时间系统的实际性 能非常贴近, 我们就可以更加相信该仿真模型的逻辑的正确性了。 或者我们也可以使用同样 的方法对具有特定到达模式的系统进行仿真运行, 例如, 卡车按照一个固定的但是不规则的 日程时间安排到达一个分销中心的装载码头运送货物。 我们在 10.1.1 小节开始一个简单的实例,即从文本文件中读取实体到达数据;在 10.1.2 小节我们将介绍从其它数据源读取类似数据的方法。

10.1.1 模型 10-2:从文本文件中读取实体的到达数据
为了对呼叫中心模型作这样的修改, 我们需要一个包含所要研究时间段的到达时间数据 的文件,用它来替换产生实体的模型逻辑。方便起见,假定仿真运行从第 0 分钟开始,我们 构造了一个包含相应仿真时间值的 ASCII 类型的文本文件,该文件(Model 10-02 Input.txt) 的前几个数值如图 10-4 所示。在这里我们不详细介绍这个 ASCII 文本文件是如何产生的。 实际上,读者很可能会发现,读者所能获取的信息很难如此方便地存储起来,但是通过电子 数据表格或者数据库软件的有效使用, 通常读者还是能够将原始数据转化成可以直接用于仿 真的值并导出到文本文件中。

原书 P403 图 10-4. 修改后的呼叫中心模型的呼叫时间数据

我们需要决定如何使用存储在文本文件中的历史数据, 这涉及到两个方面的问题: 一是 将数据从文件传至模型的机制; 二是如何使这些数据在适当的时间产生实体。 我们先看看在 适当的时间产生实体的逻辑,这包括当到达模型逻辑的相应部分时读取数据的细节问题。 到目前为止,我们都是用 Create 模块来产生实体,在仿真运行的整个过程都是基于间 隔时间来产生新的实体。我们知道,手工仿真的(还记得第二章的有关内容吗?)每一个实 体到达的时候, 当前到达的实体都被送至模型中, 而下一个到达的实体则被放入未来事件表 以便在将来的某个适当时间到达,对话框中 Time Between Arrivals 项的数据决定了下一个实 体到达的时刻,更一般的,这和概率分布的抽样结果有关。 然而,我们不能通过构造一个简单的 Time Between Arrivals 项的表达式来从我们的数据 文件中建立呼叫的到达信息,相反的,如图 10-5 所示,我们将直接在模型中使用一个控制 实体(control entity)来模仿当前到达和下一个到达的实体逻辑。

原书 P404 图 10-5. 从文件产生实体的逻辑图

如图 10-6 所示,Create 模块只产生一个实体。对于这个 Create 模块,Arena 只会在每次 仿真实验开始时产生一个实体,然后就停止实体产生的流程,因为这已经达到了在 Max Arrivals 项设置的产生实体的最大数量(即 1) 。 产生的实体进入 ReadWrite 模块,如图 10-7 所示,从数据文件中读取下一个值并将它 赋给实体属性 Call Start Time。ReadWrite 模块可以在高等运送面板中找到,它能从外部数据 源读取一个或多个数值到 Arena 中, 并且将这些值赋给模型变量。 Arena 的文件名 Arrivals File 用作文件的模型标识符,这个名称千万别和存储在硬盘上(或者任何其它地方)的实际文件 名混淆了,我们后面将介绍在 File 数据模块中定义这个实际的文件名称。

原书 P404

图 10-6. 修改后的 Create 模块

原书 P405 图 10-7. ReadWrite 模块

实体从数据文件读取数值之后到达 Delay 模块 (图 10-8) 等待 Call Start Time 长的时间, 以使代表呼叫的实际实体能在适当的时间到达逻辑模型。 由于数据文件中的数值代表从仿真 运行开始后每一个呼叫的绝对时间而不是间隔时间,所以 Delay Time 项被赋值为 Call Start Time - TNOW,这样实体将被延迟到存储在 Call Start Time 属性里的时间值。

原书 P405 图 10-8. Delay 模块

当控制实体完成必要的延迟之后, 即可产生实际的呼叫实体进入逻辑系统, 基本操作面 板中的 Separate 模块可以很好地满足这个需要, 如图 10-9 所示。 Separate 模块一方面将控制 实体(标有 Original 的模块退出点)传送回 ReadWrite 模块,再从数据文件中获取下一个呼 叫时间;另一方面,Separate 模块产生控制实体的一个副本,并通过标有 Duplicate 的退出 点(如图 10-5 所示)将其传送至逻辑模型,这个复制实体代表一个新的呼叫,它将完成所 有剩余的模型逻辑。

原书 P406 图 10-9. Separate 模块

修改模型的最后工作就是要指定数据文件的必要信息,如图 10-10 所示,编辑高等操作 面板中的 File 数据模块。当我们在 ReadWrite 模块的 Arena File Name 项中敲入 Arrivals File 时,Arena 将自动在 File 数据模块中产生一个相应的输入栏,我们在该输入栏的 Operating System File Name 项中输入 Model 10-02 Input.txt,不管模型文件保存在什么地方,也不管 ReadWrite 模块什么时候引用 Arena 的 Arrivals File, Arena 都会去访问 Model 10-02 Input.txt。 读者也可以给出文件的完整路径,如 C:\My Documents\Cool Stuff\Model 10-02 Input.txt,但是 如果读者决定把这个模型和数据文件发给其他人, 他们也必须有同样的文件夹结构, 才能保 证正确读取数据。File 数据模块的其它选项都保留默认值,包括文件类型 Free Format(表 示 Model 10-02 Input.txt 文件包含文本值) ,以及 end-of-file action 选项也保留 Dispose 值,这 样控制实体读完文件的最后一个值后就会离开系统,从而有效地终止模型的实体到达。

原书 P407 图 10-10. File 数据模块

让我们使用图 10-4 的数据值来描述前两个呼叫的仿真逻辑,在仿真时刻 0(即仿真实 验开始的时刻) ,控制实体先读取一个值 1.038 并将其赋给 Call Start Time 属性,然后延迟 (1.038-0)时间单位。在 1.038 时刻控制实体离开 Delay 模块,并产生一个副本进入 Queue 模块开始呼叫的实际处理过程。控制实体返回 ReadWrite 模块,从数据文件中读取下一个值 2.374 并将其赋给 Call Start Time 属性,然后进入 Delay 模块,延迟(2.374-1.038=1.336)时 间单位,Arena 将在未来事件表中产生一个与控制实体有关的新的事件,该事件在未来的 1.336 个时间单位发生,即在实际的未来时刻 2.374 发生,该事件发生之后控制实体将到达 Separate 模块, 在那里产生一个呼叫实体, 该实体的 Call Start Time 属性值 2.374 表示第二个 呼叫进入系统的时刻。当控制实体将 Model 10-02 Input.txt 文件的全部数据读取完成之后, 这个过程即告结束。 有两个条件可以终止仿真的运行。第一,数据文件中列出的呼叫还没有发生完,如果仿 真已经达到了 Run Setup 对话框中所设定的运行终止时间, Arena 将在该时刻终止仿真运行, 因为任何一个模型的运行时间都不可能超过事先设定好的仿真终止时间; 第二, 还没有达到 事先设定好的仿真终止时刻, 但是数据文件中列出的呼叫都已经产生, 并且处理完成离开系

统,未来事件表变空,此时 Arena 就会在事先设定好的终止时刻之前停止仿真运行(还记得 控制实体读取完数据文件的最后一个数据之后就离开系统吗?) ,因为在未来事件表中没有 实体并且没有额外的基于时间的控制需要处理的时候,Arena 将在最后一个实体离开模型之 后终止仿真运行。

10.1.2 模型 10-3 和 10-4:读和写 Access 和 Excel 文件
如果保存呼叫到达数据的不是文本文件,而是微软的 Access 数据库或者 Excel 电子表 格,那该怎么办呢?下面的介绍将使读者认识到,在 Arena 中处理这些问题是很简单的。 首先假定保存呼叫到达信息的是 Access 数据库文件,并且相关数据存储在名叫 Arrival Times 的表中,图 10-11 显示了该文件(Model 10-03 Input.mdb)的前面一些数据值。

原书 P408 图 10-11. Access 表中的呼叫时间数据

从上节我们建立的模型 Model 10-02.doe 开始,只需做少量的改动即可完成读取数据库 的功能。 读取和使用数据来控制实体产生过程的模型逻辑依然有用, 我们只需改变获取数据 的一些细节。 这次从描述新的数据文件开始。编辑高等操作面板中已经存在的 File 数据模块,如图 10-12 所示。保留 Name 项为 Arrivals File,回顾一下,这项内容是在模型逻辑(本例中为 ReadWrite 模块) 里用来标识文件的, 没有必要改变它, 但是我们必须将 Operating System File Name 项改为 Model 10-03 Input.mdb1,而其它大多数选项都保留默认值,包括 End of File Action 的值 Dispose,这就像以前一样,控制实体读完文件的最后一个值就离开仿真系统。 读者将注意到 Access Type 项有一个可供选择的下拉列表,在这里选择 Microsoft Access (*.mdb) ,有关字段(列)和以前不一样了,这是因为读取数据库文件需要和文本文件不同 的信息。特别是出现了一个标有初始值为 0 rows 的按钮,在该按钮上方有一个新的列,标

使用扩展名为.mdb(Access 文件的默认格式)的文件时请注意,不要和 Arena 模型重名。Arena 自动将其 输出信息保存在文件 ModelName.mdb 中(其中 ModelName 为 Arena 模型文件名称) ,任何同名的文件都将 被其覆盖。

1

记为 Recordsets,单击按钮打开如图 10-13 所示的记录集编辑器。

原书 P409 图 10-12. File 数据模块

读取数据库的时候, 其实是从表或行和列中读取记录的集合。 一个数据库可能有多个不 同的记录集,Arena 通过定义 Recordset Name 来区分每一个记录集,每个 Recordset Name 必须和数据库的一个表建立联系。读者可以选取任何合法的标识名称作为 Recordset Name 的值,方便起见,我们在这里输入表名 ArrivalTimes。单击 Add/Update 完成记录集的定义。 单击 Table Name 下面的下拉列表框的箭头将显示数据库中当前定义好的所有表,本例中选 择唯一的表 ArrivalTimes,如图 10-13 所示。如果读者想浏览某个记录集的一些数据,请先 在左栏中选定该记录集,然后单击 View 按钮,浏览之后单击 Close 按钮关闭浏览窗体。最 后单击 OK 按钮退出记录集编辑器。

原书 P409 图 10-13. 记录集编辑器

读者可能想知道我们为什么要先改变文件属性,而不是先修改 ReadWrite 模块。如果现 在打开 ReadWrite 模块(如图 10-14 所示) ,可以看到它有些不一样了,事实上,ReadWrite 模块将自动获取所读文件类型的有关信息, 本例中, 它判断出要读取数据库并且需要确定记 录集。我们从下拉列表中选取 ArrivalTimes,如果读者想控制每次循环要读取的记录,请在 Record Number 项输入一个任意的表达式,但我们在此保留其默认值,即不填写任何数据, 这样系统将从第一条记录开始顺序读取。还记得我们不必改变 Arena 的 File Name 和 Assignments 项吧,所以单击 OK 按钮完成设置。

原书 P410 图 10-14. ReadWrite 模块

就这样简单, 一切就绪, 保存读者最新创建的模型, 或者在读者的 CD 上查找文件 Model 10-03.doe,现在可以运行模型,从 Access 文件而不是文本文件中读取数据了。 如果读者从第一节开始一直跟着我们学习, 现在应该就已经知道了读取 Excel 电子表格 文件要做的大多数工作了。 读者可能已经注意到 Excel 电子表格的行和列与数据库表的行和 列非常相似,Excel 不是关系数据库管理系统,但是很多地方我们都可以像处理 Access 数据 库文件一样处理它。 在 Excel 里,一个矩形区域即单元格或行和列的集合等价于一个 Access 数据库表的行 和列,如果我们想将其看作一个数据库(事实上我们在这里的确是这样处理的) ,命名的区 域就必须包含至少两个单元格。读者可以通过选定单元格集合,然后选择菜单 Insert->Name->Define,输入一个名字,来创建 Excel 的命名区域。例如,如果选定单元格 A3 到 C9 并且按照上述步骤进行,将工作簿选定区域命名为 MyRange,读者将得到非常类 似 Access 表的三行和七列,如图 10-15 所示。如果查看名称下拉列表(一般都在菜单工具 栏的左上角处) 可以看到已经定义好的所有单元格区域的名称, , 同样的, 这些区域和 Access 数据库表也是等价的。

原书 P411 图 10-15. Excel 电子表格的呼叫数据

让我们重新开始刚刚在上面建立起来的模型 Model 10-03.doe, 把它修改成从 Excel 而不 是 Access 中读取数据。提供的例子数据文件 Model 10-03 Input.xls 如图 10-15 所示,可以看 到区域 ArrivalTimes 在名称框和工作簿里都被突出显示。如图 10-16,我们仍然从描述现有 的 File 数据模块中的新数据文件开始,除了更改 File Name 和 Access Type 两项以外,其余 设置都可以保留和读取 Access 数据库文件一样, Operating System File Name 项改为 Model 将 10-03 Input.xls,在 Access Type 下拉列表中选择 Microsoft Excel (*.xls)。

再次单击 Recordsets 按钮显示记录集编辑器,定义好的记录集 ArrivalTimes 仍然存在, 但是由于我们选择了一个新的文件, 所以其链接已经删除了。 选择左边定义好的记录集来恢 复链接,Named Range 底下的下拉列表将显示所有在 Excel 中定义好的命名区域,选定 ArrivalTimes 并单击 Add/Update 按钮保存修改。如果读者想查看记录集的一些例子数据,请 先选定左栏中的记录集,然后单击 View 按钮,可以看到如图 10-17 所示的内容,单击 Close 按钮关闭浏览窗体,最后单击 OK 按钮退出记录集编辑器。

原书 P411 图 10-16. File 数据模块

原书 P412 图 10-17. 记录集编辑器

因为我们已经修改了 Read/Write 模块使其从 ArrivalTimes 纪录集中读取纪录, 所以不必 做其它额外的变动。现在可以运行模型,从 Excel 文件读取数据了。 既然已经懂得如何读取 Access 和 Excel 文件,接下来就准备向这些文件中写数据。这 必须做一个修改, 那就是在 Read/Write 模块的 Type 项中选择 Write to File, 而不是 Read from File,其它项目和前面读取信息时保持一样。当然,写 Access 和 Excel 文件时,文件本身必 须存在。微软的 ADO(ActiveX Data Objects,ActiveX 数据对象,对不同的数据源都有高效 的数据访问能力)技术可以获取有关的文件结构和格式化信息。特别地,表和命名区域必须 已经存在。对于 Excel 文件还有一个额外的限制,如果命名区域没有用初始数据格式化成数 值类型,那么所有的数据都会当作字符串类型进行写入操作。要解决这个问题,最简单的方 法就是在写入之前在命名区域中输入一些格式化的样本数据。如果读者想了解更详细的信 息,请查阅 Arena 的帮助主题 Excel: Read/Write Limitations Using ADO。 我们将对呼叫中心模型作最后一次扩充, 使其能够在同一个 Excel 文件的不同工作簿中 纪录处理时间信息。 我们有一个新的数据文件 Model 10-04 Call Data.xls, 该文件包含和 Model

10-03 Input.xls 文件相同的信息,同时也包含一个新的区域 ProcessTimes,该区域定义在一 个新的工作簿 OutputData 中。ProcessTimes 区域已经格式化成数值类型,并且其第一个单元 格为 0。我们在新的工作簿中添加了一个图形区域来说明进一步改进的可能性,尽管该图形 现在是空白的,但是当数据写入工作簿时,就会自动在图形中显示出来。 首先,修改 File 数据模块,指定新的文件名,使用纪录集编辑器指定文件中的第二个 区域。经过修改之后,有关模块如图 10-18 所示。

原书 P413 图 10-18. File 数据模块和纪录集编辑器

我们需要调整仿真逻辑, 以便呼叫处理完成之后能够将处理时间写入文件中。 如图 10-19 所示,在呼叫终止前添加一个 ReadWrite 模块。

原书 P413 图 10-19. 写入处理时间数据的逻辑图

要读写同一个文件,指定 ReadWrite 模块的 RecordSet ID 项为 ProcessTimes,要写的值 是一个计算表达式,指定 Assignments 的 Type 项为 Other,在 Other 项中输入处理时间的表 达式 TNOW-Call Start Time,如图 10-20 所示。

原书 P414 图 10-20. 在 ReadWrite 模块写入处理时间信息

现在可以进行仿真运行了,模型将和以前一样读取数据,但是每一个呼叫完成之后,它 的处理时间都将写入 OutputData 工作簿,仿真运行终止时,该工作簿可能如图 10-21 所示。

原书 P415 图 10-21. 处理时间输出数据和图像

10.1.3 高级读写操作
如果数据总是以单一的形式出现, 那么问题将变得非常简单, 但是现实生活却很难如此, 相反,我们通常获取的数据都不能立即满足需要。举一个简单的例子,包含冗余数据的文本 文件,如图 10-22 所示。

原书 P415 图 10-22. 呼叫中心的改进模型的更多呼叫时间数据

这些数据粗略地看起来有些古怪, 头两行好像都包含一个单词和两个数值, 第三行好像 包含一个单词和一个数值。但事实上除了 1 至 8 列包含的是描述信息以外,这个文件和图 10-4 所示的文件是完全一样的。我们必须使用格式化的方法来读取这种类型的文件,一个 简单的手段就是修改 10.1.1 节我们建立的模型的 File 数据模块,在 Access Type 项选择 Sequential File,对于 Structure 项,用 FORTRAN 或者 C 语言格式输入一段描述性文字,表 示忽略前 8 列数据,从第 9 列开始读取数据,如图 10-23 所示。

原书 P416

图 10-23. 格式化数据的 File 模块

顺便提一下, 如果读者的数据不是在表中的第一列时读者该怎么办?如果读者有修改文 件的权限的话,一个很自然的选择就是定义区域或者表格使其恰好包含读者需要读取的数 据。例如,如果读者的电子表格有一个从 A 列到 C 列的命名区域,但是读者只需要 C 列的 数据,最好的方法就是对 C 列单独定义一个新的区域。不幸的是,很多情况下都不能修改 源文件, 此时最好的选择也许就是简单的读取并丢弃那些不相关的数据。 读者可以定义一个 临时变量然后将冗余数据读入其中。继续我们的例子,定义一个 JunkValue 变量,扩展 Read 模块如图 10-24 所示,忽略区域中的头两列。 即便读者的数据存储在更加复杂的 Excel 或 Access 文件中也不必担心,当需要更加复 杂的数据访问技术,或者数据来源于其它软件包时,微软提供了一套解决方案,即 ADO。 所幸的是, 读者已经使用过 ADO 了, 前述例子中用到的 Excel 和 Access 接口都是使用 ADO 实现的,Arena 做了大量的工作来使常用的任务变得更加简单。然而,如果读者碰巧遇到了 一些更加复杂的情况,花点时间学习一下 ADO 技术还是非常值得的,我们并不想对 ADO 做深入研究,而只是通过一些例子向读者展示一下 ADO 的魅力。 ,就会出 如果读者将 File 数据模块的 Access Type 项指定为 Active Data Objects(ADO) 现一个新的字段(Connection String,连接字符串) 。连接字符串是通过给定连接信息来定制 ADO 接口的,如指定连接所需的提供者、文件名和任何其它项目。假如读者要忽略对 Excel 内建的支持,比如读者想支持列标题,所以读者要定制自己的数据连接。按照图 10-25 输入 连接字符串,或者使用 SQL Server 驱动连接到服务器 RSI-Joe 上的数据库 BizBikes,其连接 字符串如图 10-26 所示。在这两个例子中,这些字符都应该当作一个连续的字符串在 File 数 据模块的 Connection String 项中输入。

原书 P417 图 10-24. 忽略冗余数据的 ReadWrite 模块

原书 P417 图 10-25. 使用 ADO 标题的 Excel

原书 P417 图 10-26. 使用 ADO 的 SQL 命令行

有一点很重要,文件的输入输出会影响执行速度,和其它处理任务比较起来显得更慢。 许多情况下, 数据访问数度慢点无关紧要, 因为耗费在读写数据的时间相对于模型运行的时 间而言通常是微乎其微的。 但是当数据量很大时输入输出速度就显得异常重要了, 此时读者 可能想把数据变成速度尽可能快或容量尽可能小的形式,因为尽管 ADO 一般都简单易用而 且柔性很好, 但其执行速度却常常都是一个问题。 二进制文件通常具有更快的速度并且占用 更小的空间,它采用机器可读的形式存储数据,但是普通人不容易解读,因此如果人们要直 接和数据交互时一般都不会选择二进制形式,然而如果只是在相同平台的程序之间传递数 据,它将产生又小又利于读写的文件,对于容量很大访问频繁的文件,二进制形式是一个重 要的选择。大多数计算机语言都支持对二进制文件的读写操作,读者甚至可以使用 Arena 将文件一次性转换成二进制形式,然后在仿真运行和实验的过程中重复使用。 要实现这个目的,请在 File 数据模块的 Access Type 项中选择 Sequential,在 Structure 项中选择 Unformatted。

10.2 Arena 中的 VBA
这一节我们将介绍有关 Arena 内嵌的 VBA,借助这项技术可以撰写特定的程序代码来 增强 Arena 的模型逻辑。10.3 和 10.4 节将说明 Arena 和 VBA 具体如何协同工作。

10.2.1 ActiveX 自动化技术和 VBA 概述
Arena 利用两项微软的 Windows 技术来加强和桌面应用程序的集成。第一项就是 ActiveX 自动化技术, 这项技术允许应用程序之间以及应用程序本身通过编程接口进行控制, 它是 Windows 提供的隐藏框架, 可以通过被设计使用 ActiveX 功能的编程语言如 Visual Basic

进行访问。事实上,如果读者在 Excel 中使用过宏,读者就已经利用过这项技术了,只是可 能读者没有意识到而已。Excel 的宏用 VBA 代码格式存储,通过 ActiveX 接口使 Excel 应用 程序完成一些特定的功能,如格式化单元格、改变公式或产生图表等。 应用程序所支持的方法类型是由对象模型定义的,程序设计者(如 Excel 和 Arena 的开 发者) 构建对象模型来提供接口, 这样编程语言就可以使应用程序完成用户使用鼠标和键盘 通常会进行的交互工作。对象模型包括:    可控的应用程序对象列表(如 Excel 工作簿、图表、单元格) ; 可被读取或修改的对象属性(如工作簿的名称、图表的标题、单元格的值) ; 对象可接受或完成的方法(或称行动,如删除工作簿、创建图表、合并单元格) 。

当读者安装包含对象模型的应用程序时,安装过程将在 Windows 操作系统中注册其对 象模型(即将其添加到计算机的对象列表中) 。当读者想使用编程语言来利用此应用程序的 功能时,读者可以建立到其对象模型的引用,然后直接对该对象进行编程实现。我们将通过 在 Arena 中编写 VBA 代码向 Excel 传送数据,从而展示上述方法的工作原理。许多应用程 序都可以进行定制(即通过其它应用程序进行控制) ,包括 Office、AutoCAD、Visio 等等, 读者可以使用 C++、Visual Basic 或者 Java 等编程语言创建程序来达到控制的目的。 Arena 进行应用集成的第二项技术就是其内嵌的 VBA,通过它可以不用购买或安装单 独的编程语言即可编写代码来控制其它应用程序。VBA 是 Office、AutoCAD 和 Arena 通用 的语言,它也是 Visual Basic 的内在引擎。当读者安装 Arena 的同时就安装了完整的 Visual Basic 编程环境,读者可以通过菜单 Tools->Macro->Show Visual Basic Editor 进行访问。 这两项技术协同工作,使 Arena 能够集成其它支持 ActiveX 自动化的应用程序。读者可 (通过 Visual Basic Editor) 来定制其它程序, Excel、 如 以直接在 Arena 中编写 Visual Basic 代码 AutoCAD 或者 Visio 等。在我们改进的呼叫中心模型中,我们将创建一个新的工作簿,在仿 真过程中向该工作簿填充数据, 并且自动用图形的方式显示数据, 所有的操作都不直接接触 Excel 本身。读者也可以编写 VBA 代码来定制 Arena,如添加动化变量、获取仿真输出统计 值、更改模块操作数的值等等。 当读者在 Arena 中用 VBA 编写 Visual Basic 代码时, 读者的代码将存储在 Arena 模型文 件 (.doe) 中, 就像 Excel 的 VBA 宏存储在电子表格 (.xls) 文件中一样。 读者可以使用 VBA 的所有功能,包括:  Visual Basic 的程序结构,如 Sub、Function、Class、If、Elseif、Endif、While、Wend、 Do、On Error、Select Case 等;



包含各类控件(如 toggle 按钮、滚动条、输入框、命令按钮、一直很流行的 spin 按钮 等)的用户窗体(通常指对话框) ;

 

代码调试工具,如追踪、断点和各种单步调试选项; 全面的帮助信息 要在 Arena 中打开 Visual Basic Editor,请选择菜单 Tools->Macro->Show Visual Basic

Editor,或者在 Integration 工具栏上单击相应的按钮(

) ,这将打开一个独立的窗体,包

含 VBA 代码、窗体、调试接口和帮助等,如图 10-27 所示。

原书 P420 图 10-27. Visual Basic 编辑器窗体

Visual Basic 编辑器窗体是 Arena 的子窗体,当读者退出 Arena 时,它将随着父窗体自 动关闭。而且 Arena 窗体中的改变,如打开一个新的模型,Visual Basic 编辑器窗体中的信 息也会发生相应的变化,这种关系影响着 VBA(集成在如 Arena 的宿主程序中,VBA 代码 隶属于模型文件,而且只有宿主程序可以访问)的架构。

10.2.2 内置的 Arena VBA 事件
Visual Basic 编辑器窗体左侧的项目面板显示了打开的模型列表,每一个模型都包含一 个 Arena Objects 列表,其中有一个叫做 ThisDocument 的单一的条目,ThisDocument 对象赋 予 VBA 项目对 Arena 模型各类事件的访问权限。要为事件程序添加代码,请在 Visual Basic 编辑器中选择 ModelLogic 对象,然后在右侧的程序列表中选择所需的事件,如 RunBegin 事 件。 Arena 内置的 VBA 事件主要可以分为三类。 (实际的函数名称都有前缀 ModelLogic_, 如 ModelLogic_DocumentOpen。 )    运行前事件,如 DocumentOpen,DocumentSave; Arena 触发的运行事件,如 RunBegin,RunBeginSimulation,RunEndReplication; 模型/用户触发的运行事件,如 UserFunction,VBA_Block_Fire,OnKeystroke

程序列表中显示的事件提供了触发 VBA 代码的所有位置集合,因此,读者面临的第一 个问题就是决定使用什么事件,使读者的代码能够在适当的时候被触发来完成所需要的任 务。 运行前事件如 DocumentOpen 和 DocumentSave, VBA 代码能够在特定的用户操作 使 (如 打开和保存模型)下执行。然而,Arena 的 VBA 事件大多是为仿真运行提供支持的,只要 读者开始运行仿真程序(如选择菜单 Run->Go) ,一系列的 Arena 操作和 VBA 事件就会出 现,如图 10-28 所示。

原书 P421 图 10-28. 仿真运行的 VBA 事件

当仿真运行开始、完成和终止的时候,Arena 自动调用每一个相应的事件(如图 10-28 中粗体所示) 。如果事件中没有 VBA 代码,Arena 将不采取任何特殊操作,就好像这些事件 并不存在一样;如果读者打开 Visual Basic 编辑器并在有关事件中输入 VBA 代码,Arena 就 会在运行时执行这些代码,我们将在接下来的两节中给读者展示这方面的内容。 图 10-28 同时指出上述事件调用的一个重要问题,即不同仿真时间阶段 VBA 代码可以 访问的数据是不一样的。当读者编辑 Arena 模型时,仿真变量、计数器、统计量等通过读者 输入的模块信息被定义成模型结构的一部分, 但是它们还没有实际的值 (如还没有平均排队 数,没有资源状态等) 。因此,当模型处于编辑状态时,只能访问模块操作数(模块对话框 和表格单元格的字段)的值。在模型 10-5 中,我们将通过这个方法修改两个 Create 模块的 Max Arrivals 字段的值。 当读者开始仿真运行时,Arena 检测并初始化模型,将模块中的有关信息转换成仿真运 行所要求的格式,并且将模型置于运行状态。在仿真运行过程中,可以通过 Arena 的仿真控 制器和 VBA 代码,检查和更改变量值、资源状态、统计量等,如模型 10-6 所述,将运行的 统计值传入 Excel 中。运行终止时,Arena 释放有关仿真运行信息并且将模型重置为编辑状 态。 回到 Arena 的内置事件,我们将简要地介绍一下图 10-28 中的每一步,其中粗体部分代 表 Arena 可以访问的 VBA 事件,斜体部分简单地描述了 Arena 的运行过程。 1. 调用 ModelLogic_RunBegin

此时 VBA 代码可以修改模型的结构化数据,即模块操作数的值,并且其更改将 应用于仿真的运行过程,但是,RunBegin 事件不能直接更改仿真运行期的值,如变 量、实体属性等,因为此时仿真还没有初始化。读者可以通过这个事件来覆盖存储 在模块中的一些输入值 (如 Decide 模块的概率)接下来的模型 10-5 说明了 RunBegin 。 事件的有关应用。 2. Arena 检测模型并将仿真初始化为运行状态 这个过程在后台进行,Arena 验证模型是否准备运行。检测并初始化模型之后, Arena 忽略模块本身所包含的数据,取而代之的是随着仿真运行开始之后动态变化 的实时仿真数据,此时所有的变量都被赋予了初始值(如读者在变量表格中输入的 数值) ,资源也被赋予了初始的加工能力,但是还没有实体进入模型。 3. 调用 ModelLogic_RunBeginSimulation 读者在这里插入的代码只会在仿真运行的开始执行一次(当然,如果 Arena 在 第二步中检测到模型包含错误,就不会调用这个事件了,读者首先得改正错误使 Arena 能够初始化) 。当 Arena 执行完成 RunBeginSimulation 事件中的 VBA 代码之 后, 仿真运行才会继续开始, 因此可以在此处从外部数据源如 Excel、 Access 或 Oracle 中安全地载入大量数据;显示一个用户窗体来获取有用信息,如仿真运行要做多少 次实验(一次仿真运行[Simulation]可以包含多次仿真实验[Replication]) ,或者将详 细的仿真结果存储在 Excel 文件中 (如模型 10-6 所示)让用户设置文件的表头信息。 , 尽管读者也可以创建实体、改变资源能力、或者更改许多其它内容(如果读者已经 对 Arena 的对象模型进行了深入研究)执行完成 RunBeginSimulation 事件中的 VBA 。 代码之后,Arena 将进入下一步。 4. 调用 ModelLogic_RunBeginReplication Arena 在 仿 真 运 行 的 每 一 次 实 验 之 前 ( 即 实 体 进 入 模 型 之 前 ) 都 会 调 用 RunBeginReplication 事件,此处可以完成的任务与 RunBeginSimulation 类似,只是 在每一次仿真实验之前都会重复执行, 模型 10-6 将展示如何使这两个事件协同工作。 5. Arena 仿真运行 紧接着,模型正式运行,这一步将会产生并释放实体、获取和释放资源等等, 读者在前几章中学到的内容都可以在这里派上用场。在仿真运行的过程中,Arena 还提供了很多接口触发 VBA 代码,如:  ModelLogic_UserFunction—在 Arena 逻辑中引用 UF 变量即可触发该事件,

用于完成诸如过程延迟或者决策标准的复杂计算;  ModelLogic_VBA_Block_Fire—模型逻辑中实体经过 VBA 模块(位于 Blocks 面板)时即可触发该事件,在模型 10-6 中,当实体离开模型时,用此事件 将一些详细信息写入 Excel 文件中;  ModelLogic_OnKeystroke—仿真运行过程中用户按键时即可触发该事件,例 如,当按数字键 1 时可以通过 VBA 代码显示一个用户窗体来总结模型的状 态;  ModelLogic_OnClearStatistics—当清空统计信息时(如仿真时钟达到 Run Setup 对话框所设置的预热期的时间值)即可触发该事件,用于设置模型变 量, 或者在模型中传送一个实体激发特定的逻辑以便对标准的 Arena 统计初 始化功能进行扩充; 6. 当一次仿真实验结束时调用 ModelLogic_RunEndReplication 此事件主要用于将一些总结信息写入外部文件,或者增加一些全局变量等。请 注意,该事件只在一次仿真实验结束时调用,如果其它原因导致仿真运行停止(如 用户在 Run 工具栏上单击 End 按钮) ,则不会触发该事件。 7. 调用 ModelLogic_RunEndSimulation 不管 Arena 仿真运行如何终止,此事件中的 VBA 代码都会被执行。调用 RunEndSimulation 时,运行期的仿真数据仍然可用, 因此可以在此添加 VBA 代码访 问最终的统计值、资源状态等。典型的应用如将定制的统计信息写入文件、电子表 格和数据库中,或者关闭文件,显示运行结束的有关消息等。 8. Arena 终止仿真运行 这和第二步相对应, Arena 清除所有的运行期仿真数据并且将模型设置为编辑状 态。 9. 调用 ModelLogic_RunEnd 最后,和第一步的 RunBegin 事件相对应,Arena 调用 RunEnd 事件。该事件中 的 VBA 代码不能访问刚刚完成的仿真运行中的任何信息 (因为第八步已经清除了这 些信息) ,但是可以访问所有其它的 VBA 函数。如果读者愿意,可以在此显示一个 用户窗体询问是否要再次进行仿真,如果是的话,我们可以自动地返回第一步重新 开始整个仿真过程。

10.2.3 Arena 对象模型
读者确定在哪里撰写 VBA 代码之后, 很可能就要从 Arena 中获取信息了。 对象模型 (又 称为类库) 提供了对象列表以及读者可以在代码中使用的对象的属性和方法, 读者需要通过 代码从 Arena 中获取的所有信息,以及读者需要通过代码使 Arena 完成的所有操作,都可以 使用 Arena 对象模型中的元素来实现。 一个对象就是一个读者能从代码中控制的条目,它的特点即属性,可以在 VBA 中进行 检测,许多属性也可以通过代码进行改变。对象属性的例子包括:矩形、多边形等的线条颜 色、位置(水平位置 x 和垂直位置 y) ,以及动画对象如站点和队列等的标志符,等等。大 多数对象还包含方法, 可以用来完成一定的操作, 例如激活一个窗体或者产生一个新的多边 形等。同时,多数对象可以组成集合,一个集合通常包含一个或者多个相同类型的对象,例 如, Arena 对象库中有一个 Modules 集合, 它包含一个子模型窗体中的所有 Module 实例 (类 型为 Module 的对象) 。 如果读者想浏览对象库,VBA 提供了一个手动的浏览器,可以在 Visual Basic 编辑器窗 体中选择菜单 View->Object Browser,或者按 F2 键,打开对象浏览器。通过对象浏览器, 读者可以在对象库中导航,浏览对象以及它们的属性和方法。图 10-29 显示了通过对象浏览 器在 Arena 对象库中查看 StatusVariables 集合对象及其 Create 方法。

原书 P424 图 10-29. VBA 对象浏览器

Arena 对象模型包含如下对象分类:  模型窗体(Model-widow)对象——所有可以放置在 Arena 模型窗体中或者能够通过其 电子表格查看的项目。模块、集合、线条、多边形、文本、动画对象以及和交互有关的 对象如命名视图等等,都属于模型-窗体对象;  SIMAN 对象—一类特殊的对象类型,通过它可以访问仿真运行时的信息,如变量值、 资源能力、队列长度和当前的仿真时钟等等; 

( 对象——用于访问一般的 Arena 函数, Application、 如 Module Definition 结构 Structural)

和 Panel 对象等。 当读者撰写代码来进行通常的交互(即通过鼠标和键盘完成)时,大多都是协同模型窗体类对象工作,这些对象构成了对象库中的大部分,因为 Arena 提供了大量对象使读者在 模型中进行工作。 例如,图 10-30 所示代码向模型中添加 10 个动画变量,代码中引用的第一个对象变量 叫做 oModel, 它被声明为 Arena.Model 类型, 表明它来自 Arena 对象模型类库, 并且为 Model 类型(我们用小写的‘o’作为变量名称前缀,表明它是对象变量,以便和整型或其它类型 的变量区分开来) 。Arena 对象模型提供了一个特殊对象即 ThisDocument,其属性 Model 表 示当前模型,我们将该属性赋值给 oModel 变量,使其指代包含 VBA 代码的模型窗体。然 后,在循环中通过使用 StatusVariables 集合的 Create 方法添加一个新的动画变量,该方法包 含许多参数,用于建立 WIP(1)至 WIP(10)的变量标志符,连接“WIP(” 、循环变量 i 和“)” 形成变量名称,还有位置、大小、文本等信息。

原书 P425 图 10-30. 生成 10 个状态变量的示例代码

对象库的第二个主要内容就是重要的对象类型 SIMAN,它包含在 Model 对象里,提供 接口用于访问正在运行的仿真模型的所有信息,使用 SIMAN 对象的属性,VBA 代码几乎 可以找到任何仿真的东西。在浏览器中单击 SIMAN 对象,可以按照需要查看到 SIMAN 丰 富的函数列表。 图 10-31 所示的一段代码显示了如何获取用户输入的变量值(在 Visual Basic 中使用 InputBox 函数) ,然后将该值赋给模型变量 Mean Cycle Time。InputBox 中输入的结果存储在 一个局部字符串变量 sNewValue 中,然后设置 oSIMAN 变量指向 ThisDocument.Model 的 SIMAN 对象(SIMAN 是运行 Arena 模型的仿真引擎) ,我们想在运行的仿真模型中获取或 改变任何信息都可以使用 oSIMAN 变量完成。最后两行代码将输入值赋给变量。首先用 SymbolNumber 函 数 将 变 量 名 转 换 成 SIMAN 引 擎 所 使 用 的 内 部 索 引 , 最 后 , VariableArrayValue 属性被更改为在 InputBox 中输入的任何结果。

原书 P426 图 10-31. 运行期间给变量赋新值的代码

由于这两类对象本质特征的不同,它们的使用范围也就不尽相同。通常,模型-窗体对 象多数用在驻留于 Arena 外部的代码中,或者用在通过 VBA 函数完成类似布置变量表(如 图 10-30 所示) 、自动构建 Arena 模型(如与 Arena 分布的 Visio 接口)的代码中。 而 SIMAN 对象只在仿真运行的过程中才被激活,它典型地应用于 10.2.2 节所描述的内 置事件中。使用 SIMAN 对象的任何代码,都只有当模型处于运行状态时(即在 RunBegin 和 RunEnd 事件之间)才可能被执行。SIMAN 对象的属性和方法提供了对正在运行的仿真 模型的所有变量和统计信息(如排队数目、平均计数值、当前的仿真时钟等)的访问权限, 以及部分建模行为来产生实体并将实体传送到模型中,SIMAN 对象不提供 Arena 模型以外 的任何建模能力和仿真数据。这个自动化接口是获取和改变模型信息的一个简单可取的方 法,我们将在 10.4 节中给读者展示如何使用 SIMAN 对象把数据从 Arena 模型传至 Excel 文 件中。

10.2.4 Arena 宏记录
正如读者在 10.2.1 至 10.2.3 节中所看到的那样,VBA 提供了强大的功能和柔性,但也 有些难学。许多支持 VBA 的产品同时也提供宏记录能力,从而使读者有一个更高的起点。 宏是存储在 VBA 模块中的一系列 VBA 命令或指令,它可以在读者需要完成一项任务时随 时运行。 宏记录器是通过记录与实际任务相关的命令从而方便快捷地生成宏的工具。 本节中, 我们将介绍如何使用宏来构建 VBA 解决方案。 假定我们要写代码来放置一些模块, 这当然可以利用 10.2.3 节中描述的 Arena 对象模型, 但是我们通过产生一些可以定制的样本代码来取代原来的方法。先选择菜单 Tools>Macro>Record Macro 或者选择 Record Macro 工具栏上的 Start/Pause/Resume 按钮 ( ) ,来打开宏记录,在显示的记录宏对话框中给定有意义的宏名称和描述,如图 10-32

所示(注意,VBA 的宏名称不能包含空格) 。

原书 P427 图 10-32. 开始记录宏

一旦读者选择 OK 按钮,宏就开始进行记录,记录宏工具栏就变成(

) ,表示当前

有一个宏记录任务,Start/Pause/Resume 按钮被按入显示当前正在记录读者的行动。再次单 击该按钮将暂停记录,但是不终止宏任务,只需再次单击该按钮又将继续宏记录。当读者正 在记录或暂停一个任务时,End 按钮处于可用状态(表示正在记录宏) ,可以在任何时候单 击该按钮以终止宏记录。 一旦激活宏记录,请确保只完成那些读者想记录的步骤。Arena 对象模型定义的行动可 能被记录下来,但类似模块对话框的一些行动将不作记录,如果读者想改变模块数据,必须 使用电子表格接口。 我们下一步要说明如何放置一个模块并且设置其操作数。 从基本操作面 板中选择 Create 模块并放入模型窗体中,然后使用电子表格接口设置 Name、Entity Type 和 Value 等项,如图 10-33 所示。

原书 P428 图 10-33. 宏记录的过程中设置 Create 参数

在宏记录工具栏上单击 End 按钮,停止记录并且自动将产生的代码存储在名为 PlaceCreateModule 的 VBA 模块中, 载入 Visual Basic 编辑器 (菜单 Tools>Macro>Show Visual Basic Editor) ,然后双击 ThisDocument 查看刚才产生的代码,如图 10-34 所示。它是和宏同 名的一段子程序,包含输入的宏描述信息,下一行代码将模块放到特定的 x、y 坐标位置, 接下来的三行代码设置我们在电子表格接口中修改的操作数,最后几行关闭子程序并结束 宏。 关闭 VB 编辑器并返回模型试验我们的新代码, 选择 Tools>Macro>Run Macro…打开 Run Arena Macro 对话框(图 10-35) ,它提供了所有定义好的宏列表(到目前为止我们只定义了

一个宏) 并且有一些运行选项。 , 单击 Run 按钮, 尽管好像什么也没有发生, 但事实上, Arena 已经在旧的 Create 模块的位置上又放置了一个新的 Create 模块,把上面的模块拖走,就可 以看到隐藏在底下的原来的模块, 进一步可以看到新模块的参数仍然是默认值。 那是正确的 吗?宏的确如我们所愿地放置了一个 Create 模块,到目前为止一切顺利,让我们再次查看 图 10-34 所示的代码。

原书 P429 图 10-34. 宏记录产生的代码

原书 P429 图 10-35. 宏记录产生的代码

大多数 VBA 命令影响当前选定的对象(Model.ActiveView.Selection) ,本例中,我们创 建的模块仍然处于活动状态,其标记为 object.11。为了设置我们刚创建模块的操作数,接下 来的三行代码都对 object.11 执行了 smFindTag 类型的查找操作,因此,宏似乎正确地记录 了我们所做的一切。下面让我们看看运行宏将发生什么。第一行代码在原先的 Create 模块 位置上放置了一个新的 Create 模块;第二行代码查找 object.11,即原始的对象,并且设置其 操作数。 宏像我们所设计的那样工作, 但其运行结果却并不是我们所预期的。 如果返回模型, 把两个模块都删除掉,再次运行宏,将会发生什么情况呢?结果系统出现错误,因为宏正在 查找一个实际并不存在的对象。 刚才所创建的宏运行起来显然没有什么效果, 因此读者可能想知道宏命令究竟还有什么 价值呢?读者想通过宏来记录一些应用,不做任何修改再重复使用,但是多数情况下,这是 很难实现的。宏的典型价值在于,其产生的代码可供参考。尽管上面的宏只是试验性的,它 却提供了大量有用信息,我们可以看到如何放置模块,应该给定哪些参数,如何通过标记查 找对象,如何设置模块的操作数,以及我们想修改的三个特定的操作数的名字。总之,这个 简单的宏给了我们一个很高的起点,使我们能够更容易地编写实际的代码。

宏记录的主要价值在于使学习和扩展 VBA 模型变得更加简单,一旦读者知道系统是如 何工作的,就可以使用同样的技术来解决其它问题。创建宏的数量是没有限制的,而且可以 根据需要混合或者匹配多个不同的宏。一句话,使用宏记录,结合本章中读者所学到的其它 技术,就能够给 Arena 的定制提供更加强大的能力。

10.3 模型 10-5:给用户提供到达选择
10.1 节我们利用 Arena 的特征把数据和模型集成了起来, 接下来我们将重点介绍如何与 用户进行交互。 在模型 10-5 中,我们将设置一套机制,当模型运行时允许选择呼叫到达是由随机过程 产生 (如原始模型 10-1) 还是由文件产生 (如模型 10-2) 运行开始时显示一个用户窗体 , (VBA 的术语叫做对话框)来提供选项,如图 10-36 所示。

原书 P430 图 10-36. Visual Basic 的用户窗体

用户单击所需的选择按钮,然后点击 OK 开始仿真运行。我们将撰写 VBA 代码,只有 要求的呼叫到达类型才能真正产生实体进入模型。 在本节结束时, 读者将学到很多精彩内容, 但现在让我们从窗体开始。

10.3.1 修改 Creation 逻辑
首先,需要对模型进行设置,使其既能从模型 10-1 的随机到达过程产生实体,也能从 模型 10-2 的输入文件产生实体。 为此, 在同一个模型中放置两套逻辑, 连接到 Process 模块, 这是呼叫逻辑的开始,如图 10-37 所示。

原书 P431

图 10-37. 模型 10-5 的呼叫生成逻辑

如果使用随机过程到达逻辑, 则将其 Create 模块的 Max Arrivals 项设置为 Infinite (如模 型 10-1) ,而文件逻辑的相应项则设置为 0,表示它不会产生实体进入模型。相反,如果要 使用文件逻辑,则将随机过程到达的 Create 模块的 Max Arrivals 项设置为 0,而文件逻辑的 相应项则设置为 1(还记得其逻辑只产生一个单一实体吗?) 。图 10-38 显示了不产生实体 的随机过程到达的 Create 模块。

原书 P431 图 10-38. Max Arrivals 为 0 的 Create 模块

要验证模型是否正常工作,可以编辑 Create 模块设置 Max Arrivals 的值,然后运行仿真 并观察 Create 模块后面的计数器。在运行开始处添加 VBA 代码之后,就不再需要担心 Max Arrivals 项了,我们将根据用户选择的到达类型,通过 VBA 给其赋予适当的数值。 继续之前,我们将对模型进行两个额外的修改,使 VBA 代码能够方便地找到所需的 Create 模块。 读者可能没有意识到, Arena 模型窗体中的每个对象都有一个相应的标记 (tag) , 这个标记在对象显示的时候并没有显示出来, 只能通过属性对话框进行访问 (读者可以右击 对象,选择属性打开属性对话框) ,如图 10-39 所示的 Create 模块。

原书 P432 图 10-39. 通过属性对话框修改模块标记

当添加对象时 Arena 使用 Object.nnn 格式给标记赋值,其中 nnn 是一个整数,随着模型 。如图 10-39 所示,将随机过程的 Create 模块的标 中放置的新对象而递增(如 Object.283) 记修改为 Create from random process,将文件到达的 Create 模块的标记修改为 Create from file,右击每个 Create 模块,从菜单中选择属性,然后输入适当的标记。最后,当 VBA 代码

需要查找这些特定的模块时,就可以使用 Find 方法搜索到匹配的标记值,由于是我们自己 给模块的标记赋值的, 所以可以保证其唯一性, 这样就能通过标记方便地找到相应的模块了。

10.3.2 设计 VBA 用户窗体
既然模型要能够触发两类呼叫到达,我们就再次使用 VBA 在每次仿真运行开始的时候 让建模者选择呼叫到达类型。首先绘制出要显示的窗体,然后撰写 VBA 代码来响应在窗体 上的选择。 为了添加用户窗体,请打开 Visual Basic 编辑器,选择菜单 Insert>UserForm,这将在 VBA 项目中添加一个新对象,并打开一个窗体,可以在该窗体上布置控件(与用户交互的 对象) 添加图片和标签等。 、 我们将忽略在 VBA 中设计窗体的细节, VBA 帮助主题 Microsoft Forms Design Reference 可以帮助读者理解有关的基本概念、工具栏和窗体的特点。 要通过 VBA 代码访问窗体,需要给窗体命名,如图 10-40 所示,在属性对话框的 Name 项中输入 frmArrivalTypeSelection。

原书 P433 图 10-40. VBA 项目的用户窗体

可以直接从控件工具栏中把控件拖放至窗体上来设计窗体的内容。 将一个标签控件拖放 至窗体,在其属性对话框的 Caption 项中输入如图 10-41 所示的描述性文本(Call entities can…) ;然后拖放一个选择按钮在该标签下方,将其 Name 修改为 optFromRandomProcess, Caption 修改为 Random interarrival-time process,Value 设置为 True 使其默认为选择状态; 再添加一个名称为 optFromFile 的选择按钮,caption 属性设置为 Arrival times from a file,默 认值为 False; 最后在窗体底部添加一个命令按钮, 命名为 cmdOK, caption 设置为 OK, Default 属性设为 True,这样按下 Enter 键就能产生和在该命令按钮上单击相同的效果。

原书 P433 图 10-41. 用户窗体的布局

这个用户窗体现在成了 Arena 模型的一部分,当读者保存模型文件的时候,窗体也随之 保存。在 VBA 知道如何使用窗体之前,它还没有多大用处,我们接下来就要进行这一项具 体的工作了。

10.3.3 显示窗体并设置模型数据
我们想要模型的 VBA 代码根据用户在仿真过程中实际需要的呼叫类型来打开和关闭两 个 Create 模块的 arrivals 项, 这就必须在仿真运行之前设置两个 Create 模块的 Max Arrivals, 这样该值就会编译到模型中, 就像在模块对话框中输入相应的值一样。 如果读者还记得 10.2 节中所列的步骤,读者就会发现在 RunBegin 事件中处理这个问题再好不过了,该事件在仿 真运行开始模型检验之前调用,所以通过 VBA 代码对模块数据所作的改变将在仿真运行的 时候起作用。 当然,我们要向用户显示窗体,让用户选择所需的到达类型,在 RunBegin 事件中插入 一行代码即可完成。双击 Project 框的 ThisDocument 对象,在左边的下拉列表中选择 ModelLogic,在右边的下拉列表中选择 RunBegin,进入 RunBegin 事件,如图 10-42 所示。

原书 P434 图 10-42. 在 VBA 项目中添加 ModelLogic_RunBegin 事件

显示窗体的代码如图 10-43 所示, 通过 Show 方法来显示名为 frmArrivalTypeSelection 的 窗体。

原书 P435

图 10-43. ModelLogic_RunBegin 事件中显示窗体的代码

仿真运行开始时这行代码将显示窗体并将程序控制权交给该窗体, Show 方法执行之后, VBA 进程将被挂起, 直到用户再次激活窗体的 VBA 事件, 同时 Arena 也被暂停, 直到 VBA 代码从 RunBegin 事件中返回。这就有时间让用户操作窗体,使 VBA 完成 RunBegin 的有关 工作。因此,如果读者现在运行模型,Arena 的 VBA 将立即显示窗体和用户交互,而我们 还没有撰写有关的交互代码,所以读者好像就得停滞在这里了,幸亏 VBA 窗体有一个关闭 按钮(在窗体的右上角) ,读者可以单击该按钮来关闭窗体,使 Arena 继续运行。 用户选定到达类型并单击 OK 按钮后,接下来 VBA 代码应该做出响应。用户可以在显 示窗体上单击选择按钮改变选项,但是最终选定并单击 OK 按钮时,VBA 代码应该能够在 Create 模块中设置适当的值,使窗体消失并继续仿真运行。 和 Arena 类似,VBA 用户窗体也有预定义的事件。要在单击 cmdOK 按钮触发的事件中 插入有关代码,请在项目栏中双击 frmArrivalTypeSelection 打开窗体设计器,然后双击 OK 按钮,Visual Basic 编辑器自动打开和用户窗体相关的代码窗体,并且为 cmdOK_Click()事件 插入开始和结束语句,如图 10-44 所示。

原书 P435 图 10-44. 用户窗体的 cmdOK_Click 事件

我们将在这个事件中写入所有与用户交互的代码,包括:     定位任何一个 Create 模块 在每个 Create 模块中设置 Max Arrivals 值 添加其它有关代码 关闭用户窗体

在 Arena 对象模型中,代码通常设计用来模仿类似通过鼠标和键盘直接进行交互的操 作,理解这一点很有帮助。比如读者想修改 Create 模块,首先就要找到并打开该 Create 模 块,然后进行编辑。 为了描述 cmdOK_Click 事件的代码,我们首先给出如图 10-45、10-46 以及 10-49 所示

的小段代码, 这样方便读者一边阅读注释一边查看有关代码。 10-50 在完整的 cmdOK_Click 图 程序中重复了所有的代码,以便展示它们是如何协同工作的。 我们将从定位两个 Create 模块的代码开始, 这样才能给 Max Arrivals 项赋予适当的数值。 在 VBA 代码中使用 10.3.1 节赋予的标签(tag)值来查找 Create 模块,如图 10-45 所示(我 们包括本节中声明变量的 Dim 语句,通常变量声明语句都放在函数开始位置,如图 10-50 的完整代码所示,但这也不是必须的) 。给变量 nCreateRandomProcessIndex 赋值的语句告诉 VBA 在 Modules 集合中查找标签值为 Create from random process 的模块 (smFindTag 常量表 示 Find 方法去匹配标签值而不是模块名称值) ,同样地,nCreateFileIndex 变量查找从文件 产生实体的 Create 模块。获取每个索引之后,它们就被用来指向相应的代表 Create 模块的 变量(oCreateRandomProcessModule 和 oCreateFileModule) 语句用于检测返回的索引值 。If 是否为 0,从而指出是否存在满足标签值的模块(例如当相应的 Create 模块已经被删除时, 程序就会给出提示信息) 。 到目前为止, 有两个变量指向 Create 模块, 只需要检查用户窗体的选择按钮, 并给 Max Arrivals 赋值即可。VBA 代码可以检测 Value 属性,返回选择按钮的设置值,如图 10-46 所 示。如果点击 OK 按钮时用户选定的是 optFromRandomProcess 按钮,则其 Value 为 True, 此时应该让 Create 模块从随机过程产生实体(即设置该 Create 模块的 Max Arrivals 值为 Infinite) ,并且关闭另一个 Create 模块不要从文件中产生实体。否则,设置随机过程到达的 Create 模块的 Max Arrivals 值为 0,而从文件产生实体的 Create 模块则为 1(这样控制实体 将进入模型并且从文件中读取到达时间) VBA 代码可以通过 Data 方法修改模块的字段 。 (也 称操作数)值。 如果读者正在聚精会神地学的话,可能已经注意到代码中根本不包含 Max Arrivals 字 样,Create 模块定义最大到达数的字段叫 Max Batches。在 Arena 模块中,出现在模块对话 框的文本叫做提示信息,它可能和模块定义的内在操作数名称一致也可能不一致,而 VBA 中模块对象的 Data 方法要求使用操作数名称。 要查找模块的操作数信息, 可以查阅和 Arena 一起安装的文本文件 (位于 Arena 的程序文件目录下)本例中, 。 Create 模块来自 Basic Process 面板,打开 BasicProcess.txt 文件,找到 Create 模块,它位于文件顶端。查看图 10-47 的提示 信息列表, 可以发现 Max Arrivals 的操作数名称为 Max Batches, 因此输入 Max Batches 作为 Data 方法的参数。

原书 P437 图 10-45. VBA 中通过标记定位 Create 模块

原书 P437 图 10-46. 根据用户选择更新 Create 模块

原书 P437 图 10-47. BasicProcess.txt 的文件列表

作为一个新手,让我们回顾一下有关内容。用户可能通过单击 Run 工具栏的 Go 按钮开 始仿真运行,Arena 调用 VBA 事件 ModelLogic_RunBegin,其中的 VBA 代码则调用窗体 frmArrivalTypeSelection 的 Show 方法,用户可以在显示的窗体上单击选择按钮来选择所需 的到达类型(VBA 窗体在此只允许选定一个选择按钮) ,Arena 在此期间被挂起,直到 VBA 代码完成其所有工作为止。 用户最终单击窗体的 OK 命令按钮,使 VBA 调用 frmArrivalTypeSelection 代码窗体的 cmdOK_Click 事件,找到 Create 模块,并在 Max Arrivals 字段中输入适当的值。请记住,所 有这些操作都发生在 RunBegin 事件中,该事件在检测并编译模型之前调用,所以模块数据 的变化都将在仿真运行过程中使用。不能在 RunBeginSimulation 和 RunBeginReplication 事 件中撰写类似代码, 因为这两个事件在模型编译并初始化运行之后才调用, 此时我们只能通 过 SIMAN 模型对象访问实时数据(可以回到图 10-28 查看有关 Arena 的 VBA 事件顺序) 。 在结束定制工作之前, 再添加一些有趣的东西到项目中。 在模型窗体上放置一个声音文 件,设定其唯一的标记,撰写 VBA 代码找到该声音文件并播放一些激动人心的音乐。 要把文件放入 Arena 模型,请返回 Arena 模型窗体,打开文件浏览器(例如 Explorer 或者 Microsoft Outlook) ,找到声音文件,并把它拖入 Arena 模型,如图 10-48 所示。

原书 P438 图 10-48. 向 Arena 中拖放文件

Arena 模型中的声音对象是一个嵌入文件,它包含原始文件的一个拷贝。该文件也可以 通过 Windows 剪贴板或者通过 Arena 的 Edit>Insert New Object 菜单放入模型。对象本身就 像存储在磁盘上的声音文件一样, 双击它就可以放出动听的音乐。 为了给声音对象设置一个 唯一的标记,请在 Arena 模型窗体中右击其图标,从菜单中选择属性,输入 Mission Possible 作为标记值。 最后返回 Visual Basic 编辑器窗体, 在运行开始处插入激活声音文件的代码, 如图 10-49 所示。再次使用 Find 方法查找所需的对象,不过这次是用模型对象的 Embeddeds 集合而已。 如果找到标记为 Mission Possible 的对象, 就使用 Do 方法激活它 (本例中嵌入的是声音文件, 激活后即播放声音) 。

原书 P439 图 10-49. 播放声音文件的代码

运行仿真多次以后,读者可能想关闭声音文件,只需把计算机的扬声器关了即可,或者 把播放音乐的语句注释掉,或者改变 If 条件使播放语句不执行(如要执行时再把条件改回 来即可) 。 现在我们已经完成了所有的工作, 最后一步就是要关闭用户窗体, 退出 OK 按钮的 Click 方法, Arena 继续仿真运行, 让 这些代码在图 10-50 (列出了 cmdOK_Click 事件的完整代码) 的底部。 窗体隐藏并且 cmdOK_Click 程序退出之后,窗体的 Show 事件调用结束,VBA 代码将 控制权返回 ModelLogic_RunBegin 子线程。回到图 10-43,可以看到 RunBegin 只是简单地 退出子线程。此后 Arena 检测模型,初始化仿真运行,开始第一次仿真实验,读者还可以同 时听着嵌入声音文件的动听音乐。

原书 P440 图 10-50. 完整的 cmdOK_Click 事件代码

10.4 模型 10-6:在 Microsoft Excel 中记录并用图表显示 模型结果
10.1.2 节介绍了如何向一个现有的 Excel 工作簿中写入数据,以及如何使用现有的图表 工具。本节将介绍如何在 Arena 中使用 VBA 达到更加完全的控制,具体包括创建工作簿、 格式化数据,以及创建图表。展示如何使用 VBA 在 Excel 电子表格中记录每一个完成的呼 叫的信息,目标是创建一个包含呼叫到达时间、结束时间和呼叫周期的 Excel 文件,并对呼 叫周期图表化,来查看任何感兴趣的趋势,如非常短或非常长的呼叫组。图 10-51 是模型结 果的一个实例。 为了建立必要的逻辑来创建电子表格并且用图形形式显示结果, 需要完成三个方面的任 务。首先,需要撰写必要的 VBA 代码创建 Excel 文件,在每次仿真运行开始时打开该文件, 并且在数据工作簿上写入新的头信息以检测每天的结果 (工作簿是 Excel 文件中标记的页) ; 其次,需要修改模型逻辑并撰写必要的 VBA 代码,在每次销售呼叫完成之后使其实体触发 一个 VBA 事件将有关值写入工作簿中;最后,撰写 VBA 代码,在每次仿真实验结束时创 建呼叫周期图表,并且在仿真运行结束时保存文件。

原书 P441 图 10-51. Microsoft Excel 结果

接下来的几节描述了这些步骤, 但只是强调有关概念并且列出相应的代码, 如果读者对 这方面的内容有更深的兴趣,请查看有关 VBA 和 Arena 对象模型的帮助信息,以及相关的

SMARTs 库模型,也可以阅读任何有关使用 VBA 开发 Excel 解决方案即 Excel 定制方面的 书籍,还有许多学习 Visual Basic 方面的资源,如各种各样的书籍、CD、训练课程和网站。

10.4.1 运行开始时建立 Excel
为了在仿真过程中存储呼叫数据,首先创建 Excel 文件,就像运行 Excel 打开一个新文 件一样。在每天(即仿真实验)开始时,为数据列写入头信息。为此我们将使用两个 Arena 内置的 VBA 事件:RunBeginSimulation 和 RunBeginReplication。在 RunBeginSimulation 事 件中放置启动代码运行 Excel 并创建新的表格(即文件) ;由于每次仿真实验都需要一组新 的文件标识,所以在 RunBeginReplication 事件中写入表头信息。 图 10-52、10-54 和 10-55 列出了模型 10-6 的 VBA 代码,要在 Arena 模型中查看这些代 码,请打开 Model 10-06.doe 文件,该文件其实是模型 10-2 加上本节所描述的代码构成的, 选 择 菜 单 Tools>Macro>Show Visual Basic Editor , 并 在 Visual Basic 项 目 栏 中 双 击 ThisDocument 项 , 注 意 , 代 码 窗 体 中 创 建 的 内 置 事 件 的 相 应 函 数 会 自 动 增 加 前 缀 ModelLogic_,为了方便讨论,我们不管该前缀,因为 Arena 的 VBA 事件列表会自动进行补 充。 图 10-52 显 示 了 全 局 变 量 的 声 明 部 分 , 包 含 了 所 有 过 程 之 外 ( 即 在 定 义 过 程 ModelLogic_RunBeginSimulation 的语句之前)的代码,通过一系列的 Dim(Visual Basic 的 变量声明语法,dimension 的缩写)语句定义所有过程的全局变量,同时包含 Option Explicit 语句强制 VBA 中所有的变量必须声明,我们建议使用这个选项来防止变量名称的误输入导 致的难于查找的代码错误。

原书 P442 图 10-52. 模型 10-6 的 VBA 全局变量声明

声明一个全局变量 oSIMAN,在 RunBeginSimulation 中将其指向模型的 SIMAN 对象, 用于在剩余的过程中从运行的仿真中获取数值。变量类型 Arena.SIMAN 从 Arena 对象库中 前两行 Dim 语句声明的其余变量用于追踪在多个过程 将 SIMAN 对象赋予了 oSIMAN 变量。

中所需的数值,我们将在查看有关代码时对其进行描述。 剩余的全局变量的数据类型是以 Excel.开头的,它们是 Excel 对象库中的对象变量。因 为 Excel 是一个外部应用程序(不像 Arena,是 VBA 代码的宿主程序) ,必须事先建立好到 Excel 库的引用。可以通过菜单 Tools>References 打开 Visual Basic 编辑器窗体,在引用对话 框中选定 Microsoft Excel Object Library,如图 10-53 所示。这要求运行该模型的计算机必须 安装有 Excel 应用程序,如果没有 Excel,虽然可以打开和编辑模型,但是不能完成仿真运 行。 检查如图 10-54 所示的 RunBeginSimulation 事件代码,首先设置 oSIMAN 变量等于一系 列包含点的字符,当读者阅读使用对象的代码时,从右往左使用点来分离项目,这样阅读对 象通常更有帮助。例如,语句 Set oSIMAN = ThisDocument.Model.SIMAN 可以想象成设置 oSIMAN 变量指向 SIMAN 属性,该 SIMAN 属性属于 Model 对象,而 Model 对象包含在 ThisDocument 对象中。因为没有仔细钻研 Arena 对象模型或者 Visual Basic 的技术细节,就 让我们认为 ThisDocument 指向包含 RunBeginSimulation 事件代码的 Arena 模型, Model 是其 中的主要对象, 它提供访问模型具体内容的权限, SIMAN 则是 Model 对象中的一个对象, 而 使用它可以获取或修改模型的运行期数据(如资源状态、变量值和实体属性等) 。

原书 P443 图 10-53. VBA 的 Tools>References 对话框

原书 P444 图 10-54. 模型 10-6 的 RunBeginSimulation 事件的 VBA 代码

oSIMAN 变 量 指 向 SIMAN 运 行 数 据 之 后 , 就 可 以 使 用 它 在 VBA 的 全 局 变 量 nArrivalTimeAttrIndex 中存储 Call Start Time 属性的索引值, 以便在仿真运行的整个过程中当 实体离开模型时获取有关属性值。Arena 对象模型的 SymbolNumber 函数用于将模型元素的 名称(如属性)转换成 Arena 运行期索引(一个整型数值,范围从 1 至模型包含的所有元素

的数目) 。将属性 Arrival Time 的索引存储在 VBA 全局变量中使用,所以只需要 Arena 计算 一次索引值。仿真过程中执行的代码(在 VBA_Block_1_Fire 事件中,我们将简单讨论该事 件)将索引值传至 EntityAttribute 属性函数以获取实际的属性值。 接下来,调用 ActiveX 自动化方法 CreateObject 启动 Excel,设置应用程序的 Visible 属 性为 True 以使 Excel 可见,然后使用方法 oExcelApp.Workbooks.Add 定制 Excel 来创建一个 新的 Excel 文件(该文件也指向一个电子表格) ,读者可以将这想象成向 oExcelApp 应用程 序的 Workbooks 集合中添加一个元素。oWorkbook 变量将存储一个指向新创建的 Excel 表格 的指针,仿真运行结束时将该表格存入文件。RunBeginSimulation 事件的其余代码行设置 oWorksheet 变量指向新创建的 Excel 电子表格的工作簿,并且设置该工作簿的一些特性。如 果读者要使用 Excel,我们建议读者利用其宏记录的功能,这样就可以稍作修改甚至不作修 改直接将 Excel 宏记录中的代码拷贝到 Arena 中,这比读者自己尽力研究 Excel 对象模型撰 写代码完成某些任务更有效率。

原书 P445 图 10-55. RunBeginReplication 事件的 VBA 代码

RunBeginSimulation 事件只在仿真运行开始时调用一次,而 RunBeginReplication 事件在 每次仿真实验开始时 Arena 都会调用, 模型 10-6 的 RunBeginReplication 事件的代码如图 10-55 所示,我们使用该事件来为新一天的数据撰写列的头信息。为了获取要写数据的列,使用当 前的实验次数(通过 RunBeginSimulation 事件中初始化好的 oSIMAN 全局变量从 Arena 对 象模型的 SIMAN 部分获取仿真实验次数信息)进行适当的计算得到所需的三列(参考图 10-51 查看列的布局, 每次仿真实验都包含三个数据列和一个空白列, 代表一天的呼叫信息) 。 With oWorksheet 和 End With 语句之间的代码使用 Excel 对象模型给工作簿的不同单元格 赋值,并对其进行格式化处理以满足图 10-51 的设计要求。读者可以使用 Excel 的帮助查阅 定制 Excel 的内容来了解有关技术细节。最后一个语句给全局变量 nNextRow 赋值为 3,该 值将决定在仿真运行过程中要从哪行开始撰写每一个呼叫的结果信息。

10.4.2 使用 VBA 模块存储呼叫数据
下一个任务不但要撰写 VBA 代码,还要修改模型逻辑,让我们先修改模型逻辑吧。呼 叫完成之前(即通过 Dispose 模块离开模型之前) ,应该触发 VBA 代码在 Excel 工作簿的下 一行撰写呼叫到达时间、呼叫完成时间和呼叫周期等统计信息。此处要触发的 VBA 代码并 不像我们检测的头两个事件那样(仿真运行和每次仿真实验开始时调用)可以提前预测到, 相反, 它是由仿真模型的动态性来将确定何时应该执行 VBA 代码的。 为了实现这样的任务, Arena 在 Blocks 面板中提供了一个 VBA 模块, 实体经过该模块时, Arena 将触发其中的 VBA 代码,而不是包括模块本身的一些预定义的逻辑。图 10-56 显示了修改后的呼叫中心的模型 逻辑,在释放销售呼叫实体之前插入了一个 VBA 模块。

原书 P446 图 10-56. VBA 模块

当读者放置一个 VBA 模块时,Arena 给它设置了一个唯一的值,用于在 Visual Basic 项 目中关联特定的 VBA 模块代码, 这个数值是从 1 开始的整数, 每次往 Arena 中新增一个 VBA 模块该数值就自动加 1。要编辑 VBA 模块的代码,请返回 Visual Basic 编辑器,在 ThisDocument 代码窗体的对象列表中,选择适当的项目,如图 10-57 所示。 和 VBA 模块相关联的事件名称为 VBA_Block_1_Fire(),其中 1 为 Arena 提供的用于标 识 VBA 模块的数值,其代码如图 10-58 所示。

原书 P446 图 10-57. Visual Basic 编辑器中选择 VBA 模块 1 的事件

原书 P447 图 10-58. VBA_Block_1_Fire 代码

当一个呼叫实体完成处理进入 VBA 模块时,就将触发 VBA_Block_1_Fire 事件。过程中 的头两行代码从运行中的仿真程序获取信息(通过 RunBeginSimulation 事件中设置的 oSIMAN 变量完成) 。首先,将索引为 nArrivalTimeAttrIndex 的活动实体属性值存入局部变量 dCreateTime 中,nArrivalTimeAttrIndex 全局变量是在所有过程之外声明的(所以任何过程都 可以使用) ,在 RunBeginSimulation 中将其指向了 Call Start Time 属性(使用 SymbolNumber 函数) ;其次,将当前的仿真时间存储在局部变量 dCurrentTime 中。这些数值用来把实体信 息保存在电子表格中,使用 nNextRow 变量确定行的位置,然后将其加 1。这些代码为某特 定实体执行之后,实体将回到模型并进入 Dispose 模块,然后被释放。

10.4.3 将结果图形化并在仿真结束时完成清理工作
我们最后的任务就是为每次仿真实验创建呼叫周期的图表, 并且在仿真结束时保存电子 表格文件。尽管可以在运行结束时绘制所有图形(因为数据仍然存在于数据表格中) ,我们 还是在仿真过程的 RunEndReplication 事件中完成这个工作。 每 次 仿 真 实 验 结 束 的 最 后 一 个 实 体 处 理 完 成 后 , Arena 都 会 调 用 VBA 的 RunEndReplication 过程。本模型中,我们将作图表示包含在刚刚完成的仿真实验的工作簿 的 Duration 列的数据,用曲线图展示那次仿真实验的呼叫周期。我们将跳过对制图代码的 探讨,如果读者对 Excel 的作图功能很感兴趣的话,建议读者浏览在线帮助,试着操作不同 的制图选项,并用宏记录下来仔细研究。 最后,仿真结束时调用 RunEndSimulation 过程,只需要将 Excel 工作表保存到位于模型 同一目录下的 Model 10-06.xls 文件中即可(使用 ThisDocument.Model.Path) ,保持 Excel 处 于运行状态。图 10-59 显示了这两段程序的代码。

原书 P448 图 10-59. 仿真实验及仿真结束时的 VBA 代码

运行仿真模型可以看到仿真开始时桌面上出现了 Excel 程序,随着呼叫实体离开模型, 一系列数值加入到了工作簿中,最后,每次仿真实验结束时都会创建相应的图形。 正如读者所期望的那样,Arena 和其它应用程序的集成不止局限于向 Excel 中写入数据 和创建图表,如果读者已经安装了一个支持定制的应用程序,Arena 的 VBA 接口就允许读 者通过外部应用程序的对象模型做任何可能做的事情,如在 Excel 工作簿中创建图表、在 Oracle 数据库中对运行数据进行分类等等。

10.5 使用 Arena 专业版创建模块:Template 10-1
在结束本章之前,我们将简要介绍如何使用 Arena 专业版(Professional Edition)通 过构建新的模块来进行定制。Arena 教学版(随本书附赠的 CD 中有该版本)不包含构建新 模块的功能,而研究版和商业版都有。尽管如此,通过本节读者还是可以理解在 Arena 模型 中使用新创建的模块的过程。 因为只是要对创建新模块有一个快速的了解, 所以我们将浏览一下构建一个非常简单的 模块的步骤,同时给读者展示一些窗体和对话框。结束的时候将设计出一个可用的(也是有 用的)模块,我们只会略微谈到一小部分构建 Arena 模板的特征,但这已经足以达到使读者 认识专业版本功能的目的了。 要想更彻底的了解如何使用研究版本和专业版本构建模块, 读 者可以查阅 Arena 专业版的参考手册。

10.5.1 Create from File 模块
关于模板,让我们先回顾一下呼叫中心模型 Model 10-02.doe 的修改过程,我们开发了 一套逻辑来从文件读取到达时间信息产生呼叫实体,为了完成这个任务,使用了四个模块: Create、ReadWrite、Delay 和 Separate,加上 File 数据模块协同工作,从而在适当的时间产 生实体进入模型。 如果我们正在做大量的建模工作, 而且这些工作要使用上述方法产生实体, 那么把这些模块 (以及保证模型正确工作的适当的数据) 集成在一个模块中就可能非常快捷, 而且也不需要记住使实体在适当时候进入模型的诀窍,模型本身看起来也会更加简单。 为了构建这个模块(命名为 Create from File) ,先拷贝模型 10-2 建立好的模型逻辑到一 个模板文件中;然后定义操作数(双击模块时出现在对话框中的字段) ,当使用 Create from File 模块的实例时就可以修改文件名称 (像原始模型假定所有的模块都是从文件 Model 10-02

Input.txt 中读取信息就有些武断) ;再制作一幅图片以便在模板工具栏上显示出来;当模块 放置在模型窗体上时排列显示对象。这四个简单的步骤:定义逻辑、操作数、面板图标和用 户视图,是在 Arena 中构建模板的基础。 在仔细察看每一步操作之前,先看看最终结果,如图 10-60 所示,一个 Create from File 模块放置在模型窗体上,读者可能认为很好,这个模块看起来和其它模块一样,事实上,它 也的确和其它模块一样。当读者使用 Arena 的模板设计工具创建自己的模块时,最终的结果 就是一个模板对象(.tpo)文件,这和读者一直使用的 BasicProcess.tpo, AdvancedProcess.tpo 等模板一样。Arena 背后的一个重要理念就是,可以容易地创建个性化的模型结构,并且和 标准模板协同工作。

原书 P450 图 10-60. 模型中使用的 Create from File 模块

10.5.2 模板源文件:Template10-01.tpl
要检查 Create from File 模块的定义,请查看包含逻辑、操作数等的 Template 10-01.tpl 文件。如果读者正在运行 Arena 的研究版本或专业版本,可以通过标准菜单 File>Open 打开 ,并选择 Template 10-01.tpl。这将打 该文件,只是要把文件类型更改为 TemplateFiles(*.tpl) 开模板窗体,列出模板包含的所有模块(本模板只有 Create from File 一个模块) 。其中的 Professional 工具条(图 10-61)上的按钮可以打开其它不同的定义模块的窗体,预览模块对 话框,产生模型使用的模板对象文件(.tpo) 。

原书 P450 图 10-61. 模板窗体和工具条

10.5.3 面板图标和用户视图
在深入研究模块 Create from File 之前,我们将简单地讨论模块使用者看到的头两件事 情。要在 Arena 模型中使用该模块,以及包含它的模板面板需要添加到 Template 工具条中, 如图 10-60 所示。Arena 在工具条上显示出模板创建者为每个模块绘制的图片,即模块的面 板图标。在模块 Create from File 的实例中,该图片是一个带箭头并卷角的页面(模块设计 者的艺术能力只能做到这样了,它代表从文件中产生实体) 。 当建模人员把模块的一个实例放入模型窗体时, 添加到窗体的图形对象同时就成了模块 的用户视图。每个模块都至少有一个存在形式,最典型的就是模块名称周围有一个方框,大 多数模块也有一个或多个入口和出口用于连接其它模块。参照图 10-60,Create from File 模 块显示了 Name 操作数(建模者在对话框中输入的模块描述信息) ,该模块有一个单一的出 口(连接到 Process 模块) 。

10.5.4 模块逻辑和操作数
当模块放置在模型窗体上时, 其核心就在于仿真过程中该模块完成的实际逻辑。 在模板 上构建模块,就像构建仿真模型一样,从其它模板中放置并连接模块,从而定义出该新模块 的逻辑。Create from File 模块逻辑包含模型 10-2 使用的模块,以及一个 Assign 模块用于计 算离开 Create from File 模块的实体数目。 10-62 在模块定义逻辑窗体中显示了其逻辑。 图 从 模型 10-2 中拷贝四个所需的模块以及它们之间的连接,然后粘贴到逻辑窗体,再从 Blocks 面板中添加 Assign 模块,把它连接到 Separate 模块的 Duplicate 退出点。

原书 P451 图 10-62. 模块定义的逻辑窗体

原书 P452

图 10-63. 放入模型时出现的模块对话框

每次把 Create from File 模块放进模型时,都会包含潜在的逻辑以便根据文本文件中的 数据产生实体进入模型。 机敏的读者可能会问: 什么文件?在模型的什么地方?这就是模块 操作数要完成的工作了。如果只是使用模型 10-2 的原始逻辑,Create from File 模块就只能 从文件 Model 10-02 Input.txt 中产生实体, 所以添加操作数 File Name 来允许在模块中输入新 的文件名,通过使用一种特殊的操作数类型将该文件名添加到模型中作为 File 数据模块的 一部分。再添加一个名为 Name 的操作数,作为流程图的一部分显示在用户视图中。还有一 个名为 Time Units 的操作数用于定义数据文件的信息类型。图 10-63 显示了 Create from File 模块对话框。 在模板的操作数窗体上定义 Create from File 操作数, 如图 10-64 所示 (使用定义对话框 定义 File Name 操作数) 。在操作数定义对话框给操作数命名为 File Name(这样就能在 File 数据模块中对它进行引用) ,采用默认的 Basic 类型,允许输入任何字符,保留 Default Value 为空,勾选 In Userview 选项以便在模型窗体的模块句柄中显示文件名称,勾选 Required 选 项使建模者在编辑模块时必须给出非空值。 在操作数窗体上也定义一个名为 Name 的操作数,它将在模型窗体上显示出来,并且定 义 ReadWrite 和 File 模块的部分 File Name。Time Units 操作数在一个下拉列表中给定 Seconds、Minutes、Hours 和 Days 选项,其值将传入逻辑窗体的 Delay 模块。最后,定义名 为 Destination 的操作数, 其类型为 Exit Point, 它可以在逻辑窗体的 Assign 模块的 Next Label 项引用,用于在包含 Create from File 模块的模型中建立实体流。当 Arena 产生 SIMAN 模型 时(例如验证[Check]模型时) ,从逻辑窗体的 Create 模块开始(由于 Create 是一个特殊的模 块,用于产生实体流进入模型) ,根据连接进入 ReadWrite、Delay、Separate 和 Assign 模块, 为初始实体建立循环离开 Separate 模块返回 ReadWrite 模块, 通过 Assign 模块的 Destination 操作数,连接到任何与 Create from File 模块相连的模块上,例如图 10-60 所示的 Process 模 块。

原书 P453

图 10-64. 包含文件名称定义对话框的操作数窗体

读者可以将 Exit Point 操作数类型看作是上升层,它从 Create from File 模块的内在逻辑 连接到包含该模块的模型的主体逻辑;当然,也有一个 Entry Point 操作数类型,它是下降 层,用于建立高层逻辑到包含在其它模块的逻辑窗体中的模块的连接。 用户在模块对话框中输入的数值通过操作数引用(operand referencing)传递到逻辑窗 体中的模块,如果逻辑窗体中的模块的某些字段值放在两个单引号(')之间,那么该字段 的实际值将从模块对话框获取,即从和单引号之间的字符串名称相同的操作数得到实际值。 我们在此定义 ReadWrite 模块对话框的 Arena File Name 和 File 模块的电子表格为 'Name'.ArrivalsFile,如图 10-65 所示。例如输入 June26Data 作为 Create from File 模块的名 称,那么用于仿真的 Arena file name 就是 June26Data.ArrivalsFile(通过 ReadWrite 和 File 模块传递) 。Assign 模块通过 Destination 操作数确定退出点连接对象也是采用同样的操作数 引用机制,在逻辑窗体的 Assign 模块的 Next Label 字段输入'Destination'建立该模块的退出 点。

原书 P454 图 10-65. 逻辑窗体模块的操作数引用

到目前为止,Create from File 模块的定义已经完成,它允许用户指定包含到达时间数据 的文件名称,并且连接到其它模块。Create from File 模块的潜在逻辑同时建立一些固定的逻 辑元素(即建模者不能更改的部分) 。特别地,通过 Create from File 模块进入模型的每一个 实体都有一个名为 Call Start Time 属性,用于存储实体到达时间值(因为 ReadWrite 模块保 留着该赋值功能) 。当读者设计模块的时候,需要确定哪些东西允许用户修改(例如文件名 称) ,哪些东西应该保护起来不让用户修改(例如属性名称和有关赋值) 。 读者所熟悉的大多数模块都包含许多操作数,通常也包括复杂的逻辑。这些模块(例如 Arena 模板面板提供的模块)都是用 Arena 专业版本开发的,它们的面板图标、用户视图、 操作数和内在逻辑则是使用软件的标准模板设计能力开发的。 利用这些模块的特征可以帮助 读者更好地掌握 Arena 专业版本的功能。在这里我们只提及一些基本的结构和产品功能,结

束本章之前,我们将介绍一下个人和组织使用定制模板的一些相关问题。

10.5.5 使用模板
开发模板可能满足多方面的需求,一些用于巨大的目标市场,如 Arena Contact Center Edition 或者 Arena Packaging Edition;其它则可能只是从实用的角度考虑的,如本章提出的 简单例子。 开发 Arena 模板最主要的是用于商业市场,典型的是定位在特定的工业,例如高速生产 行业或客户关系中心。定位于工业的模板有两个方面的主要优势,首先,模板可以使用适于 工业的专业术语,使建模者能够快速地把一个实际系统转化成软件模型;更重要地,通过 Arena 的层次级别,模板可以构建成完全客户化的,从而精确地代表工业系统的元素。模板 设计者有能力准确地模拟设备、人员、产品、部件等等的行为,提供任何适用于不同系统元 素的类型选择。而且,通过 Arena 支持的 ActiveX 自动化技术,可以产生向导和其它工具与 模板一起协同工作,来生成特定的图形和报告、直接从外部数据库调用数据等等。 使用 Arena 专业版本设计的许多模板都可以辅助建模者设计特定的系统、设备或过程, 但它们可能不是商业级的, 尽管其适用面可能比商业模板更窄, 但这些模板和工业模板一样 有许多共同的目的,并提供许多同样的好处。例如,可以设计一个模板用于分析卡车装载方 案, 或者描述到达的呼叫分派给技师的规则。 这些基于应用的模板和基于工业的模板一样受 益于 Arena 的多层结构:提供给建模者的接口可以定制得非常熟悉且易于操作(采用图形动 画或用户熟知的术语) ;精确地使用最终应用环境的元素。一些实例中,如果同样的问题在 建模过程中重复出现,建模者就可以只为个人使用目的构建特定的模板;其它实例中,可以 构建在一个建模群体中通用的模板,应用模板也可以在企业的不同建模群体中共享。 对于一个建模者而言,Arena 专业版本提供了一个复用建模者在建模过程中学到的建模 技术的机会。随着编程工具的发展,过程、子线程、函数都可以复用代码,此后,面向对象 的工具允许在软件中定义对象达到完全复用的目的。 模块可以认为和面向对象软件中的对象 很相似, 它允许读者充分利用一个过程的特点, 而这个过程是读者在建模时可以复用并在每 次使用时可以进行定制的。本节设计的 Create from File 模块就是这类模板的一个例子。一 旦一项建模技术形成并测试通过之后, 其实现细节就隐藏在模块定义中了, 再次使用同样的 技术时,就可以不去研究其实现方法和细节,而且因为内嵌的逻辑已经通过测试,所以风险 和错误也将大大减少。

10.6 小结
本章讨论了定制 Arena 的许多问题,以及把 Arena 和其它应用程序相集成的方法,它们 只是 Arena 定制的一部分内容。我们还粗略地介绍了 VBA,以及如何让 Arena 和 Microsoft Office 协同工作,还使用 Arena 专业版本定制了一个模型结构。本章的内容只是冰山一角, 目的在于激发读者的想象和兴趣,给读者足够的基础知识自己继续深造。 如果读者继续阅读,就会发现 11 章讲述如何对连续过程建模,例如液体或大批物料的 流动;然后在 12 和 13 章,我们将把精力集中在一些重要话题上,例如好的仿真研究的基础 和支持等。

10.7 练习
10-1 修改模型 10-1 的仿真逻辑,将到达时间间隔和加工时间(不包括任何等待时间) 存储在属性中,然后使用高等操作面板的 ReadWrite 模块把这两个属性写入 Excel 或 Access 文件中(如果读者没有安装 Excel 和 Access,则将其写入一个文本文件中) 。 10-2 从模型 10-2 开始, 使用练习 10-1 产生的数据文件指定呼叫到达逻辑和呼叫处理时 间。注意,由于文件中的数据是到达时间间隔而不是绝对到达时间,所以仿真逻辑也应该稍 作修改。和练习 10-1 进行比较,看看仿真结果如何? 10-3 构建一个简单的、单服务台的排队模型,实体到达时间间隔服从指数分布 EXPO (0.25) ,单位为分钟。使用 ReadWrite 模块,在仿真运行开始时输入并获取服务台的平均处 理时间(默认值为 0.2 分钟) ,建立均匀分布[a,b],其中 a 比输入的平均时间小 10%,b 比输 入的平均时间大 10%。仿真运行直到有 300 个实体离开模型时终止。 10-4 创建练习 10-3 所描述的模型,用 VBA 窗体代替 ReadWrite 模块,在仿真运行开 始的时候显示该窗体。 10-5 在练习 10-4 的单服务台模型中,添加仿真逻辑,当服务队列中的实体超过某一特 定值(阈值)时播放一段声音或者显示一个消息。建模者可以在仿真开始显示的窗体中输入 该阈值。 10-6 在仿真结束时弹出一个 VBA 窗体,显示模型 10-1 中产品队列的平均长度和最大 长度。如果读者机器上安装有绘图程序(如 Excel) ,则绘制一幅平均值的直方图。 10-7 建立一个模型,向文件里写入 1000 条记录,每个记录都包含记录号和十个介于 0

到 100000 的随机数。在菜单 Run>Setup>Reports 中,选择 SIMAN Summary Report 作为默 认输出,选择 Disable Generation of report database 禁用正常的模型输出,启用 Run>Run Control>Batch Run(No Animation)加速仿真运行。分别使用文本文件、二进制文件、Excel 文件、Access 文件、XML 文件,以及不使用任何文件(只是产生然后释放随机值) ,重复 实验, 比较每次实验的运行时间和文件大小。 如果读者的机器速度较快, 可以重复使用 10000 条和 100000 条记录作实验。

Similar Documents

Free Essay

Simulation

...INTRODUCTION: The purpose of this paper is to bring out the use of Simulation by Managers of various organizations. Under discussion will be:  Definition of simulation.  Model construction.  When and why it becomes handy to use simulation.  Steps used in simulation technique.  Random selection in simulation.  Advantages / benefits derived from use of simulation technique.  Disadvantages /Challenges associated with simulation technique.  Role of computer in simulation.  Conclusion / comments. Definition of simulation: Simulation can be defined as a quantitative technique which describes a process by developing a model of that process and then conduct a series of organized trial and error experiments to predict the behavior of the process through time often with the aid of a computer. It is a method that is used to solve a problem in many areas of management, for example inventory management, queuing problems, profit analysis and project management among others. Model construction: A successful simulation model has to be carefully designed in order to achieve the intended predictive purpose. Therefore important factors have to be considered such as; i. It must be objective oriented. It must be constructed for a purpose and be able to achieve that purpose. ii. Critical variables and relationships. These must be identified and incorporated in model. However it is not essential or indeed desirable to include all variables in the model. iii. Simplicity...

Words: 1498 - Pages: 6

Free Essay

Simulation Modeling

...Brooklyn Warren Chapter 10 Simulation Modeling What is Simulation? * To try to duplicate the features, appearance, and characteristics of a real system. * Imitate a real-world situation mathematically. * Study its properties and operating characteristics. * Draw conclusions and make action decisions based on the results. Processes of Simulation: 1. Define Problem 2. Introduce Important Variables 3. Construct Simulation Model 4. Specify Values of Variables to Be Tested 5. Conduct the Simulation 6. Examine the Results 7. Select Best Course of Action Advantages of Simulation: * Straightforward and flexible. * Can handle large and complex systems. * Allows "what-if" questions. * Does not interfere with real-world systems. * Study interactions among variable. * "Time comparison" is possible. * Handles complications that other methods can't. Disadvantages of Simulation: * Can be expensive and time consuming. * Does not generate optimal solutions. * Managers must generate all conditions and constraints. * Each model is unique. Monte Carlo Simulation: Can be used with variables that are probabilistic. Steps: * Establish the probability distribution for each random variable. * Use random numbers to generate random values. * Repeat for some number of replications. Probability Distributions: Historical data Goodness-of-fit tests for common distributions: ...

Words: 259 - Pages: 2

Free Essay

Simulation

...In “Are you living in a computer simulation?”, Nick Bostrom presents a probabilistic analysis of the possibility that we might all be living in a computer simulation. He concludes that it is not only possible, but rather probable that we are living in a computer simulation. This argument, originally published in 2001, shook up the field of philosophical ontology, and forced the philosophical community to rethink the way it conceptualizes “natural” laws and our own intuitions regarding our existence. Is it possible that all of our ideas about the world in which we live are false, and are simply the result of our own desire to believe that we are “real”? Even more troubling, if we are living in a computer simulation, is it possible that the simulation might be shut off at any moment? In this paper, I plan to do two things. First, I hope to consider what conclusions we might draw from Bostrom’s argument, and what implications this might have for how we affect our lives. Second, I plan to discuss a possible objection to Bostrom’s argument, and how this might affect our personal probability for the possibility that we are living in a computer simulation. Bostrom begins his argument by making a few assumptions necessary to the probabilistic claims he makes. The first is substrate-independence. This is simply the claim that if we were able to model the mind with enough detail, then we would be able to create artificial minds capable of thought in the same way that we are...

Words: 923 - Pages: 4

Premium Essay

Littlefield Simulation Report

...Initial operations strategy Prior to the commencement of the simulation, we examined the 50 days of historical data to glean as much information as we could about the operations. We performed some analysis in Excel and created a dashboard to illustrate various data. Specifically, we regressed the prior 50 days of jobs accepted to forecast demand over the next 2 - 3 months within a 95% confidence interval. The yellow and grey lines represent the maximum and minimum variability, respectively, based on two standard deviations (95%). Exhibit 1: Forecasted and actual demand by Day 50 and Day 270 Our two primary goals at the beginning of the simulation were as follows: 1) Eliminate bottlenecks and increase capacity in order to meet forecasted demand 2) Decrease lead time to 0.25 days in order to satisfy Contract 2 and maximize revenue In order to achieve these goals, we would need to know the capacity and throughput time of the entire system. We used the time required by each machine to process a lot to calculate capacity per station and then capacity of the entire production line (380 kits/day or 6 orders/day). In Exhibit 2 we can observe that the capacity of the production line is given by the station that produces the least number of units per day. Exhibit 2: Capacity of the production line The Decisions We decided to work with the maximum variability of demand because there was a penalty for late jobs and because there was no revenue for orders that took more than “x”...

Words: 765 - Pages: 4

Free Essay

Interpretation of Modeling and Simulation

...Interpretation of Modeling and Simulation Can there be a better fit for a company out there that uses Microsoft Excel to conduct modeling to simulate their business growth other than Microsoft itself? Microsoft has made billions of dollars selling their Microsoft Office Suites and their home computer operating systems around the world. They have become one of the largest and well known companies in the world. The way that I see it, is that Microsoft’s business model, in a nutshell, is to provide goods and services in the form of software and support to paying customers. One question that may be asked in this day an age is with the advances in cloud computing and Google’s “free” gadgets, will the traditional Microsoft’s business model come to an end? What will Microsoft’s business analysts do in order to change their business model? One can only imagine that it will need to be modeled and simulated first to avoid potentially expensive mistakes. I must start off by saying that before I started my Systems Modeling Theory online class through Strayer, I thought that it may just be one of the hardest classes to understand that I’ve ever taken throughout the course of my college career. I can say now after having completed the last nine weeks of class that I was correct. What’s hard, is not understanding the concepts of why businesses would use Excel models for their business growth but rather the actual use of Excel itself. With all of the bells and whistles...

Words: 1781 - Pages: 8

Free Essay

Simulation Write-Up

...Simulation 2 Write-Up During the simulation there were many different factors leading to varying results. One of the biggest causes for variation was in the performance of the worker. The worker had the impression that they were under a time constraint. The performance of the worker was usually kept constant until the last 5 or 10 drawings of cards, which is when the worker felt the pressure to draw cards faster. Another cause of variation was the shuffling of the worker. If the worker didn’t shuffle the cards thoroughly it would result in a varied outcome from normal results. This variation is considered a normal cause for variation because as the time constraint became more noticeable the workers would shuffle differently. This occurred more on the last few draws each round. One special cause occurred when the professor walked over to our workstation and had a conversation. This distracted the worker and simulated a special cause for variation. In order to improve the process, I would first designate a worker for shuffling the cards so we could eliminate time used passing the cards. This worker would then split the cards into two piles. Then I would assign two other workers the jobs of counting the cards after they have been separated. The workers would then both tell a single recorder the amounts to be recorded. This would be repeated with the designated shuffler. In order to assure that the second supplier is delivering the promised quality, we made a second...

Words: 436 - Pages: 2

Premium Essay

Simulation Based Medical Education

...Simulation is a technique for practice and learning that can be used in many nursing facilities to help trainees to learn different skills in training and communication. It is a technique to replace and amplify real experiences with guided ones that can help the trainee to develop essential skills while at work. Simulation-based learning can be the way to develop health professionals’ knowledge, skills, and attitudes, while protecting patients from high risks situations. Simulation-based medical education can be the basics which provides a valuable information in learning how to solve certain problems and issues in nursing. Simulation-based training techniques, tools, and strategies can be applied learning experiences, as well as be used as...

Words: 358 - Pages: 2

Premium Essay

Monte Carlo Simulation

...Monte Carlo Simulation The Monte Carlo Simulation encompasses “any technique of statistical sampling employed to approximate solutions to quantitative problems” (Monte Carlo Method, 2005). The Monte Carlo method simulates the full system many times, each randomly choosing a value for each variable from its probability distribution. The outcome is a probability distribution of the overall value of the system calculated through the iterations of the model. A standard approach to risk management of projects is outline by Project Management Institute (2004) that includes six processes: Risk Management Planning, Risk Identification, Risk Qualification, Risk Quantification, Risk Response Planning, and Risk Monitoring and Control. Monte Carlo is usually listed as a method to use during the Risk Quantification process to better quantify the risks to the project manager is able to justify a schedule reserve, budget reserve, or both to deal with issues that could adversely affect the project. Monte Carlo simulation, while not widely used in project management, does get some exposure through certain project management practices. This is primarily in the areas of cost and time management to quantify the risk level of a projects budget or planned completion date. In time management, Monte Carlo simulation may be applied to project schedules to quantify the confidence the project manager should have in the target competition date or total project duration. In cost management, the project...

Words: 976 - Pages: 4

Free Essay

The Uses of Simulation in the Military

...The Uses of Simulation in the Military Week 1, Research Paper Simulation has been a part of the military for almost as long as war has been around. However the types of simulations that we use today are a modern invention. Generals have been creating and testing strategies in simulation for a long time. Today we have the technology to create virtual representations of a battle zones stocked with geographical landscapes, both hostile and non-hostile NPCs (non-playable characters) and controllable entities acting as the various soldiers and vehicles. Simulation is a great and a necessary tool for training your soldiers and winning the war, the most important of these simulations are wargames, field exercises and flight training. One of the oldest types of simulation in the military are Wargames. A wargame generally is a type of game or simulation that is designed to expose a player to concepts and aspects of war (University of Virginia, 1999). Wargames would have started at the time of the first organized war (University of Virginia, 1999). These games were most likely picking an action then taking that action testing it and then tweaking the plan to make it better (University of Virginia, 1999). Generals used this setting for many years, allowing them to come up with better strategies, therefor winning more battles. In 7th century India there was a wargame called Chaturanga, Chaturanga in many aspects is much like the game chess which is often played today. In the game each...

Words: 1047 - Pages: 5

Premium Essay

Medical Training: Simulation-Based Learning

...Simulation-based learning is a training method that involves imitating the circumstances regarding a real-life job through the use of representations and models, (Saks, Haccoun, 2013. Pg.178-179). This training method presents trainees with the opportunity to learn in an environment that resembles the real-life job while protecting them from any risks. Furthermore, it helps trainees develop the necessary knowledge and skills to perform the job effectively, (Lateef, 2010). It causes them to master the task, improve their problem-solving skills, and enhance their teamwork abilities, (Lateef, 2010). Simulation training is commonly used in training for dangerous jobs, such as jobs in medicine or the military. Medical training programs often...

Words: 975 - Pages: 4

Free Essay

Order Book Simulations Using Monte Carlo Methods

...Modeling Order Book Fluctuation by Monte Carlo Technique CONTENTS Page no. 1) Certificate 2 2) Acknowledgement 3 3) Abstract 5 4) Introduction 6 5) Simulation code 8 ➢ Order Book 8 ➢ Diffusion 9 ➢ Price and Annihilation 11 ➢ One Trade return 14 ➢ Waiting time between consecutive trades 16 ➢ Conditional return 19 ➢ Hurst curve 20 6) Results and Discussion 22 7) Summary 28 8) Future Prospects 29 9) References ...

Words: 1053 - Pages: 5

Free Essay

Discrete Event Simulation of Sports Facilities at University of Cincinnati

...Simulation of Sports Facilities at University of Cincinnati Campus Recreation Center By: Nikhil Shaganti MID: M07428499 MS- Business Analytics Carl.H. Lindner College of Business, University of Cincinnati Page | 1 Table of Contents Acknowledgments………………………………………………………………….3 List of Figures……………………………………………………………...............4 Objectives of the study………………………………………………......................5 About UC Campus Recreation Center…………………………………….............. 5 Scope of Simulation……………………………………………………….............. 6 Data Collection  Fitting Distributions for Wait times…………………………………………8  Challenges Faced…………………………………………………………….9  Assumptions………………………………………………………………..10 Fitness Center Model…………………………………………………………….....9  Basic Model………………………………………………………………….9  Updated Model- More Realistic……………………………………………10 Swimming Pool Model……………………………………………………………13 Output Analysis…………………………………………………………………...14 Conclusion………………………………………………………………………...18 References………………………………………………………………………...19 Page | 2 Acknowledgements With sincere gratitude, I would like to express my special thank you to Professor Dr. W. David Kelton. This project would have never been completed without his direction, assistance, and encouragement. I would also like to thank my parents, for their endless support during each and every one of my life’s endeavors. Page | 3 List of Figures Figure 1. Triangular distribution observed in Input Analyzer for Fitness Center Wait times...…………………………………………...

Words: 2395 - Pages: 10

Free Essay

Simulations in Wireless Sensor and Ad Hoc Networks: Matching and Advancing Models, Metrics, and Solutions

...TOPICS IN AD HOC AND SENSOR NETWORKS Simulations in Wireless Sensor and Ad Hoc Networks: Matching and Advancing Models, Metrics, and Solutions Ivan Stojmenovic, University of Birmingham and University of Ottawa ABSTRACT The objective of this article is to give advice for carrying out a proper and effective simulation activity for protocol design. It challenges some of the existing criticisms of simulation practices that emphasized validation aspects. This article advocates the use of simple models, matching assumptions and metrics in the problem statement and simulation to provide a basic “proof of concept,” and comparison with truly competing solutions, which is possible only after a thorough and critical literature review. Then the complexity of the models can be increased (one parameter at a time), revising the algorithms themselves by adapting them to new assumptions, metrics, and the corresponding simulation environment. Selected independent variables should explain performance under a wide range of scenarios. unclear which protocol will perform well under a wide range of scenarios. It is our view that each article should be judged on its overall contribution, including the assumptions used, theory developed, new algorithms introduced, protocol details, simulation results, and relevance to an ultimate goal of staying on a path toward creating applications. We begin with a literature review of existing criticism for simulation practices, and then discuss what we believe...

Words: 4845 - Pages: 20

Free Essay

Using a Combined Method of Hierarchical Analysis and Monte Carlo Simulation in Order to Identify and Prioritize the Target Market Selection Criteria

...Applied mathematics in Engineering, Management and Technology 2 (2) 2014:466-475 www.amiemt-journal.com Using a combined method of hierarchical analysis and Monte Carlo simulation in order to identify and prioritize the target market selection criteria (Case study: Food distribution companies of Mashhad-Iran) Amir kariznoee Ph.D. student of Industrial Management,University of Mazandaran ,Iran (Corresponding Author's E-mail: Amir.kariznoee@yahoo.com) Monireh Bijandi Graduate of Accounting in Ferdowsi University of Mashhad,Iran Mahdi Ghayur Maddah Student of Public Management in Ferdowsi University of Mashhad,Iran Vajihe Mogharabi M.A. Student of Information Technology Management, Shahid beheshti University,Tehran,Iran Abstract The aim of this study is to identify and prioritize the key factors in selecting a target market in the food industry. In order to determine the components and subcomponents of this study, we have used previous researches in this area. In order to match these factors with the food industry situation and create a hierarchical structure, we have obtained the opinions of 323 experts about affecting factors on choosing a market in this industry with the use of questionnaire. Then, using a combination of hierarchal analysis process and Monte Carlo simulation and cooperation with 10 senior executives of distribution companies, the weight of each component and sub-component was determined. In general, four components and ten sub-components were...

Words: 3589 - Pages: 15

Premium Essay

Realty Tycoon Simulation Game

...REAL-TY-COON Alternative method of teaching is a very important tool to encourage students to learn in a fun and meaningful way. Simulation game is one of the ways to achieve that. A simulation game is a dramatic view of real life situations for the serious purpose of learning about real experiences in a controlled environment. Students of CEC from IIM Raipur created and conceptualized a simulation game, REAL-TY-COON. The main objective of the game is to replicate real life scenario of construction business. The game is based on the concept of demand and supply and how market prices of products are determined. The game consisted of 5 set of teams. 4 set of teams played the role of suppliers and 1 played the role of builders. The division of teams was done as follows: Team Type | Teams | No. of Players | Builders | 5 | 4 | Cement Suppliers | 3 | 2 | Sand Suppliers | 3 | 2 | Stone Suppliers | 3 | 2 | Steel Suppliers | 3 | 2 | The game has 5 rounds. In each round, builders have to build a specific building allocated to them. To build any of the buildings, they have to buy adequate amount of cement, stone, steel and sand from the suppliers. They will be provided with fixed initial amount of cash. Builders can approach bank to get additional cash at a fixed rate of 10% which will be applicable for that round only, carrying forward loan for each extra round will attract an additional 5% rate per round. In case the builders are not able to get a deal from the...

Words: 654 - Pages: 3