Лучший способ решения оптимизации с несколькими переменными в Matlab?
Я пытаюсь вычислить численно решения для системы многих уравнений и переменных (более 100). Я попробовал три вещи:
- Я теперь, что вектор p(i) (который содержит большинство эндогенных переменных) уменьшается. Таким образом, я просто дал несколько начальных точек, а затем увеличивал (уменьшал) свое предположение, когда увидел, что конкретное значение p слишком низкое (высокое). Конечно, это всегда было обусловлено исправлением другого, что не так. В конечном итоге это должно сработать, но не эффективно и не очевидно, что я достигаю решения за конечное время. Это работало при уменьшении системы до 4-6 переменных, хотя.
- Я мог бы создать более 100 петель вокруг друг друга и использовать деление пополам для каждой петли. Это в конечном итоге привело бы меня к решению, но потребовалось бы много времени для программирования (поскольку я понятия не имею, как создать n циклов вокруг друг друга без необходимости писать циклы - что также плохо, так как я хотел бы увеличить / уменьшить количество переменных легко) и выполнить.
- Я пробовал fminsearch, но, как и ожидалось, для такого количества переменных - ни за что!
Я был бы признателен за любые идеи... Вот код (этот fminsearch я пробовал):
Это файл запуска:
clear all
clc
% parameter
z=1.2;
w=20;
lam=0.7;
tau=1;
N=1000;
t_min=1;
t_max=4;
M=6;
a_min=0.6;
a_max=0.8;
t=zeros(1,N);
alp=zeros(1,M);
p=zeros(1,M);
p_min=2;
p_max=1;
for i=1:N
t(i)= t_min + (i-1)*(t_max - t_min)/(N-1);
end
for i=1:M
alp(i)= a_min + (i-1)*(a_max - a_min)/(M-1);
p(i)= p_min + (i-1)*(p_max - p_min)/(M-1);
end
fun=@(p) david(p ,z,w,lam,tau,N,M,t,alp);
p0=p;
fminsearch(fun,p0)
И это программа-файл:
function crit=david(p, z,w,lam,tau,N,M,t,alp)
X = zeros(M,N);
pi = zeros(M,N);
C = zeros(1,N);
Xa=zeros(1,N);
Z=zeros(1,M);
rl=0.01;
rh=1.99;
EXD=140;
while (abs(EXD)>100)
r1=rl + 0.5*(rh-rl);
for i=1:M
for j=1:N
X(i,j)=min(w*(1+lam), (alp(i) * p(i) / r1)^(1/(1-alp(i))) * t(j)^((z-alp(i))/(1-alp(i))));
pi(i,j)=p(i) * t(j)^(z-alp(i)) * X(i,j)^(alp(i)) - r1*X(i,j);
end
end
[C,I] = max(pi);
Xa(1)=X(I(1),1);
for j=2:N
Xa(j)=X(I(j),j);
end
EXD=sum(Xa)- N*w;
if (abs(EXD)>100 && EXD>0)
rl=r1;
elseif (abs(EXD)>100 && EXD<0)
rh=r1;
end
end
Ya=zeros(M,N);
for j=1:N
Ya(I(j),j)=t(j)^(z-alp(I(j))) * X(I(j),j)^(alp(I(j)));
end
Yi=sum(Ya,2);
if (Yi(1)==0)
Z(1)=-50;
end
for j=2:M
if (Yi(j)==0)
Z(j)=-50;
else
Z(j)=(p(1)/p(j))^tau - Yi(j)/Yi(1);
end
end
zz=sum(abs(Z))
crit=(sum(abs(Z)));
1 ответ
Прежде всего, моя рекомендация: используйте свой мозг.
Что вы знаете о функции, можете ли вы использовать градиентный подход, линеаризовать проблему или, возможно, исправить большинство переменных? Если нет, подумайте дважды, прежде чем решите, что вы действительно заинтересованы во всех 100 переменных, и, возможно, упростите задачу.
Теперь, если это невозможно, прочитайте это:
- Если вы нашли способ быстро получить локальный оптимум, вы можете просто обернуть его вокруг петли, чтобы попробовать разные начальные точки и надеяться, что вы найдете хороший оптимум.
- Если вам действительно нужно сделать много циклов (и переменное количество), я думаю, это можно сделать с помощью рекурсии, но это нелегко объяснить.
- Если вы просто хотите быстро создать фиксированное число циклов внутри друг друга, это легко сделать в Excel (подсказка: переменные цикла можно назвать t1,t2 ...)
- Если вам действительно нужно оценить функцию по множеству точек, возможно, сначала создайте все точки, используя
ndgrid
и тогда оценка их всех сразу предпочтительнее. (Излишне говорить, что это не будет хорошим решением для 100 нетривиальных переменных)