敏感性分析实验
敏感性分析实验帮助您探索模拟结果对模型参数变化的敏感程度。实验通过多次运行模型,改变其中一个参数,并展示模拟输出如何依赖于此参数。对于单一值类型的输出,会显示“输出与参数”的图表。如果模拟输出是一个数据集(例如,某个过程随时间的动态),则会在一个图表上显示一系列曲线以供比较。
AnyLogic 支持多核处理器。当您启动敏感性分析实验时,AnyLogic 会自动检测可用的核心数量,并在不同处理器核心上并行运行多个迭代。从而显著提高性能,使实验比在单核处理器上执行快得多。
创建敏感性分析实验
要创建敏感性分析实验,请按照以下步骤操作:
- 在项目视图中,右键单击(macOS:Ctrl + 单击)模型项,并从弹出菜单中选择新建 > ![新建仿真实验向导图标]。
- 在实验类型列表中选择 ![参数变化实验图标] 的敏感性分析选项。
- 在名称编辑框中输入实验名称。
- 从顶级代理下拉列表中选择实验的顶级代理。
- 如果您想从另一个实验中应用模型时间设置,请保留选中从…复制模型时间设置复选框,并在右侧的下拉列表中选择实验。
- 单击下一步进入向导的下一页。
- 在这里,您选择要变化的参数以及变化的方式。您想变化的参数在变化参数下拉列表中选择。在此控件下方,您选择这个参数将如何变化。
- 如果您设置参数为自由形式变化,您应该在表达式字段中指定任何评估参数值的随机表达式。它可以是固定值,或者是评估实际参数值的表达式。在表达式字段中使用索引来引用迭代次数(0,1,2,…)。
- 否则,如果您设置参数在范围内变化,您应该为变化的参数定义最小值、最大值和步长值。
- 单击下一步进入向导的图表页面。在这里,您指定将显示模拟输出的图表。每个图表在表格的单独一行中定义:您应该为每个图表定义标题、类型和表达式。图表的可用类型包括:数据集图表用于数据集,标量 XY 图表用于变化参数的标量值。您可以使用表达式。
- 单击完成。
属性
通用
名称 — 实验的名称。
由于 AnyLogic 为每个实验生成 Java 类,请遵循 Java 命名指南,并以大写字母开头。
忽略 — 如果选中,实验将从模型中排除。
顶级代理 — 使用下拉列表,选择实验的顶级代理类型。此类型的代理将在模型的代理层次结构中扮演根的角色。
最大可用内存 — 分配给模型的 Java 堆的最大大小。
创建默认 UI — 按钮为实验创建默认 UI。
不要按这个按钮,因为它会删除向导创建的实验 UI 并创建可能不符合您任务的实验的默认 UI。
参数
参数 — 在这里,您可以选择如何变化参数:在指定范围内,或自由地。
在范围内变化 — 如果选中,您应该在下面的表中为每个要变化的参数明确定义值的范围。
自由形式 — 如果选中,模型将按照您在下面的运行次数字段中指定的固定迭代次数运行,并且根据您在下面的表中定义的表达式计算参数值。
正是这个选项应该为敏感性分析实验选择。
运行次数 — [如果上面选择了参数:自由形式选项] 定义实验将使用不同的参数值运行模型的次数。
位于此处的表显示了顶级代理的所有参数。对于表中表达式列的每个参数,您可以指定一个(通常是随机的)表达式,根据此表达式,在实验的下一个“运行”期间计算此参数的值。使用表达式中的索引关键字可以引用当前模型运行次数。
如果上面选择了参数:在范围内变化选项,那么表将显示类型和值(最小值,最大值,步长)列,但这适用于另一种实验 - 参数变化。
模型时间
停止 — 定义模型是否在指定时间停止,在指定日期停止,或者它将永不停止。在前两种情况下,使用停止时间/停止日期控件指定停止时间。
开始时间 — 模拟时间范围的初始时间。
开始日期 — 模拟时间范围的初始日历日期。
停止时间 — 模拟时间范围的最终时间(模型在停止前运行的模型时间单位数)。
停止日期 — 模拟时间范围的最终日历日期。
附加实验停止条件 — 在这里,您可以定义任意数量的附加实验停止条件。当这些条件中的任何一个变为真时,实验将停止。条件可以包括数据集平均置信度、变量值等的检查。您可以在这里将实验的顶级代理作为根访问,因此,例如,如果要在实验的顶级代理的变量 plainVar 超过阈值时停止实验,可以在这里输入,比如说,root.plainVar>11。要使条件生效,请在表的相应行中选中复选框。
随机性
随机数生成器 — 在这里,您指定是否要为此模型随机初始化随机数生成器或使用某个固定种子。这对随机模型很有意义。随机模型需要伪随机数生成器的随机种子值。在这种情况下,模型运行无法重现,因为每次模型运行都使用不同的值初始化模型随机数生成器。指定固定种子值,您将使用相同的值初始化每次模型运行的模型随机数生成器,从而使模型运行可重现。此外,您可以在这里使用自己的 RNG 替换 AnyLogic 默认 RNG。
-
随机种子(唯一的模拟运行) — 如果选中,随机数生成器的种子值是随机的。在这种情况下,每次模型运行都使用相同的值初始化随机数生成器,模型运行是唯一的(不可重现的)。
-
固定种子(可重现的模拟运行) — 如果选中,随机数生成器的种子值是固定的(在种子值字段中指定)。在这种情况下,每次模型运行都使用相同的值初始化随机数生成器,模型运行是可重现的。
-
自定义生成器(Random 的子类) — 如果由于某种原因您对默认随机数生成器 Random 的质量不满意,您可以用自己的替换它。只需准备您的自定义 RNG(它应该是 Java 类 Random 的子类,例如 MyRandom),选择这个特定选项,并在右侧的字段中输入返回您的 RNG 实例的表达式,例如:new MyRandom() 或 new MyRandom(1234)。
您可以在自定义数字生成器中找到更多信息。
复制
使用复制 — 如果选中,引擎将为一次模拟运行多次复制。当您的模型包含随机性时,您需要这样做。在这种情况下,模拟运行的结果是唯一的,并且对于使用相同优化参数值执行的模拟运行获得的优化函数值很可能彼此不同。我们不能只执行一次模拟运行,接受其结果作为当前迭代结果,然后通过检查其他参数值进行优化。为了获得可靠的代表性数据,我们需要对单个参数值集执行多次运行(这里称为“复制”),并接受所有复制结果的平均值作为目标的值。
固定数量的复制 — 如果选中,每次模拟将运行固定数量的复制。
- 每次迭代的复制 — [如果设置了固定数量的复制] 将为每次模拟运行的固定数量的复制。
变化数量的复制(在达到最小复制次数后停止复制,当置信水平达到时) — 如果选中,每次模拟将运行变化数量的复制。当运行变化数量的复制时,您将指定要运行的最小和最大复制次数。引擎将始终为解决方案运行最小数量的复制。然后,引擎确定是否需要更多的复制。当出现以下情况之一时,引擎将停止评估解决方案:
- 真实目标值在迄今为止复制的平均值的给定百分比内。
- 当前复制目标值没有收敛。
- 已运行最大数量的复制。
对于此属性,有以下选项可用:
-
最小复制 — [如果设置了变化数量的复制] 引擎每次模拟将始终运行的最小复制次数。
-
最大复制 — [如果设置了变化数量的复制] 引擎每次模拟可以运行的最大复制次数。
-
置信水平 — [如果设置了变化数量的复制] 要评估的目标的置信水平。
-
误差百分比 — [如果设置了变化数量的复制] 确定置信水平的目标的百分比。
窗口
窗口属性定义了当用户启动实验时将显示的模型窗口的外观。
实验窗口的大小使用模型框架定义,并适用于模型的所有实验和代理类型。
标题 — 模型窗口的标题。
启用缩放和平移 — 如果选中,用户将被允许平移和缩放模型窗口。
启用开发人员面板 — 选中/清除复选框以在模型窗口中启用/禁用开发人员面板。
启动时显示开发人员面板 — [仅当选中了启用开发人员面板复选框时启用] 如果选中,每次运行实验时开发人员面板将默认显示在模型窗口中。
Java 动作
初始实验设置 — 实验设置时执行的代码。
每次实验运行前 — 每次模拟运行前执行的代码。
模拟运行前 — 模拟运行前执行的代码。此代码在模型设置时运行。此时,模型的顶级代理已经创建,但模型尚未启动。您可以在这里对顶级代理的元素执行一些操作,例如在这里分配实际的参数值。
模拟运行后 — 模拟运行后执行的代码。当仿真引擎完成模型执行(调用 Engine.finished() 函数)时,此代码将被执行。当您通过单击终止执行按钮停止模型时,此代码不会执行。
迭代后 — 迭代运行后执行的代码。
实验后 — 实验运行后执行的代码。
高级 Java
导入部分 — 实验类代码正确编译所需的导入语句。当生成 Java 代码时,这些语句将插入在 Java 类定义之前。
附加类代码 — 在这里定义任意成员变量、嵌套类、常量和方法。此代码将插入到实验类定义中。您可以在实验的任何位置访问这些类数据成员。
Java 机器参数 — 在这里指定您想要应用于启动模型的 Java 机器参数。您可以在 Java Sun Microsystems 网站上找到有关可能参数的详细信息:http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/java.html。
命令行参数 — 在这里,您可以指定要传递给您的模型的命令行参数。您可以使用任何代码字段中的 String[] getCommandLineArguments() 方法获取传递的参数值。唯一的例外是静态变量的值,因为这些在实验类本身之前就已初始化。
高级
允许并行评估 — 如果选中此选项,并且处理器具有多个核心,则 AnyLogic 将在不同的处理器核心上并行运行多个实验迭代。从而显著提高性能,使实验执行得更快。此功能是可控的,因为在某些罕见的情况下,并行评估可能会影响优化器策略,从而需要更多的迭代才能找到最优解。
如果您在这里启用并行评估,请不要使用静态变量、集合、表函数和自定义分布(确保它们的高级选项静态未选中)。
从快照加载顶级代理 — 如果选中,实验将从右侧控制中指定的快照文件加载模型状态。实验将从保存模型状态时的时间开始。
功能
您可以使用以下功能来控制实验、检索其执行状态的数据,并将其用作创建自定义实验 UI 的框架。
控制执行
功能 | 描述 |
---|---|
void run() | 从当前状态开始实验执行。 如果模型尚未存在,则该函数将重置实验,创建并启动模型。 |
void pause() | 暂停实验执行。 |
void step() | 执行实验执行的一个步骤。 如果模型尚未存在,则该函数将重置实验,创建并启动模型。 |
void stop() | 终止实验执行。 |
void close() | 此函数立即返回,并在单独的线程中执行以下操作: - 如果实验尚未停止,则停止实验, - 销毁模型, - 关闭实验窗口(仅当模型以应用模式启动时)。 |
Experiment.State getState() | 返回实验的当前状态:IDLE, PAUSED, RUNNING, FINISHED, ERROR, 或 PLEASE_WAIT。 |
double getRunTimeSeconds() | 以秒为单位返回实验执行的持续时间,不包括暂停时间。 |
int getRunCount() | 返回当前模拟运行的次数,即模型被销毁的次数。 |
double getProgress() | 返回实验的进度:介于 0 和 1 之间的数字,对应于实验已完成部分(完成迭代的总数的比例),或者如果无法计算进度,则返回 -1。 |
int getParallelEvaluatorsCount() | 返回此实验中使用的并行评估器的数量。 在允许并行执行的多核/多处理器系统上,此数字可能大于 1。 |
迭代
功能 | 描述 |
---|---|
int getCurrentIteration() | 返回当前迭代计数器的值。 |
int getMaximumIterations() | 返回总迭代次数。 |
int getNumberOfCompletedIterations() | 返回已完成迭代的次数。 |
复制
在调用敏感性分析实验功能之前,您可能需要确保使用了复制(调用 isUseReplications() 函数)。
功能 | 描述 |
---|---|
boolean isUseReplications() | 如果实验使用复制,则返回 true;否则返回 false。 |
int getCurrentReplication() | 返回当前迭代已运行的复制次数。 |
访问模型
功能 | 描述 |
---|---|
Engine getEngine() | 返回执行模型的引擎。要访问模型的顶级代理(通常是 Main),请调用 getEngine().getRoot();。 |
IExperimentHost getExperimentHost() | 返回模型的实验主机对象,或者如果主机对象不存在,则返回没有功能的虚拟对象。 |
从快照恢复模型状态
功能 | 描述 |
---|---|
void setLoadRootFromSnapshot(String snapshotFileName) | 告诉仿真实验从 AnyLogic 快照文件加载顶级代理。这个函数只在 AnyLogic Professional 中可用。 snapshotFileName — AnyLogic 快照文件的名称,例如:“C:\My Model.als” |
boolean isLoadRootFromSnapshot() | 如果实验配置为从快照文件加载的状态开始模拟,则返回 true;否则返回 false。 |
String getSnapshotFileName() | 返回此实验配置为开始模拟的快照文件的名称。 |
错误处理
功能 | 描述 |
---|---|
RuntimeException error(Throwable cause, String errorText) | 通过抛出一个 RuntimeException 来在模型运行期间发出错误信号,错误文本由代理的全名加上 errorText 组成。 这个函数从不返回,它本身抛出运行时异常。返回类型定义为当您想使用以下调用形式时: throw error(“my message”); cause — 原因(将保存以获取更详细的信息),可以为 null。 errorText — 将显示的错误文本。 |
RuntimeException errorInModel(Throwable cause, String errorText) | 通过抛出一个 ModelException 来在模型运行期间发出模型逻辑错误信号,指定的错误文本由代理的全名加上 errorText 组成。 这个函数从不返回,它本身抛出运行时异常。返回类型定义为当您想使用以下调用形式时: throw errorInModel(“my message”); 此函数与 error() 在显示错误信息的方式上有所不同:模型逻辑错误比其他错误“更柔和”,它们通常发生在模型中,并提醒建模者模型可能需要一些参数调整。 例如:“代理无法离开流程图块,因为后续块正忙”,“托盘架容量不足”等。 cause — 原因(将保存以获取更详细的信息),可以为 null。 errorText — 将显示的错误文本。 |
void onError(Throwable error) | 此函数可以被重写以执行模型执行期间发生的错误的自定义处理(即,在事件的动作代码、动态事件、转换、状态的进入/退出代码、公式等中发生的错误)。 默认情况下,此函数什么都不做,因为它的定义为空。要重写它,您可以向实验中添加一个函数,将其命名为 onError 并为其定义一个 java.lang.Throwable 的单个参数。 error — 在事件执行期间发生的错误。 |
void onError(Throwable error, Agent root) | 与 onError(Throwable error) 函数类似,除了它提供了一个额外的参数来访问模型的顶级(根)代理。 error — 在事件执行期间发生的错误。 root — 模型的顶级(根)代理。对于在并行执行的多个运行的实验很有用。在某些情况下可能为 null(例如,在顶级代理创建期间发生错误)。 |
命令行参数
功能 | 描述 |
---|---|
String[] getCommandLineArguments() | 返回传递给此实验的命令行参数数组。从不返回 null:如果没有传递参数,则返回空数组。 不能在静态变量的值内调用:这些在实验类本身之前就已初始化。 |