最適化式
最適化式とは
最適化式は、最適化変数の多項式結合または有理結合です。
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
にそのように認識させるには、expr'*expr
ではなく sum(expr.^2)
と記述します。内部パーサーは、明示的な二乗和のみを認識します。例については、非負の線形最小二乗法、問題ベースを参照してください。
制約の式と方程式
制約は、==
、<=
、>=
のいずれかの比較演算子を含む 2 つの "比較可能な式" です。方程式は、比較演算子 ==
を使用する 2 つの比較可能な式です。比較可能な式は同じサイズであるか、または一方の式がスカラー、つまり、サイズが 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 列です。ここでも、z
がスカラー変数であるため、y
は z
と比較可能です。
constr3 = (sum(x,1))' <= sum(y,2);
sum(x,1)
のサイズは 1 行 2 列であるため、(sum(x,1))'
のサイズは 2 行 1 列です。sum(y,2)
のサイズは 2 行 1 列であるため、この 2 つの式は比較可能です。
メモ
多項式、有理式、および初等関数 (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
また、問題を作成するときに制約や方程式を含めることもできます。たとえば、合計が 1 を超えない正の変数が 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;
最適化変数のハンドル動作
OptimizationVariable
オブジェクトには、"ハンドル" コピー動作があります。詳細については、ハンドル オブジェクトの動作とハンドル クラスと値クラスの比較を参照してください。ハンドル コピー動作とは、OptimizationVariable
のコピーがオリジナルを指しており、独立して存在していないことを意味します。たとえば、変数x
を作成し、それをy
にコピーして、y
のプロパティを設定します。x
に新しいプロパティ値が反映される点に注意してください。x = optimvar('x','LowerBound',1); y = x; y.LowerBound = 0; showbounds(x)
0 <= x
参考
optimvar
| show
| OptimizationConstraint
| OptimizationExpression