Main Content

本页翻译不是最新的。点击此处可查看最新英文版本。

prob2struct

将优化问题或方程问题转换为求解器形式

说明

使用 prob2struct 将优化问题或方程问题转换为求解器形式。

提示

有关完整的工作流,请参阅基于问题的优化工作流基于问题的方程求解工作流

示例

problem = prob2struct(prob) 返回适合基于求解器求解的优化问题结构体。对于非线性问题,prob2struct 会为目标函数创建文件,如有必要,还为非线性约束函数和支持文件创建文件。

示例

problem = prob2struct(prob,x0) 还转换初始点结构体 x0,并将其包含在 problem 中。

示例

problem = prob2struct(___,Name,Value) 在任何输入参数之外,还可使用一个或多个名称-值对组参数指定其他选项。例如,对于非线性优化问题,problem = prob2struct(prob,'ObjectiveFunctionName','objfun1') 指定 prob2struct 在当前文件夹中创建一个名为 objfun1.m 的目标函数文件。

示例

全部折叠

将优化问题对象转换为问题结构体。

混合整数线性规划基础:基于问题 输入基本 MILP 问题。

ingots = optimvar('ingots',4,1,'Type','integer','LowerBound',0,'UpperBound',1);
alloys = optimvar('alloys',4,1,'LowerBound',0);

weightIngots = [5,3,4,6];
costIngots = weightIngots.*[350,330,310,280];
costAlloys = [500,450,400,100];
cost = costIngots*ingots + costAlloys*alloys;

steelprob = optimproblem;
steelprob.Objective = cost;

totalweight = weightIngots*ingots + sum(alloys);

carbonIngots = [5,4,5,3]/100;
molybIngots = [3,3,4,4,]/100;
carbonAlloys = [8,7,6,3]/100;
molybAlloys = [6,7,8,9]/100;

totalCarbon = (weightIngots.*carbonIngots)*ingots + carbonAlloys*alloys;
totalMolyb = (weightIngots.*molybIngots)*ingots + molybAlloys*alloys;

steelprob.Constraints.conswt = totalweight == 25;
steelprob.Constraints.conscarb = totalCarbon == 1.25;
steelprob.Constraints.consmolyb = totalMolyb == 1.25;

将问题转换为 intlinprog 问题结构体。

problem = prob2struct(steelprob);

检查生成的线性等式约束矩阵和向量。

Aeq = problem.Aeq
Aeq = 
   (1,1)       1.0000
   (2,1)       0.0800
   (3,1)       0.0600
   (1,2)       1.0000
   (2,2)       0.0700
   (3,2)       0.0700
   (1,3)       1.0000
   (2,3)       0.0600
   (3,3)       0.0800
   (1,4)       1.0000
   (2,4)       0.0300
   (3,4)       0.0900
   (1,5)       5.0000
   (2,5)       0.2500
   (3,5)       0.1500
   (1,6)       3.0000
   (2,6)       0.1200
   (3,6)       0.0900
   (1,7)       4.0000
   (2,7)       0.2000
   (3,7)       0.1600
   (1,8)       6.0000
   (2,8)       0.1800
   (3,8)       0.2400

beq = problem.beq
beq = 3×1

   25.0000
    1.2500
    1.2500

检查边界。

problem.lb
ans = 8×1

     0
     0
     0
     0
     0
     0
     0
     0

problem.ub
ans = 8×1

   Inf
   Inf
   Inf
   Inf
     1
     1
     1
     1

通过调用 intlinprog 求解问题。

x = intlinprog(problem)
LP:                Optimal objective value is 8125.600000.                                          

Cut Generation:    Applied 3 mir cuts.                                                              
                   Lower bound is 8495.000000.                                                      
                   Relative gap is 0.00%.                                                          


Optimal solution found.

Intlinprog stopped at the root node because the objective value is within a gap tolerance of the optimal value, options.AbsoluteGapTolerance = 0. The intcon variables are integer within tolerance, options.IntegerTolerance = 1e-05.
x = 8×1

    7.0000
    0.5000
         0
    3.5000
    1.0000
    1.0000
         0
    1.0000

采用基于问题的框架创建一个非线性问题。

x = optimvar('x',2);
fun = log(1 + 100*(x(2) - x(1)^2)^2 + (1 - x(1))^2);
prob = optimproblem('Objective',fun);
mycon = dot(x,x) <= 4;
prob.Constraints.mycon = mycon;
x0.x = [-1;1.5];

prob 转换为优化问题结构体。将生成的目标函数文件命名为 'logrosenbrock',将约束函数文件命名为 'circle2'

problem = prob2struct(prob,x0,'ObjectiveFunctionName','logrosenbrock',...
    'ConstraintFunctionName','circle2');

prob2struct 在当前文件夹中创建非线性目标和约束函数文件。要在一个不同文件夹中创建这些文件,请使用 'FileLocation' 名称-值对组。

求解。

[x,fval] = fmincon(problem)
Local minimum found that satisfies the constraints.

Optimization completed because the objective function is non-decreasing in 
feasible directions, to within the value of the optimality tolerance,
and constraints are satisfied to within the value of the constraint tolerance.
x = 2×1

    1.0000
    1.0000

fval = 4.7244e-11

输入参数

全部折叠

优化问题或方程问题,指定为 OptimizationProblem 对象或 EquationProblem 对象。使用 optimproblem 创建优化问题;使用 eqnproblem 创建方程问题。

警告

基于问题的方法不支持目标函数、非线性等式或非线性不等式中使用复数值。如果某函数计算具有复数值,即使是作为中间值,最终结果也可能不正确。

示例: prob = optimproblem; prob.Objective = obj; prob.Constraints.cons1 = cons1;

示例: prob = eqnproblem; prob.Equations = eqs;

初始点,指定为结构体,其字段名称等于 prob 中的变量名称。

对于某些 Global Optimization Toolbox 求解器,x0 可以是表示多个初始点的 OptimizationValues 对象的向量。使用 optimvalues 函数创建这些点。这些求解器包括:

  • ga (Global Optimization Toolbox)gamultiobj (Global Optimization Toolbox)paretosearch (Global Optimization Toolbox)particleswarm (Global Optimization Toolbox)。这些求解器接受多个起点作为初始种群的成员。

  • MultiStart (Global Optimization Toolbox).此求解器可对局部求解器(如 fmincon)应用多个初始点。

  • surrogateopt (Global Optimization Toolbox).此求解器接受多个初始点,以帮助创建一个初始替代。

有关以命名索引变量指定 x0 的示例,请参阅Create Initial Point for Optimization with Named Index Variables

示例: 如果 prob 具有名为 xy 的变量:x0.x = [3,2,17]; x0.y = [pi/3,2*pi/3]

数据类型: struct

名称-值参数

将可选的参数对组指定为 Name1=Value1,...,NameN=ValueN,其中 Name 是参数名称,Value 是对应的值。名称-值参数必须出现在其他参数之后,但参数对组的顺序无关紧要。

在 R2021a 之前,使用逗号分隔每个名称和值,并用引号将 Name 引起来。

示例: problem = prob2struct(prob,'FileLocation','C:\Documents\myproblem')

指示对非线性约束函数使用自动微分 (AD),指定为由 'ConstraintDerivative''auto'(如果可能,请使用 AD)组成的以逗号分隔的对组形式、'auto-forward'(如果可能,请使用正向 AD)、'auto-reverse'(如果可能,请使用反向 AD)或 'finite-differences'(不要使用 AD)。包括 auto 在内的选择项会导致生成的约束函数文件在求解问题时使用梯度信息,前提是约束函数受支持,如Supported Operations for Optimization Variables and Expressions中所述。有关示例,请参阅Supply Derivatives in Problem-Based Workflow

注意

要在由 prob2struct 转换的问题中使用自动导数,请传递指定这些导数的选项。

options = optimoptions('fmincon','SpecifyObjectiveGradient',true,...
    'SpecifyConstraintGradient',true);
problem.options = options;

示例: 'finite-differences'

数据类型: char | string

prob2struct 为优化问题创建的非线性约束函数文件的名称,指定为由 'ConstraintFunctionName' 和文件名组成的以逗号分隔的对组。此参数适用于 fminconfminunc 问题;请参阅 problem。文件名中不要包含文件扩展名 .mprob2struct 会在创建文件时追加文件扩展名。

如果您未指定 ConstraintFunctionName,则 prob2struct 会覆盖 'generatedConstraints.m'。如果您未指定 FileLocation,则 prob2struct 会在当前文件夹中创建文件。

返回的 problem 结构体引用此函数文件。

示例: "mynlcons"

数据类型: char | string

prob2struct 为方程问题创建的非线性方程函数文件的名称,指定为由 'EquationFunctionName' 和文件名组成的以逗号分隔的对组。此参数适用于 fsolvefzerolsqnonlin 方程;请参阅problem。文件名中不要包含文件扩展名 .mprob2struct 会在创建文件时追加文件扩展名。

如果您未指定 EquationFunctionName,则 prob2struct 会覆盖 'generatedEquation.m'。如果您未指定 FileLocation,则 prob2struct 会在当前文件夹中创建文件。

返回的 problem 结构体引用此函数文件。

示例: "myequation"

数据类型: char | string

生成的文件(目标函数、约束函数和其他子函数文件)的位置,指定为逗号分隔的对组,其中包含 'FileLocation' 和可写文件夹的路径。所有生成的文件都存储在此文件夹中;不支持多个文件夹。

示例: 'C:Documents\MATLAB\myproject'

数据类型: char | string

指示对非线性目标函数使用自动微分 (AD),指定为由 'ObjectiveDerivative''auto'(如果可能,请使用 AD)组成的以逗号分隔的对组形式、'auto-forward'(如果可能,请使用正向 AD)、'auto-reverse'(如果可能,请使用反向 AD)或 'finite-differences'(不要使用 AD)。包括 auto 在内的选择项会导致生成的目标函数文件在求解问题时包含导数信息,前提是目标函数受支持,如Supported Operations for Optimization Variables and Expressions中所述。有关示例,请参阅Supply Derivatives in Problem-Based Workflow

注意

要在由 prob2struct 转换的问题中使用自动导数,请传递指定这些导数的选项。

options = optimoptions('fmincon','SpecifyObjectiveGradient',true,...
    'SpecifyConstraintGradient',true);
problem.options = options;

示例: 'finite-differences'

数据类型: char | string

prob2struct 为优化问题创建的目标函数文件的名称,指定为由 'ObjectiveFunctionName' 和文件名组成的以逗号分隔的对组。此参数适用于 fminconfminunc 问题;请参阅 problem。文件名中不要包含文件扩展名 .mprob2struct 会在创建文件时追加文件扩展名。

如果您未指定 ObjectiveFunctionName,则 prob2struct 会覆盖 'generatedObjective.m'。如果您未指定 FileLocation,则 prob2struct 会在当前文件夹中创建文件。

返回的 problem 结构体引用此函数文件。

示例: "myobj"

数据类型: char | string

优化求解器,指定为一个列出的求解器的名称。对于优化问题,下表包含每个问题类型的可用求解器,包括来自 Global Optimization Toolbox 的求解器。方程问题的详细信息显示在优化求解器详细信息下方。

对于使用 prob2struct 转换具有整数约束的非线性问题,生成的问题结构体可能取决于所选求解器。如果您没有 Global Optimization Toolbox 许可证,则必须指定求解器。请参阅基于问题的非线性优化中的整数约束

此处列出了每种优化问题类型的默认求解器。

问题类型默认求解器
线性规划 (LP)linprog
混合整数线性规划 (MILP)intlinprog
二次规划 (QP)quadprog
二阶锥规划 (SOCP)coneprog
线性最小二乘lsqlin
非线性最小二乘lsqnonlin
非线性规划 (NLP)

fminunc 用于没有约束的问题,否则使用 fmincon

混合整数非线性规划 (MINLP)ga (Global Optimization Toolbox)
多目标gamultiobj (Global Optimization Toolbox)

在下表中,Yes 表示对应求解器可用于该问题类型,x 表示对应求解器不可用。

问题类型

LPMILPQPSOCP线性最小二乘非线性最小二乘NLPMINLP
求解器
linprog

Yes

xxxxxxx
intlinprog

Yes

Yes

xxxxxx
quadprog

Yes

x

Yes

Yes

Yes

xxx
coneprog

Yes

xx

Yes

xxxx
lsqlinxxxx

Yes

xxx
lsqnonnegxxxx

Yes

xxx
lsqnonlinxxxx

Yes

Yes

xx
fminunc

Yes

x

Yes

x

Yes

Yes

Yes

x
fmincon

Yes

x

Yes

Yes

Yes

Yes

Yes

x
fminbndxxxx

Yes

Yes

Yes

x
fminsearchxxxx

Yes

Yes

Yes

x
patternsearch (Global Optimization Toolbox)

Yes

x

Yes

Yes

Yes

Yes

Yes

x
ga (Global Optimization Toolbox)

Yes

Yes

Yes

Yes

Yes

Yes

Yes

Yes

particleswarm (Global Optimization Toolbox)

Yes

x

Yes

x

Yes

Yes

Yes

x
simulannealbnd (Global Optimization Toolbox)

Yes

x

Yes

x

Yes

Yes

Yes

x
surrogateopt (Global Optimization Toolbox)

Yes

Yes

Yes

Yes

Yes

Yes

Yes

Yes

gamultiobj (Global Optimization Toolbox)

Yes

Yes

Yes

Yes

Yes

Yes

Yes

Yes

paretosearch (Global Optimization Toolbox)

Yes

x

Yes

Yes

Yes

Yes

Yes

x

注意

如果您选择 lsqcurvefit 作为最小二乘问题的求解器,solve 将使用 lsqnonlin。对于 solvelsqcurvefitlsqnonlin 求解器是相同的。

小心

对于最大化问题(prob.ObjectiveSense"max""maximize"),不要指定最小二乘求解器(名称以 lsq 开头的求解器)。如果指定,则 solve 会引发错误,因为这些求解器无法最大化。

对于方程求解,下表包含每个问题类型的可用求解器。在表中,

  • * 表示该问题类型的默认求解器。

  • Y 表示可用的求解器。

  • N 表示不可用的求解器。

方程支持的求解器

方程类型lsqlinlsqnonnegfzerofsolvelsqnonlin
线性*NY(仅标量)YY
线性加边界*YNNY
标量非线性NN*YY
非线性方程组NNN*Y
非线性方程组加边界NNNN*

示例: 'intlinprog'

数据类型: char | string

输出参数

全部折叠

问题结构体,以下列结构体形式返回:fmincon problem 结构体、fminunc problem 结构体、fsolve problem 结构体、intlinprog problem 结构体、linprog problem 结构体、lsqlin problem 结构体、lsqnonlin problem 结构体、quadprog problem 结构体或 ga problem (Global Optimization Toolbox) 结构体。

下表给出了根据优化问题生成的默认问题类型。您还可以获得非默认问题类型。例如,对于非线性边界约束问题,您可以使用 solver 参数选择大多数 Global Optimization Toolbox 求解器。

优化目标和约束类型(线性约束包括边界)

生成的问题类型

线性目标和约束函数。

至少一个问题变量具有 'integer' 类型。

intlinprog

线性目标和约束函数。

没有问题变量具有 'integer' 类型。

linprog

线性约束函数。

目标函数是常数加上线性表达式的平方和。

lsqlin

边界约束。

目标函数是常数加上一般非线性表达式的平方和。

lsqnonlin

线性约束函数。

一般二次目标函数。

quadprog

一般非线性目标函数。

无约束。

fminunc

一般非线性目标函数,并且有至少一个任何类型的约束。

或者,有至少一个一般非线性约束函数。

fmincon

非线性目标函数或约束函数,且有至少一个整数变量。

ga

下表给出了根据方程求解问题生成的问题类型。

方程类型

生成的问题类型

有边界或无边界的线性方程组

lsqlin

标量(单精度)非线性方程

fzero

无约束的非线性方程组

fsolve

具有边界的非线性方程组

lsqnonlin

注意

对于非线性问题,prob2struct 为目标和非线性约束函数创建函数文件。对于调用支持函数的目标和约束函数,prob2struct 还会创建支持函数文件,并将其存储在 FileLocation 文件夹中。要访问所生成函数中的其他参数,请参阅Obtain Generated Function Details

对于线性和二次优化问题,问题结构体包括额外的字段 f0,它表示目标函数的加法常数。如果使用指定的求解器来求解问题结构体,则返回的目标函数值不包括 f0 值。如果您使用 solve 函数求解 prob,则返回的目标函数值包括 f0 值。

如果 probObjectiveSense'max''maximize',则 problemprob 中使用目标函数的负值,因为求解器执行最小化。要执行最大化,它们将最小化原始目标函数的负值。在本例中,求解器报告的最佳函数值是原始问题中的值的负数。请参阅对目标进行最大化。您不能使用 lsqlin 求解最大化问题。

提示

  • 如果您为非线性问题在同一 MATLAB® 会话中多次调用 prob2struct,请使用 ObjectiveFunctionNameEquationFunctionName 参数,如果合适,还使用 ConstraintFunctionName 参数。指定唯一名称可以确保生成的问题结构体引用正确的目标和约束函数。否则,对 prob2struct 的后续调用可能导致生成的非线性函数文件覆盖现有文件。

  • 为了避免导致无限递归,请不要在目标或约束函数内调用 prob2struct

  • 当为非线性问题并行调用 prob2struct 时,请确保生成的目标和约束函数文件具有唯一名称。这样做可以避免每次循环遍历写入相同的一个或多个文件。

算法

全部折叠

转换为求解器形式

问题结构体的根本是将所有问题变量隐式排列成一个向量。问题变量的顺序与 probVariables 属性的顺序相同。请参阅 OptimizationProblem。您也可以使用 varindex 查找顺序。

例如,假设问题变量的顺序如下:

  • x - 3×2×4 数组

  • y - 3×2 数组

在本例中,隐式变量顺序如同问题变量是 vars = [x(:);y(:)] 时的顺序。

vars 的前 24 个元素等效于 x(:),接下来的 6 个元素等效于 y(:),总共 30 个元素。下界和上界对应于此变量顺序,每个线性约束矩阵有 30 列。

对于具有一般非线性目标或约束函数的问题,prob2struct 在当前文件夹或 FileLocation 指定的文件夹中创建函数文件。返回的 problem 结构体引用这些函数文件。

自动微分

在以下条件下,自动微分 (AD) 适用于 solveprob2struct 函数:

  • 目标函数和约束函数受支持,如Supported Operations for Optimization Variables and Expressions中所述。它们不需要使用 fcn2optimexpr 函数。

  • solve 调用的求解器是 fminconfminuncfsolvelsqnonlin

  • 对于优化问题,solveprob2struct'ObjectiveDerivative''ConstraintDerivative' 名称-值对组参数设置为 'auto'(默认值)、'auto-forward''auto-reverse'

  • 对于方程问题,'EquationDerivative' 选项设置为 'auto'(默认值)、'auto-forward''auto-reverse'

AD 的适用情形所有约束函数均受支持一个或多个约束不受支持
目标函数受支持AD 用于目标和约束AD 仅用于目标
目标函数不受支持AD 仅用于约束不使用 AD

注意

对于线性或二次目标或约束函数,适用的求解器始终使用显函数梯度。这些梯度不是使用 AD 生成的。请参阅Closed Form

当不满足这些条件时,solve 通过有限差分来估计梯度,prob2struct 不会在其生成的函数文件中创建梯度。

默认情况下,求解器选择以下 AD 类型:

  • 对于一般的非线性目标函数,fmincon 默认选择反向 AD。对于非线性约束函数,如果其非线性约束的数量小于变量数目,fmincon 默认选择反向 AD。否则,fmincon 默认选择正向 AD。

  • 对于一般的非线性目标函数,fminunc 默认选择反向 AD。

  • 对于最小二乘目标函数,fminconfminunc 对目标函数默认选择正向 AD。有关基于问题的最小二乘目标函数的定义,请参阅Write Objective Function for Problem-Based Least Squares

  • 当目标向量中的元素数大于或等于变量数时,lsqnonlin 默认选择正向 AD。否则,lsqnonlin 默认选择反向 AD。

  • 当方程数大于或等于变量数时,fsolve 默认选择正向 AD。否则,fsolve 默认选择反向 AD。

注意

要在由 prob2struct 转换的问题中使用自动导数,请传递指定这些导数的选项。

options = optimoptions('fmincon','SpecifyObjectiveGradient',true,...
    'SpecifyConstraintGradient',true);
problem.options = options;

当前,AD 仅适用于一阶导数;它不适用于二阶或更高阶导数。因此,在某些情况下(例如,如果您要使用解析黑塞矩阵来加速优化),您无法直接使用 solve,而必须使用Supply Derivatives in Problem-Based Workflow中所述的方法。

版本历史记录

在 R2017b 中推出

全部展开