Этот пример показывает, как включить нелинейные ограничения неравенства в суррогатную оптимизацию. Пример решает ОДУ с нелинейным ограничением. Пример Оптимизировать ОДУ в Parallel показывает, как решить ту же задачу с помощью других решателей, которые принимают нелинейные ограничения.
Для видеообзора этого примера смотрите Surrogate Optimization.
Задача состоит в том, чтобы изменить положение и угол пушки, чтобы выпустить снаряд как можно дальше за стенкой. Пушка имеет дульную скорость 300 м/с. Стенка составляет 20 м. Если пушка слишком близко к стенке, она стреляет под слишком крутым углом, и снаряд не проходит достаточно далеко. Если пушка слишком далеко от стенки, снаряд не проходит достаточно далеко.
Нелинейное сопротивление воздуха замедляет снаряд. Сила сопротивления пропорциональна квадрату скорости с константой пропорциональности 0,02. Гравитация воздействует на снаряд, ускоряя его вниз с константой 9,81 м/с ^ 2. Поэтому уравнения движения для траектории x (t)
где .
Начальное положение x0 и начальная скорость xp0 являются 2-D векторами. Однако начальная высота x0(2) равен 0, поэтому начальное положение задается скаляром x0(1). Начальная скорость имеет величину 300 (дульная скорость) и, следовательно, зависит только от начального угла, который является скаляром. Для начального угла th, начальная скорость xp0 = 300*(cos(th),sin(th)). Поэтому задача оптимизации зависит только от двух скаляров, что делает ее 2-D задачей. Используйте горизонтальное расстояние и начальный угол в качестве переменных принятия решений.
Решатели ОДУ требуют от вас сформулировать модель как систему первого порядка. Увеличение вектора траектории с его производной по времени для формирования 4-D вектора траектории. В терминах этого дополненного вектора дифференциальное уравнение становится
The cannonshot файл реализует это дифференциальное уравнение.
type cannonshotfunction f = cannonshot(~,x) f = [x(3);x(4);x(3);x(4)]; % initial, gets f(1) and f(2) correct nrm = norm(x(3:4)) * .02; % norm of the velocity times constant f(3) = -x(3)*nrm; % horizontal acceleration f(4) = -x(4)*nrm - 9.81; % vertical acceleration
Визуализируйте решение этой ОДУ начиная с 30 м от стенки с начальным углом pi/3. The plotcannonsolution функция использует ode45 для решения дифференциального уравнения.
type plotcannonsolutionfunction dist = plotcannonsolution(x)
% Change initial 2-D point x to 4-D x0
x0 = [x(1);0;300*cos(x(2));300*sin(x(2))];
sol = ode45(@cannonshot,[0,15],x0);
% Find the time when the projectile lands
zerofnd = fzero(@(r)deval(sol,r,2),[sol.x(2),sol.x(end)]);
t = linspace(0,zerofnd); % equal times for plot
xs = deval(sol,t,1); % interpolated x values
ys = deval(sol,t,2); % interpolated y values
plot(xs,ys)
hold on
plot([0,0],[0,20],'k') % Draw the wall
xlabel('Horizontal distance')
ylabel('Trajectory height')
ylim([0 100])
legend('Trajectory','Wall','Location','NW')
dist = xs(end);
title(sprintf('Distance %f',dist))
hold off
plotcannonsolution использует fzero найти время приземления снаряда, что означает его высоту 0. Снаряд приземляется раньше времени 15 с, так что plotcannonsolution использует 15 в качестве количества времени для решения ОДУ.
x0 = [-30;pi/3]; dist = plotcannonsolution(x0);

Чтобы оптимизировать начальное положение и угол, запишите функцию, подобную предыдущей стандартной программе графического изображения. Вычислите траекторию, начиная с произвольного горизонтального положения и начального угла.
Включите разумные ограничения. Горизонтальное положение не может быть больше 0. Установите верхнюю границу -1. Точно так же горизонтальное положение не может быть ниже -200, поэтому установите нижнюю границу -200. Начальный угол должен быть положительным, поэтому установите его нижнюю границу равной 0,05. Начальный угол не должен превышать pi/2; установите его верхнюю границу равной pi/2 – 0.05.
lb = [-200;0.05]; ub = [-1;pi/2-.05];
Напишите целевую функцию, которая возвращает отрицательное значение полученного расстояния от стенки, учитывая начальное положение и угол. Если траектория пересекает стенку на высоте менее 20, траектория недопустима; это ограничение является нелинейным ограничением. The cannonobjcon функция реализует вычисление целевой функции. Чтобы реализовать нелинейное ограничение, функция вызывает fzero чтобы найти время, когда значение X снаряда равняется нулю. Функция учитывает возможность отказа в fzero функция путем проверки, является ли после времени 15 значение X снаряда больше нуля. Если нет, то функция пропускает шаг нахождения времени, когда снаряд проходит стенку.
type cannonobjconfunction f = cannonobjcon(x)
% Change initial 2-D point x to 4-D x0
x0 = [x(1);0;300*cos(x(2));300*sin(x(2))];
% Solve for trajectory
sol = ode45(@cannonshot,[0,15],x0);
% Find time t when trajectory height = 0
zerofnd = fzero(@(r)deval(sol,r,2),[1e-2,15]);
% Find the horizontal position at that time
dist = deval(sol,zerofnd,1);
% What is the height when the projectile crosses the wall at x = 0?
if deval(sol,15,1) > 0
wallfnd = fzero(@(r)deval(sol,r,1),[0,15]);
height = deval(sol,wallfnd,2);
else
height = deval(sol,15,2);
end
f.Ineq = 20 - height; % height must be above 20
% Take negative of distance for maximization
f.Fval = -dist;
end
Вы уже вычислили одну допустимую начальную траекторию. Используйте это значение в качестве начальной точки.
fx0 = cannonobjcon(x0); fx0.X = x0;
surrogateoptЗадайте surrogateopt опции для использования начальной точки. Для воспроизводимости установите генератор случайных чисел равным default. Используйте 'surrogateoptplot' постройте график функции. Запустите оптимизацию. Чтобы понять 'surrogateoptplot' график, см. «Интерпретация surrogateoptplot».
opts = optimoptions('surrogateopt','InitialPoints',x0,'PlotFcn','surrogateoptplot'); rng default [xsolution,distance,exitflag,output] = surrogateopt(@cannonobjcon,lb,ub,opts)

surrogateopt stopped because it exceeded the function evaluation limit set by 'options.MaxFunctionEvaluations'.
xsolution = 1×2
-28.3776 0.6165
distance = -125.9986
exitflag = 0
output = struct with fields:
elapsedtime: 38.6263
funccount: 200
constrviolation: 7.6395e-04
ineq: 7.6395e-04
rngstate: [1x1 struct]
message: 'surrogateopt stopped because it exceeded the function evaluation limit set by ...'
Постройте график конечной траектории.
figure dist = plotcannonsolution(xsolution);

The patternsearch решение в Optimize a ODE in Parallel показывает окончательное расстояние 125.9880, что почти так же, как и это surrogateopt решение.