[問題] 請教fmincon的梯度用法已回收

看板MATLAB作者 (totomomo)時間15年前 (2009/02/11 17:30), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串1/1
目的: 使用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
文章代碼(AID): #19afh6qj (MATLAB)