- 属性
- 定义目标函数
- 优化参数
- 优化参数类型
- 定义优化参数
- 优化实验函数
- 约束和要求
- 约束
- 要求
- 可行和不可行的解决方案
- 指定优化停止条件
- 默认优化用户界面
- 运行优化实验
- 优化随机模型
- 提高优化性能
推荐资料:
链接: youtube Anylogic
优化是寻找最佳条件组合以获得最佳解决方案的过程。优化可以帮助您找到例如服务器的最佳性能或处理账单的最佳方法。
如果您需要运行模拟并观察在特定条件下的系统行为,并通过决定系统参数和结构来提高系统性能,请在AnyLogic中创建优化实验。
优化实验支持两种优化引擎:
- 遗传 是基于进化算法的优化引擎,旨在保留可能解决方案的多样性,避免陷入次优解。与每一步生成单个解决方案不同,该引擎每一步生成一系列解决方案,为下一步保留最佳解决方案,依此类推,直到找到最佳可能解决方案。
- OptQuest优化引擎是OptTek Systems, Inc.的专有工具,提供了一种通用的“黑盒”全局优化算法。
对于这两种引擎,AnyLogic都提供了一个方便的图形用户界面来设置和控制优化,并允许将带有优化实验的模型导出为独立应用程序。
优化过程包括使用不同参数对模型进行重复模拟。使用复杂的算法,优化引擎在模拟与模拟之间变化可控参数,以找到解决一个问题的最佳参数。
您可以使用Java代码控制优化实验。
优化您的模型
- 创建一个新的优化实验。
- 选择优化引擎。
- 定义优化参数(将被变化的参数)。
- 创建实验用户界面。
- 指定要最小化或最大化的函数(目标函数)。
- 定义要满足的约束和要求(可选)。
- 指定模拟停止条件。
- 指定优化停止条件。
- 运行优化。
系统动态教程的最后一步解释了如何一步步创建和运行优化。
创建优化实验
- 在项目视图中,右键单击(macOS:Ctrl + 单击)模型项目并从弹出菜单中选择新建 > 实验。将显示新建实验对话框。
- 从实验类型列表中选择优化选项。
- 在名称编辑框中输入实验名称。
- 从顶层代理下拉列表中选择实验的顶层代理。
- 如果您想从另一个实验中应用模型时间设置,请保留选中从复制模型时间设置复选框,并在右侧的下拉列表中选择实验。
- 单击完成。
提高优化实验性能
请查看以下一些提示。
属性
通用
- 名称 —— 实验的名称。
- 忽略 —— 如果选中,该实验将从模型中排除。
- 顶层代理 —— 使用下拉列表选择实验的顶层代理类型。此类型的代理将扮演模型中代理层次结构树的根的角色。
- 优化引擎 —— 实验使用的优化引擎:OptQuest 或 遗传。
- 目标 —— 您想要最小化或最大化的目标函数。在这里可以访问顶层代理作为根。
- 迭代次数 —— 如果选中,优化将在超过右侧字段中指定的最大模拟次数时停止。
- 自动停止 —— 如果选中,如果目标函数的值停止显著改善(此选项命名为优化自动停止),优化将停止。
- 最大可用内存 —— 为模型分配的Java堆的最大大小。
- 创建默认UI —— 此按钮为实验创建默认UI。
参数
- 参数 —— 定义优化参数集(也称为决策变量)。表格列出了顶层代理的所有参数。
- 要使参数成为决策变量,请点击类型字段并选择除固定之外的优化参数类型。
- 根据参数类型,可能值的列表可能会有所不同:对于int是离散,对于double是连续和离散等。
模型时间
- 停止 —— 定义模型是否会在指定时间停止,在指定日期停止,或者永不停止。在前两种情况下,使用停止时间/停止日期控件指定停止时间。
附加优化停止条件 —— 在此处您可以定义任意数量的附加优化停止条件。当这些条件之一评估为真时,优化将停止。条件可以包括对数据集平均置信度、变量值等的检查。实验的顶层代理在这里可以作为根访问,因此例如,如果您想在某变量超过阈值时停止优化,请输入root.var > 11。
约束
定义约束 —— 对优化参数施加的额外限制。
模拟参数上的约束(在模拟运行前测试) —— 定义优化约束的表格。约束是对优化参数定义的条件。它为优化参数定义了一个范围。每次优化引擎为优化参数生成一组新值时,它都会创建满足此约束的可行解;因此搜索空间被缩小,优化执行得更快。
一个约束是一个描述优化参数之间关系的良构算术表达式。它总是通过指定下限或上限来定义限制,例如,parameter1 >= 10。约束在模型运行和顶层代理实例化之前计算,因此它们不能涉及顶层代理的任何内容。
每个约束在表格的单独行中定义,并且可以通过取消选择第一列中的相应复选框来禁用。
要求
定义要求 —— 对优化引擎找到的解施加的额外限制。
要求(在模拟运行后测试以确定解决方案是否可行) —— 定义优化要求的表格。要求是对优化引擎找到的解施加的额外限制。要求在每次模拟结束时检查,如果没有满足,则当前参数值将被拒绝。
一个要求也可以是对响应的限制,要求其值落在指定范围内。它可以包含任何变量、参数、函数等,在表达式字段中作为根访问实验的顶层代理。
每个要求在表格的单独行中定义,并且可以通过取消选择第一列中的相应复选框来禁用。
随机性
随机数生成器 —— 在此处指定,是否要为该模型随机初始化随机数生成器或使用某个固定种子。这对随机模型有意义。随机模型需要伪随机数生成器的随机种子值。在这种情况下,模型运行无法重现,因为每次模型运行都使用不同的值初始化模型随机数生成器。指定固定种子值,您可以使用相同的值初始化每次模型运行的模型随机数生成器,从而使模型运行可重现。此外,您可以用自己的RNG替换AnyLogic默认的RNG。
使用复制 —— 如果选中,优化引擎将为每次模拟运行多个复制。当您的模型包含随机性时,需要这样做。在这种情况下,模拟运行的结果通常是独特的,并且使用相同的优化参数值执行的模拟运行获得的优化函数值很可能彼此不同。我们不能只执行一次模拟运行,接受其结果作为当前迭代结果,并继续通过检查其他参数值进行优化。为了获得可靠的代表性数据,我们需要对单个参数值集执行多个运行(这里称为“复制”),并接受所有复制结果的平均值作为目标值。
固定数量的复制 —— 如果选中,每次模拟将运行固定数量的复制。
变化数量的复制(在达到最小复制次数时停止复制,当达到置信水平时) —— 如果选中,每次模拟将运行变化数量的复制。当运行变化数量的复制时,您将指定要运行的最小和最大复制次数。OptQuest引擎将始终为解决方案运行最小数量的复制。然后OptQuest确定是否需要更多的复制。当发生以下任一情况时,OptQuest引擎将停止评估解决方案:
- 真实目标值在迄今为止复制的平均值的给定百分比内。
- 当前复制目标值没有收敛。
- 已运行最大数量的复制。
遗传优化引擎不支持变化数量的复制。
对于此属性,提供以下选项:
-
最小复制次数 —— 如果设置了变化数量的复制,则OptQuest引擎每次模拟将始终运行的最小复制次数。
-
最大复制次数 —— 如果设置了变化数量的复制,则OptQuest引擎每次模拟可以运行的最大复制次数。
-
置信水平 —— 如果设置了变化数量的复制,则评估目标的置信水平。置信水平显示随机结果在置信区间内的可能性。您可以将其视为样本的准确性。通常使用95%,但在不需要高精度的情况下,可以使用90%甚至85%。反之,样本越大,可以建立的准确性越高。置信区间应被视为不准确性的度量。它定义了分布曲线在选定点两侧的范围内,结果可能下降的范围。
-
误差百分比 —— 如果设置了变化数量的复制,则从0到1的值,定义置信区间的大小,该大小应满足我们作为停止为当前迭代执行额外复制的条件。区间计算为(current_mean_value - current_mean_value * error percent, current mean value + current mean value * error percent)。
窗口
窗口属性定义了用户启动实验时将显示的模型窗口
Kimi: 的外观。
实验窗口的大小是使用模型框架定义的,并适用于模型的所有实验和代理类型。
标题 —— 模型窗口的标题。
启用缩放和平移 —— 如果选中,用户将被允许平移和缩放模型窗口。
启用开发人员面板 —— 选中/清除复选框以在模型窗口中启用/禁用开发人员面板。
启动时显示开发人员面板 —— [仅当选中了启用开发人员面板复选框时启用] 如果选中,每次运行实验时,默认情况下将在模型窗口中显示开发人员面板。
Java动作
初始实验设置 —— 在实验设置时执行的代码。
每次实验运行前 —— 在每次模拟运行前执行的代码。
模拟运行前 —— 在模拟运行前执行的代码。此代码在模型设置时运行。此时顶层代理已经创建,但模型尚未启动。您可以在这里对顶层代理的元素执行一些操作,例如在这里分配实际参数值。
模拟运行后 —— 在模拟运行后执行的代码。当模拟引擎完成模型执行(调用Engine.finished()函数)时执行此代码。当您点击终止执行按钮停止模型时,此代码不会执行。
迭代后 —— 在迭代运行后执行的代码。
实验后 —— 在实验运行后执行的代码。
高级Java
导入部分 —— 实验类代码正确编译所需的导入语句。当生成Java代码时,这些语句将插入在Java类定义之前。
附加类代码 —— 在此处定义任意成员变量、嵌套类、常量和方法。此代码将插入到实验类定义中。您可以在本实验中的任何位置访问这些类数据成员。
Java机器参数 —— 在此处指定您要在启动模型时应用的Java机器参数。您可以在Java Sun Microsystems网站上找到有关可能参数的详细信息:http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/java.html。
命令行参数 —— 在此处可以指定您要传递给您的模型的命令行参数。您可以使用任何代码字段的getCommandLineArguments()方法获取传递的参数值。唯一的例外是静态变量的值,因为这些在实验类本身之前就初始化了。
高级
允许并行评估 —— 如果选中此选项,并且处理器具有多个核心,AnyLogic将在不同处理器核心上并行运行多个实验迭代。从而成倍增加性能,显著加快实验速度。此功能是可控的,因为在某些罕见情况下,平行评估可能会影响优化器策略,以至于需要更多迭代才能找到最优解。
如果您在这里启用并行评估,请不要使用静态变量、集合、表函数和自定义分布(确保它们的高级选项静态未选中)。
从快照加载顶层代理 —— 如果选中,实验将从控制右侧指定的快照文件中加载模型状态。实验将从保存模型状态的时间开始。
定义目标函数
优化过程的目标是找到导致目标函数最大值或最小值的参数值。
目标函数是一个数学表达式,描述优化参数之间的关系或使用优化参数作为输入的操作(如模拟)的结果。优化目标是目标函数加上优化标准。后者决定了优化的目标是最小化还是最大化目标函数的值。
定义目标函数
- 在项目视图中,单击优化实验。
- 在属性视图中的目标编辑框中指定目标函数。您可以输入任何Java表达式作为目标函数。由于表达式被认为在顶层代理的上下文中,因此它可以访问顶层代理的变量和参数。在这里顶层代理可以作为root访问。如果您的算法相当复杂,可以在顶层代理(例如Main)中定义一个函数,并将函数调用放在目标编辑框中,如下所示:root.totalCost()。
- 定义优化标准。选择最小化/ 最大化选项来最小化/最大化您的目标函数。
优化引擎在每次模拟结束时获取目标函数的样本。引擎分析样本(如果是遗传优化引擎,则为样本批次),根据其优化算法修改优化参数,并启动新的模拟。
因此,优化是一个迭代过程,其中:
- 优化引擎计算参数的可能解决方案
- 使用建议的解决方案评估目标函数和约束
- 优化引擎分析结果,并计算新的可能解决方案集
优化参数
优化参数(或按优化术语称为决策变量)是模型中要优化的参数。例如,在医院模型中,上午班次雇用的护士人数可能是优化参数。优化引擎搜索优化参数的可能值以找到最优参数。可以有多个优化参数。
只有优化实验的顶层代理的参数才能成为优化参数,因此您必须在此代理中至少有一个参数。如果您需要优化嵌套代理的参数,请使用参数传播。
搜索区域的维度取决于优化参数的数量。每个新参数都扩展了搜索区域,从而减慢了优化速度。如果您有N个优化参数,它们的范围形成了N维正方形搜索区域。显然,该区域必须足够宽以包含最优点。然而,范围越宽,找到搜索区域内最优解所需的时间就越长。另一方面,如果使用OptQuest优化引擎,接近最优值的参数建议值可以缩短找到最优解所需的时间。
优化参数类型
在优化过程中,参数的值会根据其类型在指定的上下界区间内变化。有以下类型的优化参数:
- 布尔参数
- 连续参数
- 离散参数
布尔参数可以有真或假作为其值。
连续参数可以从区间中取任何值。参数精度决定了连续参数可以变化的最小值。
离散参数由一组具有本质方向的有限决策表示:参数像数值参数一样影响目标,但只能从指定的集合中取值。它从下限开始,以步长递增到上限。
有时范围和步长由问题明确定义,但通常您需要选择它们。如果您为参数指定了步长,那么只有离散点将参与优化,因此无法比步长定义的更精确地确定最优参数值。因此,如果您不确定步长应该是什么,选择连续而不是离散参数类型。
定义优化参数
优化参数在优化实验属性的参数部分中定义。表格已经列出了顶层代理的所有参数。默认情况下,它们都是固定的,即优化过程中不会变化。
要使参数成为决策变量:
-
在项目视图中选择优化实验。
-
在属性视图的参数部分中,转到包含要使成为决策变量的参数的参数表的行。
-
单击类型字段并选择优化参数的类型。根据参数类型,可能值的列表可能会有所不同。
如果保留固定值,则参数不会被考虑为决策变量,优化引擎将在整个实验的迭代中使用其默认值。
-
对于布尔参数,选择布尔使其成为优化参数。优化引擎将取参数值为真或假。
-
对于int参数,选择离散使其成为优化参数。参数将只取指定值范围内的有限集合中的值。
例如:最小值:0,最大值:4,步长:2。可能的值:0,2,4。
-
对于double或单位参数(例如时间,速率等),选择以下选项之一:
-
连续 —— 最受欢迎的选项。参数可以从指定范围内取任何值。
-
离散 —— 参数将只取指定值范围内的有限集合中的值。
例如:最小值:0,最大值:1,步长:0.5。可能的值:0,0.5,1。
-
-
-
为参数指定范围。在最小值字段中输入参数的下限,在最大值字段中输入参数的上限。
-
对于离散参数,在步长字段中指定参数步长。
-
如果使用OptQuest优化引擎,在建议字段中为参数建议初始值。最初,值设置为参数的默认值,但您可以在这里输入任何其他值。
遗传优化引擎不支持建议值。
优化实验函数
您可以使用以下函数来控制优化实验,获取其执行状态的数据,并将其用作创建自定义实验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。 |
目标
函数 | 描述 |
---|---|
double getCurrentObjectiveValue() | 返回当前解决方案的目标函数值。 |
double getBestObjectiveValue() | 返回当前找到的最优解决方案的目标函数值。解决方案可能是不可行的。要检查解决方案的可行性,请调用isBestSolutionFeasible()函数。 |
double getSelectedNthBestObjectiveValue() | 返回由selectNthBestSolution(int)函数识别的第N个最佳解决方案的目标值。遗传优化引擎不支持此函数。 |
解决方案
函数 | 描述 |
---|---|
boolean isBestSolutionFeasible() | 如果最优解决方案满足所有约束和要求,则返回true;否则返回false。 |
boolean isCurrentSolutionBest() | 如果解决方案目前是最优的,则返回true;否则返回false。 |
boolean isCurrentSolutionFeasible() | 如果当前解决方案满足所有约束和要求,则返回true;否则返回false。 |
boolean isSelectedNthBestSolutionFeasible() | 如果第N个最佳解决方案满足所有约束和要求,则返回true;否则返回false。遗传优化引擎不支持此函数。 |
void selectNthBestSolution (int bestSolutionIndex) | 此函数定位第N个最佳解决方案,并设置数据以供后续函数调用检索特定信息(例如,用于getSelectedNthBestObjectiveValue()和getSelectedNthBestParamValue(IVariable)函数)。bestSolutionIndex —— 最优解决方案的索引(传递1将定位最优解决方案,2 —— 第二优等)。遗传优化引擎不支持此函数。 |
优化参数
函数 | 描述 |
---|---|
double getCurrentParamValue(IVariable optimizationParameterVariable) | 返回给定优化参数变量的当前解决方案的值。 |
double getBestParamValue(IVariable optimizationParameterVariable) | 返回给定优化参数变量的当前找到的最优解决方案的值。解决方案可能是不可行的。要检查解决方案的可行性,请调用isBestSolutionFeasible()函数。 |
double getSelectedNthBestParamValue(IVariable optimizationParameterVariable) | 返回由调用selectNthBestSolution(int)函数识别的第N个最佳解决方案的变量值。遗传优化引擎不支持此函数。 |
迭代
函数 | 描述 |
---|---|
int getCurrentIteration() | 返回当前迭代计数器的值。 |
int getBestIteration() | 返回得到当前找到的最优解决方案的迭代次数。解决方案可能是不可行的。要检查解决方案的可行性,请调用isBestSolutionFeasible()函数。 |
int getMaximumIterations() | 返回总迭代次数。 |
int getNumberOfCompletedIterations() | 返回已完成迭代的次数。 |
int getSelectedNthBestIteration() | 返回由selectNthBestSolution(int)函数识别的第N个最佳解决方案的迭代次数。遗传优化引擎不支持此函数。 |
复制
在调用优化实验函数之前,您可能需要确保使用了复制(调用isUseReplications()函数)。
函数 | 描述 |
---|---|
boolean isUseReplications() | 如果实验使用复制,则返回true;否则返回false。 |
int getCurrentReplication() | 返回迄今为止针对当前评估的解决方案运行的复制次数。 |
int getBestReplicationsNumber() | 返回获得最优解决方案的复制次数。解决方案可能是不可行的。要检查解决方案的可行性,请调用isBestSolutionFeasible()函数。 |
int getSelectedNthBestReplicationsNumber() | 返回由selectNthBestSolution(int)函数识别的第N个最佳解决方案的复制次数。遗传优化引擎不支持此函数。 |
访问模型
函数 | 描述 |
---|---|
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来发出模型运行期间的模型逻辑错误,指定的错误文本由代理的全名加上。此函数永不返回,它本身抛出一个运行时异常。返回类型定义是为了方便您使用以下调用形式: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:如果没有传递参数,则返回空数组。不能在静态变量的值内调用:这些在实验类本身之前初始化。 |
约束和要求
AnyLogic支持约束和要求 —— 对优化参数和优化引擎找到的解决方案施加的额外限制。
约束
约束是定义在优化参数上的更复杂条件,每次优化引擎生成一组新值时都会进行测试。它用于那些决策变量的值需要比参数中的范围更精确地描述的情况。
通常,约束是一个良构的算术表达式,描述优化参数之间的关系。
parameterA + parameterB + 2 * parameterC = 10
parameterC - parameterA * parameterB >= 300
与遗传优化引擎不同,OptQuest允许在某些条件被违反时执行模拟运行:见下面线性和非线性约束的解释。
- 一个线性约束定义了变量之间的线性关系。OptQuest能够在不运行模型的情况下测试一个值是否违反线性约束。
- 一个非线性约束适用于表达式本身是非线性的情况,或者包含模拟的输出(即,变量值由用户控制)。OptQuest需要模型运行来测试非线性约束。
定义约束
- 通过在项目视图中单击来选择优化实验。
- 在属性视图的约束部分中,单击表格**模拟参数上的约束(在模拟运行前测试)**右侧的
按钮。
- 在行的表达式、类型和界限单元格中指定约束。
- 选择启用列中的复选框。否则,约束将从优化过程中排除,并且不会影响其结果。
要求
要求
Kimi: 是对优化引擎找到的解决方案施加的额外限制。要求在每次模拟结束时检查,如果没有满足,使用的参数将被拒绝。否则,参数将被接受。
这意味着,如果所有变量在模拟结束时都满足它们的约束,相应的参数值集被认为是可行的,模拟的结果被优化引擎接受。否则,参数值被认为是不可行的,结果将被拒绝。
一个要求也可以是对响应的限制,要求其值落在指定范围内。约束可能包含代理的任何变量、模型时间符号t、任何算术运算和方法调用,例如sin()、cos()、sqrt()等,或者调用您自己的方法。
0 <= 2 * root.variable - root.statistics.max() <= 500
sqrt(variableC) >= 49
如果模型运行在模拟期间被复制,则要求针对所有复制的表达式的平均值进行测试。
定义要求
- 通过在项目视图中单击来选择优化实验。
- 在属性视图的要求部分中,单击表格**要求(在模拟运行后测试以确定解决方案是否可行)**右侧的按钮。
- 在行的表达式、类型和界限单元格中指定要求。在表达式字段中,顶层代理可用为root。
- 选择启用列中的复选框。否则,要求将从优化过程中排除,并且不会影响其结果。
可行和不可行的解决方案
可行解决方案是满足所有约束和要求的解决方案。优化引擎将找到可行解决方案作为其最高优先级。
特定解决方案可能是不可行的,这并不意味着问题本身是不可行的。然而,不可行的问题确实存在。以下是一个例子:
parameterA + parameterB <= 4
parameterA + parameterB >= 5
显然,没有任何组合可以同时满足这两个约束。
如果模型是约束可行的,优化引擎将始终找到可行解决方案,并寻找最优解决方案(即满足所有约束的最佳解决方案)。
如果优化引擎无法找到任何可行解决方案,您应该检查约束的可行性并修复约束所建模的关系的不一致性。
指定优化停止条件
要启用优化,您必须确保每次模拟都结束。默认情况下,模拟永远不会结束;因此优化引擎没有目标函数的样本。为确保每次模拟都结束,您必须指定模拟停止条件。最常见的简单模拟停止条件是在指定的模型时间停止。
通常,模拟停止条件应该这样指定:当模拟停止时,目标函数的值是重要的。模型应该是稳定的,瞬态过程应该完成,统计数据应该是有代表性的。
模拟可能涉及多个复制。目标函数的样本是模拟/迭代的结果,而不是复制。如果在模拟期间模型运行被复制,则停止条件针对所有复制的表达式的平均值进行测试。
优化可以在两种情况下停止:超过最大模拟次数或目标函数的值停止显著改善。后者也称为自动停止。您可以使用这些条件中的任何一个来停止优化。如果指定了多个条件,优化将在满足第一个条件时停止。
在优化实验的通用属性页面上设置这些优化过程的设置。
您还可以在优化实验属性的模型时间部分的相应属性中指定其他停止条件。当这些条件之一被评估为真时,优化将停止。
在指定的迭代次数后停止优化
- 在项目视图中,单击以选择优化实验。
- 转到属性视图。
- 在迭代次数编辑框中指定迭代次数。当超过此数量时,优化将停止。
使用自动停止选项时要小心。在优化卡住的情况下(即,当目标函数变化太慢时),优化可能在真正最优解找到之前就停止了。如果遇到这个问题,建议其他参数值,或者不要使用自动停止。
切换优化自动停止
- 在项目视图中,单击以选择优化实验。
- 转到属性视图。
- 选择自动停止复选框。
默认优化UI
就像模拟实验一样,优化实验有自己的展示,它在图形编辑器图表上绘制。默认情况下,图表是空的。然而,AnyLogic提供了为实验创建一些默认UI的功能。我们建议您在完全定义了参数表中的优化参数集之后,从创建默认UI开始,然后根据需要进行调整。
创建实验的UI
- 在项目视图中,选择优化实验。
- 转到属性视图。
- 单击创建默认UI按钮。这将为优化实验创建默认UI,如下所示。
为优化实验创建的默认UI
默认UI由多个控件组成,显示有关优化当前状态的所有必要信息。
左侧的表格显示了有关优化过程的所有必要信息。当前列中的值向用户显示当前迭代次数,使用的参数值以及到目前为止找到的相应目标。最佳列中的值形成了到目前为止找到的最佳解决方案。优化完成后,此解决方案被认为是最优的。目标函数的最佳值对应于此最优解决方案。您可以使用下方的复制按钮将其复制到剪贴板。
右侧的图表直观地展示了优化过程。X轴代表模拟次数,Y轴代表每次模拟找到的当前目标、最佳可行目标和最佳不可行目标。
通过单击模型窗口控制面板上的运行按钮来运行优化实验。
运行优化实验
设置优化后,您就准备好运行它了。这包括以下步骤:
- 启动优化
- 观察状态
- 确定最佳解决方案
- (可选)将最佳解决方案复制到模拟实验中,以使用最优参数模拟此模型一段时间并观察其行为
运行优化实验
- 在项目视图中,右键单击(macOS:Ctrl + 单击)您的优化实验并从上下文菜单中选择
运行。
- 或者,选择模型 > 运行从主菜单,或单击运行工具栏按钮右侧的箭头,并从下拉列表中选择要运行的实验。
- 这将打开模型窗口,显示实验的UI。如果您为实验创建了默认UI,请通过单击模型窗口底部控制面板上的
运行按钮来启动优化。优化过程将开始。
完成寻找最优解后,您可能希望将其复制到模型的模拟实验中。然后,您将能够使用最优参数模拟此模型。
将找到的最佳参数复制到模拟实验
- 当您完成寻找最优解后,通过单击模型窗口中的复制按钮,将最佳解决方案的参数值复制到剪贴板。
- 通过打开此模拟实验的通用属性页面并单击底部的从剪贴板粘贴按钮,将最优参数值粘贴到模拟实验中。
优化随机模型
如果您的模型是随机的,单次模型运行的结果可能不具代表性;因此,您可能考虑每次模拟运行固定数量的复制,或者使用OptQuest,每次模拟运行变化数量的复制。
当运行OptQuest实验变化数量的复制时,您将指定要运行的最小和最大复制次数。引擎将始终为解决方案运行最小数量的复制。然后OptQuest能够确定是否需要更多的复制。当发生以下任一情况时,引擎停止评估解决方案:
- 真实目标值在迄今为止复制的平均值的给定百分比内。
- 当前复制目标值没有收敛。
- 已运行最大数量的复制。
优化实验的属性视图。复制部分
安排固定数量的复制
- 在项目视图中,选择优化实验。
- 在属性视图的复制部分中,选择使用复制复选框。
- 选择固定数量的复制选项。
- 在编辑框中指定每个迭代的复制次数。
安排变化数量的复制
遗传优化引擎不支持变化数量的复制。
- 在项目视图中,选择优化实验。
- 在属性视图的复制部分中,选择使用复制复选框。
- 选择**变化数量的复制(在达到最小复制次数时停止复制,当达到置信水平时)**选项。
- 在最小复制次数编辑框中指定最小复制次数。
- 在最大复制次数编辑框中指定最大复制次数。
- 为目标定义要评估的置信水平。
- 在误差百分比字段中指定用于确定置信水平的目标百分比。
提高优化性能
您可能会发现以下一些提示很有帮助:
- 在开始优化之前调试您的模型。如果您的模型在某些优化参数值下无法正常运行,您可以使用范围来限制搜索空间。否则,请注意可能的模型运行不正确。
- 如果优化引擎发现所有解决方案都是不可行的,这表明在参数空间中没有满足所有约束的解决方案。可能的原因有
-
约束不一致。检查是否存在冲突的约束,例如x>25, x<24。如果出现在约束中的变量是使用模型内的某些公式计算的,不一致可能在这些公式中。
-
优化参数的范围与约束冲突。
-
如果您发现优化性能不令人满意,请考虑以下建议。
更快地找到最优解
-
为您的问题调整优化引擎设置。微调这些设置可以提高优化性能(有关更多信息,请咨询AnyLogic类参考):
- 尽可能接近最优值地建议优化参数的初始值
- 通过指定优化参数的范围来缩小搜索空间
- 排除不影响目标函数的参数
- 避免使用约束。首先,在没有约束的情况下优化您的模型;然后检查最优解是否满足约束。如果某些约束未满足,请在约束下开始优化。
-
交互式和迭代地解决优化问题:
- 最初,使用问题的粗略近似:宽范围、大步长和低精度。
- 运行优化,直到找到的最佳值开始变化缓慢。
- 更精确地设置优化。减少优化参数的范围和步长。从上一步中获得的优化参数值开始。再次运行优化,直到找到的最佳值开始变化缓慢。如果对结果满意,请停止优化。否则,返回到上一步。
总的来说,优化过程可能非常耗时,特别是如果有多个参数。如果上述列表中的任何内容都无法帮助提高性能,请尝试使用更强大的工作站或为优化安排更多时间。
例子——youtube视频
1.主要智能体可修改参数
2.统计项
输出元素进行计算
3.Main中新建function函数
4.统计数据
本例中:需保持列车在卸货前不会排队等待
5.新建优化实验
①设置目标函数
其中,root代表最高层智能体
选择迭代数或自动停止,当目标函数不再改进时,自动停止实验
②参数变化的范围
③设置仿真停止时间
④有随机值时设置重复实验
⑤生成默认界面
图表展示目标函数的值
蓝色的线表示可行的解 红色的线表示不可行的解
⑥仿真结束后,可点击“copy”复制最优解,再到simulation中粘贴
一些使用心得
此处的“约束”非实际使用意义上的约束。这里放的表达式是用来控制输入的参数的。
此处的“要求 "是真正意义上的约束,检查求得解的可行性。