How can I expedite the speed of fmincon optimization code

18 ビュー (過去 30 日間)
NooshinY
NooshinY 2017 年 11 月 16 日
コメント済み: Walter Roberson 2017 年 11 月 16 日
I use the following code to optimize my problem, I used 4 different function in my optim function, However it is too slow. I have been runing it from last night ( almost 16 hours) and it still calculated 9 iterations. What should I do to make it faster?
warning('off');
x0=[1;1;1]; % Starting guess
lb=[0.5;0.5;0.5];
ub=[1.25;1.27;4];
options = optimoptions('fmincon','outputfcn',@outfun,'Display','iter','Algorithm','interior-point','Tolx',1e-15,'Tolfun',1e-16,'MaxFunEvals',600,'MaxIter',100);
[x,fval,exitflag,output]=fmincon(@optim,x0,[],[],[],[],lb,ub,[],options)
And my optim function is as follow:
function f=optim(x)
%%%%%x1 H2 for com 12, x2 H2 for com34, x(3) is for interval
%tau=5;
%H1=0.00125;
alpha11=0.1;
alpha12=0.15;
H11=1.25;
H12=1.27;
CI=580;
Cp=3000;
Cr=2000;
for j=2:3 % number of intervals
t1(j-1)=j*x(3);
t2(j-1)=(j-1)*x(3);
Inspcost1(j-1)=MyF(x(1),x(2),t1(j-1));
Inspcost2(j-1)=MyF(x(1),x(2),t2(j-1));
Inspcostall(j-1)=j.*abs((Inspcost2(j-1)-Inspcost1(j-1)));
end
Inspcost=CI*sum(Inspcostall(j-1));%%%%%first item in numerator
for j=2:3
Downcost1(j-1)=abs(Inspcost2(j-1)-Inspcost1(j-1)); %%%%first part in downtime cost
Down211(j-1)=MyF(H11,H12,t1(j-1));
Down212(j-1)=MyF(H11,H12,t2(j-1));
Down21(j-1)= t1(j-1).*abs(Down212(j-1)-Down211(j-1)); %%%%(1) in second part in downtime cost
Down22(j-1)=abs(t1(j-1).*(1-Down211(j-1))-t2(j-1).*(1-Down212(j-1))); %%%%(2) in second part in downtime cost
end
for j=2:3
for m=1:3
Down23each(j-1,m)=IntF(H11,H12,m,t2(j-1),t1(j-1)); %%%%(3) in second part in downtime cost
end
end
for j=2:3
Down23(j-1)=sum(Down23each(j-1,:)); %%%%(3) in second part in downtime cost
Downcost2(j-1)=Down21(j-1)-Down22(j-1)+Down23(j-1); %%%%total second part in downtime cost
Downall1(j-1)=Downcost1(j-1).*Downcost2(j-1);
end
Downcost=Cp*sum(Downall1);
for j=2:3
Lencycle1(j-1)=t1(j-1).*abs((Inspcost2(j-1)-Inspcost1(j-1)));
end
Lenthcycle=sum(Lencycle1); %%%%%denominator
Totalcost=Inspcost+Downcost+Cr; %%%%total numerator
f=10*Totalcost/Lenthcycle;
  3 件のコメント
NooshinY
NooshinY 2017 年 11 月 16 日
They are not helpful. So I can find how long does it take for each function, so what??
Matt J
Matt J 2017 年 11 月 16 日
編集済み: Matt J 2017 年 11 月 16 日
So, once you know where the bottleneck is, you know what part of the code you need to work on and make more efficient. How can you begin to solve a problem if you don't know where it is coming from?

サインインしてコメントする。

採用された回答

Steven Lord
Steven Lord 2017 年 11 月 16 日
1.
warning('off');
Please don't do this. We don't make code warn simply because we want to show some text. We intend / hope that the warnings alert you to potential problems in your code or ways to improve the behavior and/or the performance of your code.
If you have reviewed a particular warning, understand it, and know that you can safely ignore it I would silence that particular warning using its identifier.
2.
Inspcost1(j-1)=MyF(x(1),x(2),t1(j-1));
What is MyF? If it is your own function, how complicated is it?
3.
Down23each(j-1,m)=IntF(H11,H12,m,t2(j-1),t1(j-1)); %%%%(3) in second part in downtime cost
What is IntF? How complicated is it?
4.
I agree with Stephen's and Matt's suggestions to profile your code. If you can start another session of MATLAB on your machine (leaving your optimization in progress) profile this line of code:
y = optim(x0);
Use the information the profiler gives you to identify the bottlenecks. Also open your code in the MATLAB Editor and see if any of the orange Code Analyzer messages are located where the bottlenecks are. If they are, they may offer guidance on how to improve the performance of that bottleneck.
  2 件のコメント
NooshinY
NooshinY 2017 年 11 月 16 日
編集済み: NooshinY 2017 年 11 月 16 日
I used this code and the time for my function That I want to minimize for the starting point is:t =1.150404545586179e+02*
foo=@()optim([1.2;1;1]);
t=timeit(foo)
Steven Lord
Steven Lord 2017 年 11 月 16 日
So one call to your objective function takes almost 2 minutes. Repeat that call in the Profiler to identify what parts of that function takes the most time. If MyF or IntF is the bottleneck, look at the information the Profiler shows for them to see what part of those functions takes the longest.
If you can identify a particular small (no more than 15-20 lines, ideally) segment of code as your bottleneck that's more or less self contained, post it and describe what it's supposed to do and you may receive some suggestions on how to improve the performance of that code.

サインインしてコメントする。

その他の回答 (1 件)

Walter Roberson
Walter Roberson 2017 年 11 月 16 日
Sometimes (definitely not always), if you have the Symbolic Toolbox, you can pass a symbolic vector to your optimization routine and get back a single formula that calculates the value. Then you can simplify() the formula. Sometimes the resulting formula is faster to calculate than going through all of the code steps.
A step after that is to use matlabFunction and ask it to write the formula to a file and leave the default optimize option on: the resulting .m file should calculate the formula efficiently, having done sub-expression optimization. In the case of longer expressions, the optimization of the formula can take a fair bit of time (over half an hour) so it is not always worth doing unless the code is going to be executed a lot; I suggest that the first time around that you tell matlabFunction to write to a file, that you tell it to turn off optimization.
  2 件のコメント
NooshinY
NooshinY 2017 年 11 月 16 日
I am sorry, But I didn't get what should exactly do?
Walter Roberson
Walter Roberson 2017 年 11 月 16 日
X = sym('X', [3 1]);
Fsym = optim(X);
The above might fail, depending on what you do inside the functions that you did not post. If it works, then
Fsymopt = simplify(Fsym);
f = matlabFunction(Fsymopt, 'vars', {X}, 'File', 'F.m', 'Optimize', false);
If that works, then you can
foo = @()f([1.2;1;1]);
t=timeit(foo)
and see whether you got a speed increase.
The step after that would be to try
fopt = matlabFunction(Fsymopt, 'vars', {X}, 'File', 'Fopt.m', 'Optimize', true);
which might potentially take a fair amount of time. When it finishes then you can
foo = @()fopt([1.2;1;1]);
t=timeit(foo)
and see if you improved.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeLinear Least Squares についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by