[問題] 請教fmincon的梯度用法已回收
目的: 使用fmincon來求解非線性最佳化且有限制條件的問題
變數: 多變數(1~100個以上)
問題描述:
小弟目前遭遇到的問題是, 在解20個變數的時候, 不用提供梯度函數的話可以很快解
出來,
但是在解100個變數上若沒有提供梯度函數, 計算時間會變的很長, 大約3個小時以上. 而
目前
遇到的問題是該如何在objective function與constraint function之下算梯度?詳細程式
如下:
主程式:
options.MaxFunEvals = 1e10;
options.TolCon = 1e-10;
options.Tolfun = 1e-10;
options.TolX = 1e-10;
options =
optimset('LargeScale','on','display','off','GradObj','on','GradConstr','on');
[x,fval,exitflag,output] =
fmincon(@(x)ar_obj(x,objfun),x0,[],[],[],[],[],[],@(x)ar_con(x,objfun),options)
說明: objfun是我丟進去的結構,內部儲存的是常數, 目的是為了計算objective
function.
% ===== Objective Function ===== %
function f = ar_obj(x,objfun)
C_matrix = objfun{5};
R_matrix = objfun{4};
Pininfo = objfun{3};
Modinfo = objfun{2};
[t1 t2] = size(R_matrix); % t1: # of modules; t2-t1:: # of pins
tmp_fun = 0;
for m=1:t1
for n=m+1:t2
if n > t1;
radius_m = Modinfo(m).Radius;
tmp_pinx = Pininfo(n-t1).coor_xy(1);
tmp_piny = Pininfo(n-t1).coor_xy(2);
dij = ((x(2*m-1)-tmp_pinx)^2.0 + (x(2*m)-tmp_piny)^2.0 + 1.0);
cij = C_matrix(m,n);
tmp_var = cij*(dij)^0.5;
tmp_fun = tmp_fun + tmp_var;
else n <= t1;
radius_m = Modinfo(m).Radius;
radius_n = Modinfo(n).Radius;
dij = sqrt((x(2*m-1)-x(2*n-1))^2.0 + (x(2*m)-x(2*n))^2.0 + 1.0);
cij = C_matrix(m,n);
pij = radius_m + radius_n - (dij);
sij = ((radius_m)^2.0)*((radius_n)^2.0);
if pij >= 0;
tmp_var = cij*(dij) + (sij)*(pij)/(dij);
tmp_fun = tmp_fun + tmp_var;
else pij < 0;
tmp_var = cij*(dij) + ((pij))/(dij);
tmp_fun = tmp_fun + tmp_var;
end
end
end
end
f = tmp_fun;
if nargout > 1;
for k=1:t1; % 2倍的t1為變數數量
Grad(2*k-1,1) = (diff(tmp_fun,x(2*k-1)));
Grad(2*k,1) = (diff(tmp_fun,x(2*k)));
end
end
% ===== Constraint Function ===== %
function [c,ceq] = ar_con(x,objfun)
C_matrix = objfun{5};
R_matrix = objfun{4};
Pininfo = objfun{3};
Modinfo = objfun{2};
Chipinfo = objfun{1};
[t1 t2] = size(R_matrix);
tt = 4*t1;
for i=1:t1
c(4*i-3) = x(2*i-1) + Modinfo(i).Radius - Chipinfo.Boundary(1);
c(4*i-2) = Modinfo(i).Radius - x(2*i-1) ;
c(4*i-1) = x(2*i) + Modinfo(i).Radius - Chipinfo.Boundary(2);
c(4*i) = Modinfo(i).Radius - x(2*i) ;
end
ceq = [];
if nargout > 2; % 依照constraints所計算的梯度
for j=1:t1;
Grad_c(1,4*j-3) = (diff(c(4*i-3),x(2*j-1)));
Grad_c(2,4*j-3) = (diff(c(4*i-3),x(2*j)));
Grad_c(1,4*j-2) = (diff(c(4*i-2),x(2*j-1)));
Grad_c(2,4*j-2) = (diff(c(4*i-2),x(2*j)));
Grad_c(1,4*j-1) = (diff(c(4*i-1),x(2*j-1)));
Grad_c(2,4*j-1) = (diff(c(4*i-1),x(2*j)));
Grad_c(1,4*j) = (diff(c(4*i),x(2*j-1)));
Grad_c(2,4*j) = (diff(c(4*i),x(2*j)));
end
Grad_ceq = [];
end
目前遭遇到的主要問題是, 當我把梯度計算加入後, 會出現以下的錯誤訊息.
??? Error using ==> fmincon at 512
FMINCON cannot continue because user supplied objective function failed with
the following error:
Subscripted assignment dimension mismatch.
Error in ==> AR_modelL>AR_run at 39
[x,fval,exitflag,output] =
fmincon(@(x)ar_obj(x,objfun),x0,[],[],[],[],[],[],@(x)ar_con(x,objfun),options);
在沒有加入梯度之下的程式是沒有問題的, 可以跑出結果來. 但如前所述在跑變數數量
100~1000以上時,會花費很多時間. 在此想請教板上的高手, 是不是小弟所寫的梯度計算出了
問題, 希望板上的高手能指點一番. m(_ _)m
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.116.156.28