优化问题 - GlobalSearch 未在 MATLAB 中生成初始向量
Optimization problem - GlobalSearch is not generating initial vector in MATLAB
简介
我要解决优化问题,包含一组常微分方程。更重要的是我需要找到 global 最小值。到目前为止,我只设法找到了几个局部最小值,但是对于如此复杂的问题,手动检查哪个是全局最小值是很棘手的。
描述
假设我有 3 个 Matlab 文件:
Main.m
- 它是通用脚本文件,它是所有其他文件的驱动程序
ODE_set.m
- 这包含我所有的 ODE 系统
Opt_query.m
- 这包含优化目标的定义,以及确定最小值所需的所有方程式。也从这个文件启动 ODE 求解器。
我可以用这段代码寻找局部最小值,它工作得很好,没有任何错误:
Main.m
global k1 k2 k3
x0 = [0.5 8 13];
lu =[ 0.9 25.74 60.9];
lb =[ 0.1 0.74 0.9];
[k,fval,exitflag,output] = fmincon('Opt_query',x0,[],[],[],[],lb,lu);
disp(k1)
disp(k2)
disp(k3)
然而,正如我上面提到的,我需要全局最小值,所以我开始尝试 GlobalSearch
。这是我的代码:
x0 = [0.5 8 13];
lu =[ 0.9 25.74 60.9];
lb =[ 0.1 0.74 0.9];
gs = GlobalSearch;
problem = createOptimProblem('fmincon',Opt_query,x0,[],[],[],[],lb,lu);
[x,fval,exitflag,output] = run(gs,problem);
以一个错误结束:
Not enough input arguments.
Error in Opt_query (line 3)
k1 = p(1)
这里是Opt_query.m
的结构:
function q = Opt_query(p)
global k1 k2 k3
k1 = p(1)
k2 = p(2)
k3 = p(3)
y0=[1 2 3]
[t,y] = ode45(@ODE_set,[0, 130],y0,k1,k2,k3)
t_steps=0:5:130;
y_steps=interp1(t,y,t_steps);
for j = 1:27
Z = Z+ abs(y_steps(j,1)-5)+abs(y_steps(j,2)-7)+abs(y_steps(j,3)-9);
end
q = sqrt(Z);
end
这里是ODE_set.m
的结构:
function dydt = ODE_set(t, y, k1, k2, k3)
F = 20.1;
A_in = 2.5;
V = 100;
k = 0.150;
A = y(1);
B = y(2);
C = y(3);
n = numel(y);
dydt = zeros(n,1);
dydt(1) = F/V*(A_in - A) - k1*A^2;
dydt(1) = F/V*(B) - k2*B^2;
dydt(1) = F/V*(C) - k3*C^2;
问题
所以我的问题是 - 为什么当我单独使用 fmincon
时,它工作正常,但是当使用 GlobalSearch
启动时它不会生成初始 p
向量来保存参数优化?我是不是漏掉了什么,或者 GlobalSearch
需要不同的语法?
失误少
在Opt_query
中更改此
[t,y] = ode45(@ODE_set,[0, 130],y0,k1,k2,k3);
到这个
[t,y] = ode45(@(t,y)ODE_set(t,y, k1, k2, k3),[0, 130],y0);
After tspan = [0,30]
you should only use the initial conditions, do
not include k1, k2, k3
- 只需使用具有
5 inputs t,y, k1, k2, k3
的函数 ODE_set
用两个输入创建一个新的 t , y
然后 k1, k2, k3
将被保留
作为固定输入
new_ODE_set = @(t, y)ODE_set(t, y, k1, k2, k3)
- 这是 ode45 的语法
[t,y] = ode45(odefun,tspan,y0)
odefun
仅是 t, y
的函数
因为 new_ODE_set
也是 t, y
的函数,所以现在可以用作
odefun
但其实里面还有k1, k2, k3
for j = 1:27
Z = Z+ abs(y_steps(j,1)-5)+abs(y_steps(j,2)-7)+abs(y_steps(j,3)-9);
end
Here you should initialize Z
to zero before running the loop, like
this
Z = 0;
for j = 1:27
Z = Z+ abs(y_steps(j,1)-5)+abs(y_steps(j,2)-7)+abs(y_steps(j,3)-9);
end
In ODE_set
you're only using index 1
for dydt
改变这个
dydt(1) = F/V*(A_in - A) - k1*A^2;
dydt(1) = F/V*(B) - k2*B^2;
dydt(1) = F/V*(C) - k3*C^2;
到这个
dydt(1) = F/V*(A_in - A) - k1*A^2;
dydt(2) = F/V*(B) - k2*B^2;
dydt(3) = F/V*(C) - k3*C^2;
总结
Main.m
global k1 k2 k3
x0 = [0.5 8 13];
lu =[ 0.9 25.74 60.9];
lb =[ 0.1 0.74 0.9];
gs = GlobalSearch;
problem = createOptimProblem('fmincon','objective',...
@Opt_query,'x0',x0,'lb',lb,'ub',lu);
[x,fval,exitflag,output] = run(gs,problem);
disp(k1)
disp(k2)
disp(k3)
ODE_set.m
function dydt = ODE_set(t, y, k1, k2, k3)
F = 20.1;
A_in = 2.5;
V = 100;
k = 0.150;
A = y(1);
B = y(2);
C = y(3);
n = numel(y);
dydt = zeros(n,1);
dydt(1) = F/V*(A_in - A) - k1*A^2;
dydt(2) = F/V*(B) - k2*B^2;
dydt(3) = F/V*(C) - k3*C^2;
end
Opt_query.m
function q = Opt_query(p)
global k1 k2 k3
k1 = p(1);
k2 = p(2);
k3 = p(3);
y0=[1 2 3];
[t,y] = ode45(@(t,y)ODE_set(t,y, k1, k2, k3),[0, 130],y0);
t_steps=0:5:130;
y_steps=interp1(t,y,t_steps);
Z = 0;
for j = 1:27
Z = Z+ abs(y_steps(j,1)-5)+abs(y_steps(j,2)-7)+abs(y_steps(j,3)-9);
end
q = sqrt(Z);
end
简介
我要解决优化问题,包含一组常微分方程。更重要的是我需要找到 global 最小值。到目前为止,我只设法找到了几个局部最小值,但是对于如此复杂的问题,手动检查哪个是全局最小值是很棘手的。
描述
假设我有 3 个 Matlab 文件:
Main.m
- 它是通用脚本文件,它是所有其他文件的驱动程序ODE_set.m
- 这包含我所有的 ODE 系统Opt_query.m
- 这包含优化目标的定义,以及确定最小值所需的所有方程式。也从这个文件启动 ODE 求解器。
我可以用这段代码寻找局部最小值,它工作得很好,没有任何错误:
Main.m
global k1 k2 k3
x0 = [0.5 8 13];
lu =[ 0.9 25.74 60.9];
lb =[ 0.1 0.74 0.9];
[k,fval,exitflag,output] = fmincon('Opt_query',x0,[],[],[],[],lb,lu);
disp(k1)
disp(k2)
disp(k3)
然而,正如我上面提到的,我需要全局最小值,所以我开始尝试 GlobalSearch
。这是我的代码:
x0 = [0.5 8 13];
lu =[ 0.9 25.74 60.9];
lb =[ 0.1 0.74 0.9];
gs = GlobalSearch;
problem = createOptimProblem('fmincon',Opt_query,x0,[],[],[],[],lb,lu);
[x,fval,exitflag,output] = run(gs,problem);
以一个错误结束:
Not enough input arguments.
Error in Opt_query (line 3)
k1 = p(1)
这里是Opt_query.m
的结构:
function q = Opt_query(p)
global k1 k2 k3
k1 = p(1)
k2 = p(2)
k3 = p(3)
y0=[1 2 3]
[t,y] = ode45(@ODE_set,[0, 130],y0,k1,k2,k3)
t_steps=0:5:130;
y_steps=interp1(t,y,t_steps);
for j = 1:27
Z = Z+ abs(y_steps(j,1)-5)+abs(y_steps(j,2)-7)+abs(y_steps(j,3)-9);
end
q = sqrt(Z);
end
这里是ODE_set.m
的结构:
function dydt = ODE_set(t, y, k1, k2, k3)
F = 20.1;
A_in = 2.5;
V = 100;
k = 0.150;
A = y(1);
B = y(2);
C = y(3);
n = numel(y);
dydt = zeros(n,1);
dydt(1) = F/V*(A_in - A) - k1*A^2;
dydt(1) = F/V*(B) - k2*B^2;
dydt(1) = F/V*(C) - k3*C^2;
问题
所以我的问题是 - 为什么当我单独使用 fmincon
时,它工作正常,但是当使用 GlobalSearch
启动时它不会生成初始 p
向量来保存参数优化?我是不是漏掉了什么,或者 GlobalSearch
需要不同的语法?
失误少
在Opt_query
中更改此
[t,y] = ode45(@ODE_set,[0, 130],y0,k1,k2,k3);
到这个
[t,y] = ode45(@(t,y)ODE_set(t,y, k1, k2, k3),[0, 130],y0);
After
tspan = [0,30]
you should only use the initial conditions, do not includek1, k2, k3
- 只需使用具有
5 inputs t,y, k1, k2, k3
的函数ODE_set
用两个输入创建一个新的t , y
然后k1, k2, k3
将被保留 作为固定输入
new_ODE_set = @(t, y)ODE_set(t, y, k1, k2, k3)
- 这是 ode45 的语法
[t,y] = ode45(odefun,tspan,y0)
odefun
仅是 t, y
的函数
因为
new_ODE_set
也是t, y
的函数,所以现在可以用作odefun
但其实里面还有
k1, k2, k3
for j = 1:27
Z = Z+ abs(y_steps(j,1)-5)+abs(y_steps(j,2)-7)+abs(y_steps(j,3)-9);
end
Here you should initialize
Z
to zero before running the loop, like this
Z = 0;
for j = 1:27
Z = Z+ abs(y_steps(j,1)-5)+abs(y_steps(j,2)-7)+abs(y_steps(j,3)-9);
end
In
ODE_set
you're only using index1
fordydt
改变这个
dydt(1) = F/V*(A_in - A) - k1*A^2;
dydt(1) = F/V*(B) - k2*B^2;
dydt(1) = F/V*(C) - k3*C^2;
到这个
dydt(1) = F/V*(A_in - A) - k1*A^2;
dydt(2) = F/V*(B) - k2*B^2;
dydt(3) = F/V*(C) - k3*C^2;
总结
Main.m
global k1 k2 k3
x0 = [0.5 8 13];
lu =[ 0.9 25.74 60.9];
lb =[ 0.1 0.74 0.9];
gs = GlobalSearch;
problem = createOptimProblem('fmincon','objective',...
@Opt_query,'x0',x0,'lb',lb,'ub',lu);
[x,fval,exitflag,output] = run(gs,problem);
disp(k1)
disp(k2)
disp(k3)
ODE_set.m
function dydt = ODE_set(t, y, k1, k2, k3)
F = 20.1;
A_in = 2.5;
V = 100;
k = 0.150;
A = y(1);
B = y(2);
C = y(3);
n = numel(y);
dydt = zeros(n,1);
dydt(1) = F/V*(A_in - A) - k1*A^2;
dydt(2) = F/V*(B) - k2*B^2;
dydt(3) = F/V*(C) - k3*C^2;
end
Opt_query.m
function q = Opt_query(p)
global k1 k2 k3
k1 = p(1);
k2 = p(2);
k3 = p(3);
y0=[1 2 3];
[t,y] = ode45(@(t,y)ODE_set(t,y, k1, k2, k3),[0, 130],y0);
t_steps=0:5:130;
y_steps=interp1(t,y,t_steps);
Z = 0;
for j = 1:27
Z = Z+ abs(y_steps(j,1)-5)+abs(y_steps(j,2)-7)+abs(y_steps(j,3)-9);
end
q = sqrt(Z);
end