主要内容

使用自定义约束条件和目标函数计算操作点

通常,当计算模型的稳态运行点®模型使用一个文中针对搜索,指定固定的值或范围约束模型,输入或输出。万博1manbetx然而,一些系统或应用程序需要额外的灵活性定义优化搜索参数。

对于这样的系统,您可以指定自定义约束,一个额外的优化目标函数,或两者兼而有之。当软件计算稳态操作点,它适用于这些自定义约束条件和目标函数除了标准的状态,输入和输出规范。

等式和不等式约束可以指定自定义的代数组合模型,输入和输出。这些约束让你限制操作点搜索空间通过指定输入之间的关系,输出和状态。例如,您可以指定一个模型状态是两个其他国家的总和。

您还可以指定一个自定义标量模型目标函数的代数组合状态,输入和输出。使用目标函数可以根据您的应用程序需求优化稳态操作点。例如,假设您的模型有多个潜在的平衡分。您可以指定一个目标函数找到稳态点的最小输入能量。

对于复杂的模型,您可以指定一个自定义映射函数,选择一个子集模型的输入,输出,和州通过自定义成本和约束功能。

您可以指定自定义优化函数当削减你的模型:

  • 在命令行:创建一个操作点规范使用operspec,并指定使用自定义函数CustomConstrFcn,CustomCostFcn,CustomMappingFcn规范的属性。

  • 使用稳态经理:规范选项卡上,单击削减选项。在削减选项对话框,定制优化函数节中,指定函数的名字。

  • 使用模型线性化电路:线性分析选项卡,操作点下拉列表中,单击调整模型。在削减模型对话框,选项选项卡,定制优化函数节中,指定函数的名字。

下面的例子显示了如何创建自定义优化功能和如何调整模型在命令行中使用这些定制功能。

万博1manbetx仿真软件模型

对于这个示例,使用一个模型由孔相互连接的三个坦克。

mdl =“scdTanks”;open_system (mdl)

Tank1和Tank2之间流动。Tank2和Tank3之间的流动是不受欢迎的不可避免的泄漏。

在这个系统的预期稳态:

  • Tank1和Tank2有相同的压力。

  • Tank2和Tank3几乎恒定压差1补偿负载。

由于弱Tank1和Tank2之间的连接,很难调整模型,这样压力Tank1和Tank2是相等的。

削减模型没有定制

创建一个默认的操作点规范模型。规范配置三个罐压力,必须在稳定状态的自由州修剪操作点。

opspec = operspec (mdl);

创建一个选项设置调整模型,抑制的命令窗口显示操作点搜索报告。特定的调整选项取决于您的应用程序。对于这个示例,使用非线性最小二乘优化。

选择= findopOptions (“OptimizerType”,“lsqnonlin”);opt.DisplayReport =“关闭”;

调整模型,并查看了坦克的压力。

[op0, rpt0] = findop (mdl opspec,选择);op0.States
__ (1)scdTanks ans = x /惯性0 (2)scdTanks / Tank1 9 (3) scdTanks / Tank2 9.5 (4) scdTanks / Tank3 10.5

减少压力Tank1 Tank2不匹配。因此,默认操作点规范未能找到一个操作点,符合预期的稳定状态的要求。如果你减少约束宽容,opt.OptimizationOptions.TolCon,你不能实现一个可行的稳态解由于泄漏Tank2和Tank3之间。

添加自定义约束

指定自定义约束,定义一个函数在当前工作目录中或在MATLAB路径输入参数:

  • x-操作点规范,指定为一个向量。

  • u-操作点规范输入,指定为一个向量。

  • y-操作点规范输出,指定为一个向量。

输出参数:

  • c_ineq——必须满足的不等式约束c_ineq < = 0在调整期间,作为一个向量返回。

  • c_eq——平等必须满足的约束条件c_eq = 0在调整期间,作为一个向量返回。

的每个元素c_ineqc_eq指定一个约束。为应用程序定义的特定约束的代数组合状态,输入和输出。如果没有等式或不等式约束定义,返回相应的输出参数[]

对于这个示例,以满足预期的稳定状态的条件,定义以下自定义约束函数。

函数[c_ineq, c_eq] = myConstraints (x, y) c_ineq = [];c_eq = [x (2) - x (3);% Tank1 - Tank2压力的压力x (3) - x (4) + 1];% Tank2压力- Tank3压力+ 1结束

第一项的c_eq约束的压力Tank1和Tank2相同的值。第二个等式约束定义Tank2和Tank3之间的压降。

添加自定义约束函数操作规范。

opspec。CustomConstrFcn = @myConstraints;

修剪模型使用修改后的操作规范,包含自定义约束,并查看修剪状态值。

(凤凰社第一章,rpt1) = findop (mdl opspec,选择);op1.States
____ ans = x (1) scdTanks /惯性0 (2)scdTanks / Tank1 9.3333 (3) scdTanks / Tank2 9.3333 (4) scdTanks / Tank3 10.3333

调整模型与自定义约束函数产生一个操作点第一和第二坦克,以同样的压力。此外,正如所料,有一个压差1第三和第二坦克。

检查的最终值指定的限制,你可以检查CustomEqualityConstrCustomInequalityConstr操作点搜索的报告的属性。

rpt1.CustomEqualityConstr
ans e-06 * -0.0001 - -0.1540 = 1.0

接近零值表明,等式约束得到满足。

添加自定义目标函数

指定一个自定义的目标函数,定义一个函数的输入参数自定义约束函数(x,u,y),和输出参数FF是一个目标函数值最小调整期间,作为一个标量返回。

应用程序的目标函数定义为一个代数的组合状态,输入和输出。

对于这个示例,假设您想要在Tank3压力范围(16、20)。然而,这种情况并不总是可行的。因此,而不是强加硬约束,添加一个目标函数产生一个点球,如果压力不(16、20)。为此,定义以下自定义目标函数。

函数F = myObjective (x, y) F = max (x(4) -20,0) +马克斯(16 x (4), 0);结束

添加自定义操作点指定对象的目标函数。

opspec。CustomObjFcn = @myObjective;

修剪操作点使用自定义约束和定义目标函数,并查看修剪状态值。

(《凤凰社》第2章,rpt2) = findop (mdl opspec,选择);op2.States
ans = x __ (1) scdTanks /惯性0 (2)scdTanks / Tank1 15 (3) scdTanks / Tank2 15 (4) scdTanks / Tank3 16

修剪操作点,压力Tank3在[16、20]范围内指定的自定义目标函数。

查看最后的标量值目标函数,检查CustomObj财产的操作点搜索报告。

rpt2.CustomObj
ans = 0

添加自定义映射

对于复杂的模型,您可以定义一个自定义的映射,选择模型的一个子集,输入和输出通过自定义约束条件和目标函数。这样简化了约束和目标函数通过消除不必要的状态,输入和输出。

指定一个自定义映射,定义一个函数与操作规范,opspec、作为一个输入参数和输出参数:

  • indx——指数映射

  • indu——指数映射输入

  • 印第——指数映射输出

获取状态,输入和输出指标基于块路径和国家名称使用getStateIndex,getInputIndex,getOutputIndex。使用这些命令是健壮的未来模型的变化,如增加模型的状态。或者,您可以手动指定索引。更多信息的格式indx,indu,印第,请参阅getStateIndex,getInputIndex,getOutputIndex

如果没有状态、输入或输出使用的自定义约束条件和目标函数,返回相应的输出参数[]

对于这个示例,创建一个映射,它只包含三个坦克的压力状态。为此,定义以下自定义映射函数。

函数[indx, indu,印第]=关联(opspec) indx = [getStateIndex opspec,“scdTanks / Tank1”);getStateIndex (opspec“scdTanks / Tank2”);getStateIndex (opspec“scdTanks / Tank3”));indu = [];印地赛车= [];结束

添加自定义映射到操作规范。

opspec。CustomMappingFcn = @myMapping;

当你使用一个自定义的映射函数,指数,在您的自定义输入和输出约束条件和目标函数都必须相对于订单中指定的映射函数。更新与新的映射自定义约束和目标函数。

函数[c_ineq, c_eq] = myConstraintsMap (x, y) c_ineq = [];c_eq = [x - x (1) (2);% Tank1 - Tank2压力的压力x (2) - x (3) + 1];% Tank2压力- Tank3压力+ 1结束
函数F = myObjectiveMap (x, y) F = max (x(3) -20,0) +马克斯(16 x (3), 0);结束

在这里,x,u,y向量的映射状态、输入和输出,分别。这些向量包含映射中指定的值indx,indu,印第,分别。

添加更新的自定义函数来操作规范。

opspec。CustomConstrFcn = @myConstraintsMap;opspec。CustomObjFcn = @myObjectiveMap;

削减模型使用自定义映射,并查看了,与以往的结果《凤凰社》第2章

[op3, rpt3] = findop (mdl opspec,选择);op3.States
ans = x __ (1) scdTanks /惯性0 (2)scdTanks / Tank1 15 (3) scdTanks / Tank2 15 (4) scdTanks / Tank3 16

分析梯度添加到定制函数

对于更快或更可靠的计算,可以分析梯度添加到您的自定义约束条件和目标函数。添加渐变可以减少函数调用的数量在优化和可能提高优化结果的准确性。如果你指定渐变,你必须指定自定义约束条件和目标函数。(渐变为不支持自定义调整Simscape™模型)。万博1manbetx

定义给定约束条件或目标函数的梯度,求导函数对一个给定的状态下,输入或输出。例如,如果目标函数

F = (u (1) + 3) ^ 2 + y (1) ^ 2

然后的梯度F关于u (1)

G = 2 * (u (1) + 3)

将梯度添加到您的自定义约束函数,指定以下额外的输出参数:

  • G_ineq——为不等式约束梯度数组

  • G_eq——为等式约束梯度数组

每一列的G_ineqG_eq包含一个约束的梯度,列的顺序匹配的行对应的约束向量。的行数G_ineqG_eq等于的总数,输入,输出x,u,y。每一列包含梯度的州x,紧随其后的是输入u,然后输出y

在这个例子中,添加梯度约束函数,使用自定义映射。你不需要使用渐变时指定一个自定义映射。然而,定义渐变更简单使用映射子集的状态时,输入和输出。

函数[c_ineq, c_eq G_ineq G_eq] = myConstraintsGrad (x, y) c_ineq = [];c_eq = [x - x (1) (2);% Tank1 - Tank2压力的压力x (2) - x (3) + 1];% Tank2压力- Tank3压力+ 1G_ineq = [];G_eq = [1 0;1 1;0 1];结束

在这个函数中,行G_eq包含梯度对状态x(我)

同样,将梯度添加到您的自定义目标函数,指定一个额外的输出参数G,其中包含的梯度FG作为一个列向量具有相同的格式返回的列G_ineqG_eq

函数(F, G) = myObjectiveGrad (x, y) F = max (x(3) -20,0) +马克斯(16 x (3), 0);如果x (3) > = 20 G = (0 0 1);elseifx (3) < = 16 G = (0 0 1);其他的G = (0 0 0) ';结束结束

因为本例中的目标函数是分段可微的,的价值G在Tank3取决于价值的压力。

添加更新的自定义函数来操作规范。

opspec。CustomConstrFcn = @myConstraintsGrad;opspec。CustomObjFcn = @myObjectiveGrad;

使梯度优化算法,使雅可比矩阵优化选择。

opt.OptimizationOptions。雅可比矩阵=“上”;

使用分析雅克比当削减模型使用稳态经理或者是模型线性化电路,选择使雅可比矩阵分析调整选项。

修剪与梯度模型使用自定义函数,并查看了。

[op4, rpt4] = findop (mdl opspec,选择);op4.States
ans = x __ (1) scdTanks /惯性0 (2)scdTanks / Tank1 15 (3) scdTanks / Tank2 15 (4) scdTanks / Tank3 16

优化的结果是一样的结果nongradient解决方案。

梯度提高优化效率,是否查看操作点搜索报告。例如,比较函数数量评估的解决方案:

  • 没有梯度:

rpt3.OptimizationOutput.funcCount
ans = 25
  • 与梯度:

rpt4.OptimizationOutput.funcCount
ans = 5

在这个例子中,添加分析梯度优化期间减少函数调用的数量。

另请参阅

||||

相关的话题