最近在做方程組的非線性優化問題,用到了fgoalattain函數,總結一下:
- 意義
解決多目標的非線性優化問題 - 函數形式
函數表示形式如下:
上式中,weight, goal, b和beq 是向量(組),A 和Aeq 是矩陣, c(x), ceq(x)和F(x) 返回值爲向量的函數,函數可以是非線性的,x, lb, ub 可以以向量或者矩陣的形式傳遞或者表示; - 在不同場景下的語法形式
x = fgoalattain(fun,x0,goal,weight)
x = fgoalattain(fun,x0,goal,weight,A,b)
x = fgoalattain(fun,x0,goal,weight,A,b,Aeq,beq)
x = fgoalattain(fun,x0,goal,weight,A,b,Aeq,beq,lb,ub)
x = fgoalattain(fun,x0,goal,weight,A,b,Aeq,beq,lb,ub,nonlcon)
x = fgoalattain(fun,x0,goal,weight,A,b,Aeq,beq,lb,ub,nonlcon,options)
x = fgoalattain(problem)
[x,fval] = fgoalattain(...)
[x,fval,attainfactor] = fgoalattain(...)
[x,fval,attainfactor,exitflag] = fgoalattain(...)
[x,fval,attainfactor,exitflag,output] = fgoalattain(...)
[x,fval,attainfactor,exitflag,output,lambda] = fgoalattain(...)
- 描述
x = fgoalattain(fun,x0,goal,weight) 的作用是使函數fun提供的目標函數通過改變x的值來實現goal指定的目標,x的數值從x0開始,權重由weight指定;
x = fgoalattain(fun,x0,goal,weight,A,b) 的作用是解決線性不等式A*x ≤ b的目標優化問題;
x = fgoalattain(fun,x0,goal,weight,A,b,Aeq,beq) 的作用是解決線性等式Aeq * x = beq的目標優化問題。 如果不存在不等式,則通過指定設置A = []和b = []的形式進行填充。
x = fgoalattain(fun,x0,goal,weight,A,b,Aeq,beq,lb,ub) 的作用是在以上式子的基礎上,在x中的設計變量上定義了一組下限和上限,因此解決方案始終在lb≤x≤ub的範圍內。
x = fgoalattain(fun,x0,goal,weight,A,b,Aeq,beq,lb,ub,nonlcon) 的作用是將目標優化問題置於nonlcon參數中定義的非線性不等式c(x)或非線性等式ceq(x)。 fgoalattain優化使得c(x)≤0且ceq(x)= 0.如果不存在邊界,則設置lb = []或ub = [];
x = fgoalattain(fun,x0,goal,weight,A,b,Aeq,beq,lb,ub,nonlcon,options)的作用是通過options中指定的優化選項進行最小化優化,選項設置可以使用optimoptions;
x = fgoalattain(problem) 的作用是找到問題(problem)的最小值,其中問題是輸入參數中描述的結構;其中我們可以通過從Optimization應用程序導出的問題來創建問題結構;
[x,fval] = fgoalattain(...) 返回在解x的過程中fun計算的目標函數的值;
[x,fval,attainfactor] = fgoalattain(...) 返回解x處的目標達到因子;
[x,fval,attainfactor,exitflag] = fgoalattain(...)返回exitflag參數,描述計算的退出條件;
[x,fval,attainfactor,exitflag,output] = fgoalattain(...)返回包含優化信息的輸出參數output;
[x,fval,attainfactor,exitflag,output,lambda] = fgoalattain(...) 返回包含拉格朗日乘子的lambda參數。
-
函參詳解
<1>. fun:要進行優化的函數;
fun是一個接受向量x並返回向量F的函數,在x處計算目標函數, fun可以通過函數文件的函數句柄進行指定;例如x = fgoalattain(@myfun,x0,goal,weight)
,其中,myfun就是MATLAB中的函數比如 :function F = myfun(x); F = ...
,fun也可以是匿名函數的函數句柄,比如x = fgoalattain(@(x)sin(x.*x),x0,goal,weight)
,其中的sin函數就是匿名函數;如果x和F的用戶定義值是數組,則系統會使用線性索引將它們轉換爲向量。
爲了使目標函數儘可能接近目標值(即,既不大於也不小於),使用優化將EqualityGoalCount選項設置爲需要在目標值附近的目標數量。 必須將這些目標劃分爲fun返回的向量F的第一個元素。
如果也可以計算目標函數的梯度,並且SpecifyObjectiveGradient選項爲true,則設置爲options = optimoptions('fgoalattain','SpecifyObjectiveGradient',true)
,那麼函數fun必須在第二個輸出參數中返回梯度值G,即x處的矩陣。 梯度由點x處的每個F的偏導數dF/dx組成。 如果F是長度爲m且x長度爲n的向量,其中n是x0的長度,則F(x)的梯度G是n×m矩陣,其中G(ij)是偏導數 F(j)相對於x(i)(即第j列的第j列是第j個目標函數F(j)的梯度)。
<2>. goal:目標需要努力達到的向量的值。
其中向量的長度與fun返回的目標向量F相同,fgoalattain嘗試最小化向量F中的值以達到goal給出的目標值。
<3>. nonlcon:計算約束條件中非線性不等式c(x)≤0和非線性等式ceq(x)= 0的函數;
函數nonlcon接受向量x並返回兩個向量c和ceq。 向量c包含在含有x的非線性不等式中,並且ceq包含在含有x的非線性等式中。 函數nonlcon可以通過函數句柄進行指定,比如x = fgoalattain(@myfun,x0,goal,weight,A,b,Aeq,beq,.. lb,ub,@mycon)
,其中mycon就是nonlcon的函數,示例如下:function [c,ceq] = mycon(x) c = ... % compute nonlinear inequalities at x. ceq = ... % compute nonlinear equalities at x.
<4>. options: 提供選項值的功能特定詳細信息。
<5>. weight: 加權矢量用於控制fgoalattain中目標的相對不足或超額數值。 當目標值全部爲非零時,爲了確保活動目標的低於或超過相同百分比,將加權函數設置爲abs(goal);
當加權函數權重爲正時,fgoalattain會嘗試使目標小於目標值。 要使目標函數大於目標值,請將權重設置爲負值而不是正值。 要使目標函數儘可能接近目標值,請使用EqualityGoalCount選項並將該目標作爲fun返回的向量的第一個元素(請參閱前面的fun和options描述)。
<6>. problem:
目標:目標函數的向量;
x0:x的初始點;
goal:需要實現的目標;
weight:目標的相對重要性因素;
Aineq:線性不等式約束的矩陣;
bineq:線性不等式約束的向量;
Aeq:用於線性等式約束的矩陣;
beq:線性等式約束的向量;
lb:下界矢量;
ub:上界矢量;
nonlcon:非線性約束函數;
solve:‘fgoalattain’;
options:使用optimoptions創建的選項; -
返回值詳解
<1>. attainfactor: 表徵目標的過度或不足的程度。
achiefactor包含解決方案中γ的值。 如果attainfactor是負的,那麼設定的目標類似於過擬合; 如果attainfactor是正的,設定的目標便欠擬合。
<2>. exitflag : 整數標識算法終止的原因。 以下列出了exitflag的值以及算法終止的相應原因。
1:函數收斂到解x。
4:搜索方向的幅度小於指定的容差和約束違規小於options.ConstraintTolerance
5:方向導數的幅度小於指定的容差和約束違規小於options.ConstraintTolerance
0:迭代次數超出options.MaxIterations或函數評估次數超出options.MaxFunctionEvaluations
-1:由輸出功能或繪圖功能停止。
-2:找不到可行點。
<3>. lambda :在解x中包含拉格朗日乘數的結構(由約束類型分隔)。 結構的範圍是:
lower:下限lb
upper:上限ub
ineqlin:線性不等式
eqlin:線性均衡
ineqnonlin:非線性不等式
eqnonlin:非線性等式
<4>. output : 包含有關優化的信息的結構。 結構的範圍是:
iterations:迭代次數
funcCount:函數評估的數量
lssteplength:相對於搜索方向的最終行搜索步驟的大小
stepize:x中的最終位移
algorithm :使用的優化算法
firstorderopt:一階最優性的度量
constrviolation:約束函數的最大值
message :退出消息 -
應用案例
某工廠因生產需要欲採購一種原材料,市場上的這種原料有兩個等級,甲級單價2元/千克,乙級單價1元/千克。要求所花總費用不超過200元,購得原料總量不少於100千克,其中甲級原料不少於50千克,問如何確定最好的採購方案。
設x1、x2分別爲採購甲級和乙級原料的數量(千克),要求採購總費用盡量少,採購總重量儘量多,採購甲級原料儘量多。由題意可得:
首先需要編寫目標函數的M文件lwj.m,返回目標計算值:
function f=myfun(x)
f(1)=2*x(1)+ x(2); % f(1)表示的是原料採購總費用
f(2)=-x(1)- x(2); % f(2)表示的是採購總重量
f(3)=-x(1); % f(3)甲級原料的總質量
給定目標,權重按目標比例確定,給出初值:
在這裏要注意的地方時,fgoalattain函數以最小優化爲目的,所以目標函數的數值目標(也就是下邊的goal)是≤的時候,係數爲+,目標函數是≥的時候,係數爲-;
goal=[200 –100 -50]; %goal中的數據表示f(1),f(2),f(3)各自的目標數值;
weight=[2040 –100 -50]; %權重中的數值意義同上
x0=[55 55]; %初始值x0可自己隨意按照符合條件的數值進行設定【不是真的隨心所欲】,此處55和55符合條件;
給出約束條件的係數:
A=[2 1;-1 –1;-1 0]; % 此處3*2矩陣A中的數值是目標函數的係數矩陣
b=[200 -100 -50]; % 目標函數結果的矩陣
lb=zeros(2,1); %限定條件
調用:
[x,fval,attainfactor,exitflag] =fgoalattain(@lwj,x0,goal,weight,A,b,[],[],lb,[]); % 函數調用
輸出計算結果:
x =
50 50
fval =
150 -100 -50
attainfactor =
1.3235e-023
exitflag =
1
所以,最好的採購方案是採購甲級原料和乙級原料各50千克。此時採購總費用爲150元,總重量爲100千克,甲級原料總重量爲50千克。