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 default
value). The intcon variables are integer within tolerance,
options.IntegerTolerance = 1e-05 (the default value).
x = 8×1

    7.2500
         0
    0.2500
    3.5000
    1.0000
    1.0000
         0
    1.0000

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

x = optimvar('x',2);
fun = 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 转换为优化问题结构体。将生成的目标函数文件命名为 'rosenbrock',将约束函数文件命名为 'circle2'

problem = prob2struct(prob,x0,'ObjectiveFunctionName','rosenbrock',...
    '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.6187e-11

输入参数

全部折叠

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

警告

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

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

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

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

有关以命名索引变量指定 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

名称-值对组参数

指定可选的、以逗号分隔的 Name,Value 对组参数。Name 为参数名称,Value 为对应的值。Name 必须放在引号中。您可采用任意顺序指定多个名称-值对组参数,如 Name1,Value1,...,NameN,ValueN 所示。

示例: 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

输出参数

全部折叠

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

下表给出了根据优化问题生成的问题类型。

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

生成的问题类型

线性目标和约束函数。

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

intlinprog

线性目标和约束函数。

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

linprog

线性约束函数。

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

lsqlin

边界约束。

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

lsqnonlin

线性约束函数。

一般二次目标函数。

quadprog

一般非线性目标函数。

无约束。

fminunc

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

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

fmincon

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

方程类型

生成的问题类型

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

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 函数:

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

当不满足这些条件时,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 仅适用于一阶导数;它不适用于二阶或更高阶导数。因此,在某些情况下(例如,如果您要使用解析 Hessian 矩阵来加速优化),您无法直接使用 solve,而必须使用Supply Derivatives in Problem-Based Workflow中所述的方法。

兼容性考虑

全部展开

从 R2021a 起会出现错误

在 R2017b 中推出