二変数関数f(x, y)が最大最小となるx, yを求める方法

f = 0.5 * x - 10 * (x / (x + y))
x >= 0
y >= 0
0 <= (x / (x + y)) <= 1
このときfが最大となるx, yの値,fが最小となるx, yの値を求めることはできますでしょうか.

2 Comments

Hiroyuki Hishida
Hiroyuki Hishida on 24 Nov 2021
できますが、この問題はあってますでしょうか?
xが0以上(の実数)yが0以上の実数とした場合、3つ目の条件式は(x, y) = (0,0)以外成立しますが、これは意図通りでしょうか?
Miccchiyo
Miccchiyo on 24 Nov 2021
Hiroyuki Hishida さま,返信ありがとうございます.
3つめの条件式は意図通りですが確かに(x, y)=(0, 0)以外は成立しますので,無視していただければと思います.
恐れ入りますがよろしくお願いいたします.

Sign in to comment.

 Accepted Answer

Hiroyuki Hishida
Hiroyuki Hishida on 24 Nov 2021

0 votes

Miccchiyo様の環境がわかりませんが、MATLAB 関数 最大とかでGoogleすると以下のページがでてきますが、いかがでしょうか?
関数を見るとx,yが大きくなればなるほどfは単調増加するように見えるのですが、問題はこれで良いのでしょうか?

4 Comments

Miccchiyo
Miccchiyo on 25 Nov 2021
返信ありがとうございます,また質問が要領を得ておらず申し訳ございません.
fは,x, yが小さいときは単調増加にならないようなので,fが最小となるときのxとyを求めたいと考えております.
syms parm1 parm2 x y
param1 = 0.5*x
param2 = -10*(x/(x+y))
f = param1 + param2
fsurf(f, [0 50 0 50])
このときfsurfの出力結果からは,f(x, y)はいったん減少して,そのあと単調増加しているように見えております.ですので「最大」につきましては,min(f(x, y))よりもx, yが大きければ,x, yの増加に従ってf(x, y)も大きくなるのだと見込んでおりますが,「最小」につきましては正確な値を導出できずに悩んでおります.
自分でも「多変数」「最小」などで検索し演算を試しているのですが,うまくいっておりません.
Miccchiyo様、
試してみましたが、Symbolicで解くと、最後の条件わけのが面倒かと思われます。
syms f(x,y) x y
f(x,y) = 0.5*x -10*(x/(x+y));
figure;
fsurf(f, [0 5 0 5]);
title('f(x,y)')
%最小値の計算
%https://jp.mathworks.com/help/symbolic/maxima-minima-and-inflection-points.html
%実数であると仮定
assume(x, 'real');
assume(y, 'real');
assume(x>0);
assume(y>0);
%1 次導関数
dfx = diff(f, x);
dfy = diff(f, y);
%これは解がない
ansx = solve(dfy == 0, x, 'ReturnConditions',true);
%こっちは解がある
ansy = solve(dfx == 0, y, 'ReturnConditions',true);
extrema = vpa(ansy.y);
g1 = extrema(1, 1);
g2 = extrema(2, 1);
figure;
subplot(1,2,1)
fplot(g1)
title('dfx=0になるようなy=g(x)その1')
subplot(1,2,2)
fplot(g2)
title('dfx=0になるようなy=g(x)その2')
離散的に解くのであれば、総当たり計算させるなどで解くことができます。以下は、vで指定した刻み幅でx, yの値を振って、関数が最小になるときのxyを求めています。vの値を変えると計算結果は多少変わります。
%変数確保
v = 0.0001;
x= 0: v: 2;
y= 0: v: 2;
%計算結果の確保
f=zeros(length(x));
for i=1:length(x)
for j=1:length(y)
if i+j>0
f(i,j) = 0.5*x(i) -10*(x(i)/(x(i)+y(j)));
end
end
end
%最小値
[minV, minID] = min(f, [], 'all');
xvid=rem(minID, length(x));
yvid=(minID-xvid) / length(x)+1;
disp(x(xvid));
1.0000e-04
disp(y(yvid));
0
いかがでしょうか?
補足しますと、制約条件のついた最適化問題ですので、もしSymbolicで解かれたいのであれば、問題に応じた式変形が必要です。Optimization Toolboxを使用するとそのあたりをうまい具合に処理してくれます。以下のやり方では制約条件の3番が、若干上記とは異なりますが、参考になれば幸いです。
%https://jp.mathworks.com/help/optim/ug/solve-constrained-nonlinear-optimization-problem-based.html
%変数宣言
x = optimvar('x');
y = optimvar('y');
%最適化変数の式として目的関数を作成します。
obj = objfunx(x,y);
f =
Nonlinear OptimizationExpression ((0.5 .* x) - (10 .* (x ./ (x + y))))
%obj を目的関数として使用して最適化問題を作成します。
prob = optimproblem('Objective',obj);
%制約条件
con1 = x>= 0;
con2 = y>= 0;
con3 = x*y>=0;
prob.Constraints.constr1 = con1;
prob.Constraints.constr2 = con2;
prob.Constraints.constr3 = con3;
%初期点
x0.x = 1;
x0.y = 1;
%%問題の確認
% show(prob);
%解く
[sol,fval] = solve(prob,x0)
Solving problem using fmincon. Feasible point with lower objective function value found. Local minimum possible. Constraints satisfied. fmincon stopped because the size of the current step is less than the value of the step size tolerance and constraints are satisfied to within the value of the constraint tolerance.
sol = struct with fields:
x: 0.0064 y: 1.0275e-06
fval = -9.9952
%% 目的関数
function f = objfunx(x,y)
f = 0.5 * x - 10 * (x ./ (x + y))
end
Hiroyuki Hishida さま
ご丁寧にありがとうございます.
頂いたサンプルコードが,全て手元の環境で動作することを確認しました.
どの方法がよいかは別途検討させて頂きます.
参考になりました,本当にありがとうございました!
※補足※
手元の環境R2020aでは最小値minのところでエラーが発生しましたが,R2021bを利用することでエラーが解消しました.
%最小値
[minV, minID] = min(f, [], 'all');

Sign in to comment.

More Answers (0)

Categories

Find more on Financial Toolbox in Help Center and File Exchange

Products

Release

R2020a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!