
- •Содержание
- •1. Нахождение y теоретического. Преобразование формулы и решение ее с помощью Метода Эйлера. 6
- •Постановка задачи
- •Нахождение y теоретического. Преобразование формулы и решение ее с помощью Метода Эйлера.
- •Моделирование метода оптимизации. Метод покоординатного спуска
- •Описание метода поиска
- •Результаты работы программы:
- •Квадратичная функция (Эллипс)
- •Функция Розенброка
- •Целевая функция.
- •Список использованных источников
- •Приложение
Список использованных источников
http://ru.wikipedia.org/wiki/Функция_Розенброка
http://nsft.narod.ru/Programming/colmetopt.html
http://www.mathworks.com
http://www.exponenta.ru/soft/matlab/potemkin/book/matlab/chapter0/0_0.asp
http://matlab.exponenta.ru
Н.Ю. Золотых. Использование пакета Matlab в научной и учебной работе - Нижний Новгород, 2006 – 165с.
Приложение
Листинг программы
Главный файл проекта.
clear all;
clc;
ITERATION_AMOUNT = 1000;
EPSILON = 0.001; %Точность
h = 0.2; %Шаг
POINT_AMOUNT = 50; %количество точек
%начальная точка
%Эллипс
x_point_Ellipse(1) = 2;
x_point_Ellipse(2) = -2;
%Розенброк
x_point_Rosenbrock(1) = 4;
x_point_Rosenbrock(2) = 3;
%CF
a1_T_point_CF(1) = 2;
a1_T_point_CF(2) = 4;
%a и b - значения радиусов для ф-ии. Эллипса.
a = 3;
b = 2;
%исходные значения параметров функции W(s).
a1 = 10;
T = 2;
ELLIPSE = 'ELLIPSE';
ROSENBROCK = 'ROSENBROCK';
CF_text = 'CF';
%Часть 1. Эйлер.
y_teor = FirstPart_EulerMethod(a1, T, POINT_AMOUNT);
%Часть 2. Оптимизация покоординатно.
%function [value_of_funct, x] = SecondPart_OptimizationCoordinate(function_name, h, EPSILON, ITERATION_AMOUNT, a, b, y_exp, number_y_exp, POINT_AMOUNT)
[y_Ellipse, x_Ellipse] = SecondPart_OptimizationCoordinate(ELLIPSE, h, EPSILON, ITERATION_AMOUNT, x_point_Ellipse, a, b, -1, -1, POINT_AMOUNT);
[y_Rosenbrock, x_Rosenbrock] = SecondPart_OptimizationCoordinate(ROSENBROCK, h, EPSILON, ITERATION_AMOUNT, x_point_Rosenbrock, a, b, -1, -1, POINT_AMOUNT);
%Часть 3. ГСЧ. CF
[CF, a1_T_1, a1_T_2, a1_T_3] = ThirdPart(CF_text, h, EPSILON, ITERATION_AMOUNT, a1_T_point_CF, a, b, y_teor, POINT_AMOUNT);
Функция Метод Эйлера.
function y_Euler_50point = FirstPart_EulerMethod(a1, T, POINT_AMOUNT)
global y_Euler;
ITERATION_AMOUNT = 300; %количество точек для первого графика.
x_t = 5; %константа из задания x(t)
h = 0.5;
z1 = 0;
z2 = 0;
coeff_z1 = 120*a1/T.^2+6;
coeff_z2 = 6*a1-120+48*a1/T;
coeff_x_t = 120*a1/T.^2;
%free_term - свободный член.
free_term = coeff_x_t*x_t;
for i = 1:ITERATION_AMOUNT
z1(i+1) = z1(i) + h*z2(i);
z2(i+1) = z2(i) + h*(x_t-z1(i)-0.4*T*z2(i))/T.^2;
y_Euler(i) = coeff_z1*z1(i) + coeff_z2*z2(i) - free_term;
end;
% figure
% i = 1:ITERATION_AMOUNT;
% plot(i,y_Euler);
% title('Y теоретическое. график на 300 точек');
%saveas(gcf, 'output', 'bmp');
%оставляем из всех 300 точек только 50 (POINT_AMOUNT)
j = 1;
step_cycle = ITERATION_AMOUNT/POINT_AMOUNT;
for i = 1:step_cycle:ITERATION_AMOUNT
y_Euler_50point(j) = y_Euler(i);
j = j + 1;
end;
% figure
% i = 1:POINT_AMOUNT;
% plot(i,y_Euler_50point);
% title('Y теоретическое. график на 50 точек (через каждые 6)');
end
Функция покоординатной оптимизации
%Часть 2. Оптимизация покоординатно.
function [value_of_funct, x] = SecondPart_OptimizationCoordinate(function_name, h, EPSILON, ITERATION_AMOUNT, x_start_point, a, b, y_exp, number_y_exp, POINT_AMOUNT)
varlist = {'global X', 'global Y', 'global Z', 'T_plot', 'a1_plot'};
%global_varlist = {'global T_plot','global a1_plot', 'global X', 'global Y', 'global Z'};
%clear(varlist{:});
%clear CF;
clear (varlist{:});
%global X;
%global Y;
%global Z;
%Перем. для пропуска проверки условия на то, предыд. value_of_funct min из последних трех или нет.
change_coord = 1;
%Для выхода из цикла, если кол-во. итераций больше ITERATION_AMOUNT.
number_iteration = 1;
change = 1;
constant = 2;
i = 2;
x(1,1) = x_start_point(1); %первая координата, первое значение.
x(2,1) = x_start_point(2); %вторая координата, первое значение.
x(1,2) = x(change,i-1) + h; %первая координата, второе значение.
x(2,2) = x(constant,i-1); %вторая координата, второе значение.
value_of_funct(1) = Ellipse_Rosenbrock_or_CF(function_name, x(1,1), x(2,1), a, b, y_exp, number_y_exp, POINT_AMOUNT);
new_value_of_function = Ellipse_Rosenbrock_or_CF(function_name, x(1,2), x(2,2), a, b, y_exp, number_y_exp, POINT_AMOUNT);
if new_value_of_function > value_of_funct(1)
h = h* (-1);
x(1,2) = x(change,i-1) + h;
value_of_funct(2) = Ellipse_Rosenbrock_or_CF(function_name, x(change,i), x(constant,i), a ,b, y_exp, number_y_exp, POINT_AMOUNT);
else
value_of_funct(2) = new_value_of_function;
end
%Цикл пока модуль разности функций больше точности эпсилон и количество итераций меньше ITERATION_AMOUNT(10000).
while (abs(value_of_funct(i)-value_of_funct(i-1)) > EPSILON && (number_iteration < ITERATION_AMOUNT))
number_iteration = number_iteration + 1;
i = i + 1;
change_coord = change_coord + 1;
%прибавляем шаг к первой координате.
x(change,i) = x(change,i-1) + h;
%вторую координату переписываем.
x(constant,i) = x(constant,i-1);
%находим значение функции от новых значений.
new_value_of_function = Ellipse_Rosenbrock_or_CF(function_name, x(1,i), x(2,i), a, b, y_exp, number_y_exp, POINT_AMOUNT);
%если функция от текущих значений больше функции от предыдущих, то h = h* (-1), ... иначе value_of_funct(i) = new_value_of_function.
if new_value_of_function > value_of_funct(i-1)
%обнуляем последнее значение
x(change,i) = NaN;
i = i - 1; %чтобы вернуться к предыдущему минимальному значению функции
h = h* (-1);
%Если после смены координаты, по которой шагаем сделали не меньше 3 точек, то делаем проверку min value_of_funct из последних 3-х. значений.
if (change_coord >= 3)
%если функция от значений на предыдущем шаге меньше текущих и меньше чем на шаге i-2, то меняем координату перемещения.
if value_of_funct(i-1) >= value_of_funct(i)
%После перемены координаты по которой шагаем - обнуляем change_coord.
change_coord = 0;
if (constant == 1)
constant = 2;
change = 1;
else
constant = 1;
change = 2;
end
end
end
else
value_of_funct(i) = new_value_of_function;
end
end %конец цикла while
last_number = i;
%построение графика
draw_way_and_lines_level(function_name, x, last_number, value_of_funct, number_iteration, a, b, y_exp, number_y_exp, POINT_AMOUNT);
end
Функция для вычисления значения ф-ии. F(x1, x2) по Розенброку, по ф-ии. Эллипса или целевой функции (CF).
function value_of_funct = Ellipse_Rosenbrock_or_CF(function_name, x_1_i, x_2_i, a, b, y_exp, number_y_exp, POINT_AMOUNT)
if strcmp(function_name, 'ROSENBROCK') == 1
%if function_name == 'ROSENBROCK'
value_of_funct = 100 * (x_2_i - x_1_i.^2).^2 + (1 - x_1_i).^2;
return
elseif strcmp(function_name, 'ELLIPSE') == 1
%elseif function_name == 'ELLIPSE'
value_of_funct = x_1_i.^2/a.^2 + x_2_i.^2/b.^2;
return
elseif strcmp(function_name, 'CF') == 1
%elseif function_name == 'ELLIPSE'
y_model = FirstPart_EulerMethod(x_1_i, x_2_i, POINT_AMOUNT);
value_of_funct = sum((y_exp(number_y_exp,:) - y_model).^2)/POINT_AMOUNT;
return
else
value_of_funct = -1;
return
end
end
%Часть 3. CF
function [CF, a1_T_1, a1_T_2, a1_T_3] = ThirdPart(function_name, h, EPSILON, ITERATION_AMOUNT, a1_T_point_CF, a, b, y_teor, POINT_AMOUNT)
%y_max берем из 1 части.
y_max = max(abs(y_teor));
%delta_y = y max * Мю
delta_y(1) = y_max*0.005;
delta_y(2) = y_max*0.01;
delta_y(3) = y_max*0.02;
%Генератор случайных чисел. Треугольный шум.
[y_noise(1, :), x_noise(1, :)] = RNG_Triangle(delta_y(1), POINT_AMOUNT);
[y_noise(2, :), x_noise(2, :)] = RNG_Triangle(delta_y(2), POINT_AMOUNT);
[y_noise(3, :), x_noise(3, :)] = RNG_Triangle(delta_y(3), POINT_AMOUNT);
y_exp(1, :) = y_teor + x_noise(1, :);
y_exp(2, :) = y_teor + x_noise(2, :);
y_exp(3, :) = y_teor + x_noise(3, :);
i = 1:POINT_AMOUNT;
s_exp1 = 'k';
s_exp2 = 'g';
s_exp3 = 'b';
s_teor = 'r';
%Строим графики Y экспериментальных.
% figure;
% plot(y_exp(1, :), s_exp1);
% title('Yexp1 - черный');
% figure;
% plot(y_exp(2, :), s_exp2);
% title('Yexp2 - зеленый');
% figure;
% plot(i, y_exp(3, :), s_exp3, i, y_teor, s_teor);
% title('Yexp3 - голубой. Yteor - красный');
number_y_exp_1 = 1;
number_y_exp_2 = 2;
number_y_exp_3 = 3;
[CF1, a1_T_1] = SecondPart_OptimizationCoordinate(function_name, h, EPSILON, ITERATION_AMOUNT, a1_T_point_CF, a, b, y_exp, number_y_exp_1, POINT_AMOUNT);
[CF2, a1_T_2] = SecondPart_OptimizationCoordinate(function_name, h, EPSILON, ITERATION_AMOUNT, a1_T_point_CF, a, b, y_exp, number_y_exp_2, POINT_AMOUNT);
[CF3, a1_T_3] = SecondPart_OptimizationCoordinate(function_name, h, EPSILON, ITERATION_AMOUNT, a1_T_point_CF, a, b, y_exp, number_y_exp_3, POINT_AMOUNT);
%Закидываем массивы CF1, CF2, CF3 в двумерный массив CF(3,:).
size_CF(1) = size(CF1, 2);
size_CF(2) = size(CF2, 2);
size_CF(3) = size(CF3, 2);
for i = 1:size_CF(1)
CF(1, i) = CF1(i);
end
for i = 1:size_CF(2)
CF(2, i) = CF2(i);
end
for i = 1:size_CF(3)
CF(3, i) = CF3(i);
end
end
%Часть 3.
%Генератор случайных чисел. на дельта y_noise.
%Random number generator. Треугольный шум.
function [y_noise, x_noise] = RNG_Triangle(delta_y, POINT_AMOUNT)
j = 1;
while j <= POINT_AMOUNT
%a - по горизонтальной прямой - аргумент. генерируем числа от -delta_y до delta_y.
a = -delta_y + (delta_y-(-delta_y)).*rand();
%b - по вертикальной прямой - функция. генерируем числа от 0 до 1/delta_y.
b = 0 + (1/delta_y-0).*rand();
%fprintf('Value_of_Function(a, delta_y) = %d\n', Value_of_Function(a, delta_y));
%Если b меньше, то сгенерированная точка внутри треугольника.
if RNG_Value_of_Function(a, delta_y) > b
y_noise(j) = b;
x_noise(j) = a;
j = j + 1;
end;
end;
%figure;
%рисуем гистограмму.
%hist(x_noise);
end
%Часть 3.
%Вычисление значения функции для ГСЧ в зависимости от того аргуемент "+" или "-".
function y_triangle = RNG_Value_of_Function(argument, delta_y)
x1 = 0;
y1 = 1/delta_y;
y2 = 0;
%значение по горизонтали (аргумента) больше или меньше нуля
if argument > 0
x2 = delta_y;
else
x2 = -delta_y;
end;
y_triangle = (argument - x1)*(y2 - y1)/(x2 - x1) + y1;
%fprintf('y_triangle = %d\n', y_triangle);
end
%построение линий уровня и графика поиска min.
function draw_way_and_lines_level(function_name, x, last_number, value_of_funct, number_iteration, a, b, y_exp, number_y_exp, POINT_AMOUNT)
if strcmp(function_name, 'ELLIPSE') == 1
title_plot = ('Функция Эллипса');
x_contour = -5:0.1:5;
y_contour = -5:0.1:5;
[X, Y] = meshgrid(x_contour, y_contour);
Z = (X/a).^2 + (Y/b).^2;
%точка MIN
min_x = 0;
min_y = 0;
contour_amount = 50;
%координаты вывода таблички с данными
text_x = -4.8;
text_y = -3.9;
elseif strcmp(function_name, 'ROSENBROCK') == 1
title_plot = ('Функция Розенброка');
x_contour = -5:0.1:5;
y_contour = -5:0.1:5;
[X, Y] = meshgrid(x_contour, y_contour);
Z = 100 * (Y - X.^2).^2 + (1 - X).^2;
%точка MIN
min_x = 1;
min_y = 1;
contour_amount = 200;
%координаты вывода таблички с данными
text_x = -4.8;
text_y = -3.9;
elseif strcmp(function_name, 'CF') == 1
%title_plot = ('CF (Целевая функция)');
title_plot = strcat('CF', num2str(number_y_exp), ' (Целевая функция)');
a1_start = -2;
a1_step = 0.2;
a1_end = 13;
a1_contour = a1_start:a1_step:a1_end;
T_start = 1.8;
T_step = a1_step;
T_end = 7.8;
T_contour = T_start:T_step:T_end;
%создаем матрицу значений неизвестных параметров для построения линий уровня.
[a1_plot, T_plot] = meshgrid(a1_contour, T_contour);
iter_amount_a1 = (a1_end - a1_start)/a1_step + 1;
iter_amount_T = (T_end - T_start)/T_step + 1;
%fprintf('iter_amount_a1 = %d\n', iter_amount_a1);
%fprintf('iter_amount_T = %d\n', iter_amount_T);
%Здесь создаем матрицу значений CF для построения линий уровня.
for i = 1:iter_amount_T
for j = 1:iter_amount_a1
y_model = FirstPart_EulerMethod(a1_plot(i,j), T_plot(i,j), POINT_AMOUNT);
Z(i, j) = sum((y_exp(number_y_exp, :)-y_model).^2)/POINT_AMOUNT;
end
end
X = a1_plot;
Y = T_plot;
min_x = 10;
min_y = 2;
contour_amount = 500;
text_x = -1.7;
text_y = 2.5;
end
%figure
%mesh(X,Y,Z);
figure
contour(X, Y, Z, contour_amount);
% отображение меток уровня
hold on;
plot(x(1, :), x(2, :), 'k<-');
%вывод точки минимума.
plot(min_x, min_y, 'r*');
title(title_plot);
text(min_x-0.2, min_y+0.4,'MIN', 'BackgroundColor',[.7 .7 .7])
% выводначальной точки на график
text(x(1,1), x(2,1), 'A0', ...
'BackgroundColor',[.7 .7 .7]);
% вывод решения на график
text(text_x, text_y, ...
char(['x1 = ' num2str(x(1,last_number))], ...
['x2 = ' num2str(x(2,last_number))], ...
['f() = ' num2str(value_of_funct(last_number))], ...
['итераций - ' num2str(number_iteration)]), ...
'BackgroundColor',[.7 .7 .7]);
end