近期在做课设时设计到了一个优化问题,正好可以当作认识求解非线性问题的小案例。故尝试使用matlab求解。
仅供参考,官方的fmincon文档写的还是十分详细的。
关于整个问题的描述,相信能点进来的都不用多说了。(有空也可以补全。。)
还存在的问题:
① 待求解变量的初值对求解结果影响较大,同时,不同的求解器对结果也有影响。
② 初值随意取时,有可能会报错,原因未知。
Objective function is undefined at initial point. Fmincon cannot continue.
③ 代价函数设计的尚不合理
我仅仅是简单的对转角误差损失以及轴向力损失进行了归一化处理,但我认为需要根据实车的数据作为依据,来对各惩罚项进行加权。
代码如下
%main函数----------------------------------
x0 = [71,223]; %初始梯形底角和转向梯形臂长 x = [γ,m]
options = optimoptions('fmincon','Display','iter','Algorithm','interior-point');
%options = optimoptions('fmincon','Display','iter','Algorithm','sqp');
%options=optimset('largescale','off');
%x = fmincon(fun,x0,A,b,Aeq,beq,lb,ub,nonlcon,options)
%没有线性约束,因此将这些参数设置为[]
A = [];
b = [];
Aeq = [];
beq = [];
%设置边界
K = 1600;
m_min = 0.11 * K;
m_max = 0.15 * K;
lb = [70,m_min];
ub = [90,m_max];
[x,fval] = fmincon('getCost',x0,A,b,Aeq,beq,lb,ub,'getCon',options);
%---------------------------------------------
%getCon函数
function [c,ceq] = getCon(x) %约束函数
K=1600;
gamma=x(1)*pi/180;
m = x(2);
delta_min = 40*pi/180;
theta_o_max = 25.1*pi/180; %最小转弯半径对应的最大外侧车轮转角 对应式(3-24)
c = 2*m/K - ( cos(delta_min) - 2*cos(gamma) + cos(gamma+theta_o_max) )/( (cos(delta_min)-cos(gamma))*cos(gamma) );
ceq = [];
end
%---------------------------------------------
%getCost函数
function f = getCost(x)
L=3800;%轴距
K=1600;%主销轴线延长线与地面交点
G1 = 0.33 * 6650 * 9.8; %前轴载荷
gamma=x(1)*pi/180;%将布置角转化为弧度单位
m=x(2); %梯形臂长
for i=1:26
%梯形底角损失
theta_o(i) = i * pi/180; %自变量--外侧转角
N = sqrt((K/m)^2 + 1 - 2*(K/m)*cos(gamma + theta_o(i)));
theta_i_des = acot(cot(theta_o(i)) - (K/L)); %理论(期望)内侧转角
arcsin = asin(sin(gamma + theta_o(i)) / N);
arccos = acos( ((K/m)*(2*cos(gamma)-cos(gamma+theta_o(i))-cos(2*cos(gamma))))/N );
theta_i_act = gamma - arcsin - arccos; %实际内侧转角
c_gamma(i) = abs((theta_i_act - theta_i_des) / theta_i_des - 1);
%轴向力损失
FQ = 0.5*G1;
c_Fs(i) = FQ/(m*sin(gamma));
%加权
if theta_o(i) <= 10
c_gamma(i) = 1.5 * c_gamma(i);
c_Fs(i) = 1.5 * c_Fs(i);
elseif theta_o(i) > 20
c_gamma(i) = 0.5 * c_gamma(i);
c_Fs(i) = 0.5 * c_Fs(i);
else
c_gamma(i) = c_gamma(i);
c_Fs(i) = c_Fs(i);
end
end
%归一化
gamma_mean = mean(c_gamma);
gamma_var = var(c_gamma);
Fs_mean = mean(c_Fs);
Fs_var = var(c_Fs);
gamma_sum = 0;
Fs_sum = 0;
for i=1:26
gamma_sum = gamma_sum + ( c_gamma(i) - gamma_mean )/gamma_var;
Fs_sum = Fs_sum + ( c_Fs(i) - Fs_mean )/Fs_var;
end
f=gamma_sum + Fs_sum;%目标函数
end