优化表达式
什么是优化表达式?
优化表达式是优化变量的多项式或有理组合。
x = optimvar('x',3,3); % a 3-by-3 variable named 'x' expr1 = sum(x,1) % add the columns of x, get a row vector expr2 = sum(x,2) % add the rows of x, get a column vector expr3 = sum(sum(x.*randn(3))) % add the elements of x multiplied by random numbers expr4 = randn(3)*x % multiply a random matrix times x expr5 = sum(sum(x*diag(1:3))) % multiply the columns of x by their column number and sum the result expr6 = sum(sum(x.*x)) % sum of the squares of all the variables
优化表达式也是对优化变量进行许多 MATLAB® 操作的结果,例如变量的转置或连接。有关优化表达式支持的运算的列表,请参阅优化变量和表达式支持的运算。
最后,优化表达式可以是将 fcn2optimexpr
应用于作用于优化变量的 MATLAB 函数的结果。有关详细信息,请参阅将非线性函数转换为优化表达式。
优化建模函数不允许您指定复杂的、Inf
或 NaN
值。如果通过运算得到这样的表达式,则该表达式无法显示出来。请参阅表达式包含 Inf 或 NaN。
目标函数表达式
目标函数是 1×1 大小的表达式。
y = optimvar('y',5,3); expr = sum(y,2); % a 5-by-1 vector expr2 = [1:5]*expr;
表达式 expr
不适合目标函数,因为它是一个向量。表达式 expr2
适合目标函数。
注意
如果您的非线性函数不是由多项式、有理式和初等函数(如 exp
)组成的,可以使用 fcn2optimexpr
将其转换为优化表达式。请参阅将非线性函数转换为优化表达式和优化变量和表达式支持的运算。
要将表达式作为目标函数包含在问题中,请使用点符号,或在创建问题时包含目标。
prob = optimproblem; prob.Objective = expr2; % or equivalently prob = optimproblem('Objective',expr2);
要在循环中创建表达式,请从 optimexpr
返回的空表达式开始。
x = optimvar('x',3,3,'Type','integer','LowerBound',0,'UpperBound',1); y = optimvar('y',3,3); expr = optimexpr; for i = 1:3 for j = 1:3 expr = expr + y(j,i) - x(i,j); end end show(expr)
y(1, 1) + y(2, 1) + y(3, 1) + y(1, 2) + y(2, 2) + y(3, 2) + y(1, 3) + y(2, 3) + y(3, 3) - x(1, 1) - x(2, 1) - x(3, 1) - x(1, 2) - x(2, 2) - x(3, 2) - x(1, 3) - x(2, 3) - x(3, 3)
您可以创建不带任何循环的 expr
:
x = optimvar('x',3,3,'Type','integer','LowerBound',0,'UpperBound',1); y = optimvar('y',3,3); expr = sum(sum(y' - x)); show(expr)
y(1, 1) + y(2, 1) + y(3, 1) + y(1, 2) + y(2, 2) + y(3, 2) + y(1, 3) + y(2, 3) + y(3, 3) - x(1, 1) - x(2, 1) - x(3, 1) - x(1, 2) - x(2, 2) - x(3, 2) - x(1, 3) - x(2, 3) - x(3, 3)
注意
如果您的目标函数是平方和,并且您希望 solve
将其识别为平方和,请将其写为 sum(expr.^2)
,而不是 expr'*expr
。内部解析器只能识别明确的平方和。有关示例,请参阅 基于问题的非负线性最小二乘法。
约束和方程的表达式
约束是任意两个可比较的表达式,其中包含以下比较运算符之一:==
、<=
或 >=
。等式是两个使用比较运算符 ==
的可比较表达式。可比较的表达式具有相同的大小,或者其中一个表达式必须是标量,即大小为 1×1。
x = optimvar('x',3,2,'Type','integer','LowerBound',0,'UpperBound',1); y = optimvar('y',2,4); z = optimvar('z'); constr1 = sum(x,2) >= z;
x
的大小为 3×2,因此 sum(x,2)
的大小为 3×1。该表达式与 z
相当,因为 z
是一个标量变量。
constr2 = y <= z;
y
的尺寸为 2×4。再次,y
与 z
相当,因为 z
是一个标量变量。
constr3 = (sum(x,1))' <= sum(y,2);
sum(x,1)
的大小为 1×2,因此 (sum(x,1))'
的大小为 2×1。sum(y,2)
的大小为 2×1,因此这两个表达式是可比较的。
注意
如果您的非线性函数不是由多项式、有理式和初等函数(如 exp
)组成的,可以使用 fcn2optimexpr
将其转换为优化表达式。请参阅将非线性函数转换为优化表达式和优化变量和表达式支持的运算。
要在问题中包含约束,请使用点符号并为每个约束赋予不同的名称。
prob = optimproblem; prob.Constraints.constr1 = constr1; prob.Constraints.constr2 = constr2; prob.Constraints.constr3 = constr3;
类似地,为了在问题中包含方程式,请使用点符号并赋予每个方程式不同的名称。
prob = eqnproblem; prob.Equations.eq1 = eq1; prob.Equations.eq2 = eq12
您还可以在创建问题时包含约束或方程式。例如,假设您有 10 对正变量,它们的和不超过一。
x = optimvar('x',10,2,'LowerBound',0); prob = optimproblem('Constraints',sum(x,2) <= 1);
要在循环中创建约束或方程表达式,请从 optimconstr
、optimeq
或 optimineq
返回的空约束表达式开始。
x = optimvar('x',3,2,'Type','integer','LowerBound',0,'UpperBound',1); y = optimvar('y',2,4); z = optimvar('z'); const1 = optimconstr(2); for i = 1:2 const1(i) = x(1,i) - x(3,i) + 2*z >= 4*(y(i,2) + y(i,3) + 2*y(i,4)); end show(const1)
(1, 1) x(1, 1) - x(3, 1) + 2*z - 4*y(1, 2) - 4*y(1, 3) - 8*y(1, 4) >= 0 (2, 1) x(1, 2) - x(3, 2) + 2*z - 4*y(2, 2) - 4*y(2, 3) - 8*y(2, 4) >= 0
您可以创建不带任何循环的 const1
。
x = optimvar('x',3,2,'Type','integer','LowerBound',0,'UpperBound',1); y = optimvar('y',2,4); z = optimvar('z'); const1 = x(1,:) - x(3,:) + 2*z >= 4*(y(:,1) + y(:,3) + 2*y(:,4))'; show(const1)
(1, 1) x(1, 1) - x(3, 1) + 2*z - 4*y(1, 1) - 4*y(1, 3) - 8*y(1, 4) >= 0 (1, 2) x(1, 2) - x(3, 2) + 2*z - 4*y(2, 1) - 4*y(2, 3) - 8*y(2, 4) >= 0
提示
为了获得最佳性能,请将变量边界包含在变量定义中,而不是约束表达式中。此外,当您创建约束而不使用循环时,性能通常会提高。请参阅创建有效的优化问题。
小心
问题中的每个约束表达式必须使用相同的比较。例如,以下代码会导致错误,因为 cons1
使用 <=
比较,cons2
使用 >=
比较,而 cons1
和 cons2
在同一个表达式中。
prob = optimproblem; x = optimvar('x',2,'LowerBound',0); cons1 = x(1) + x(2) <= 10; cons2 = 3*x(1) + 4*x(2) >= 2; prob.Constraints = [cons1;cons2]; % This line throws an error
您可以通过为约束使用单独的表达式来避免此错误。
prob.Constraints.cons1 = cons1; prob.Constraints.cons2 = cons2;
优化变量具有句柄行为
另请参阅
optimvar
| show
| OptimizationConstraint
| OptimizationExpression