
ИДЗ / МО ИДЗ вариант Б
.pdfТаблица 2.2.2 – Результаты для f5(x)
|
Начальные |
Полученная точка |
Число |
|
f 5(x)=(x1−5)2+(x2−6)2 |
|
точки |
минимума |
итераций, |
+50 (x2+4 x1−6)2+1,4 |
|
|
|
за которое |
|
|
|
найден |
|
|
|
|
|
|
|
|
|
|
минимум |
|
|
|
|
|
Метод Нелдера- |
х(1) = (0; 0) |
(0,300; 4,826; 24,902) |
36 |
|
Мида |
x(2) |
= (0,966; |
|
|
|
|
0,259) |
|
|
|
x(3) |
= (0,259; |
|
|
|
|
0,966) |
|
|
|
|
|
|
|
Метод |
|
|
(0,833; 2,691; 29,739) |
1243 |
наискорейшего |
Х(0) = (0; 0) |
|
|
|
спуска |
|
|
|
|
|
|
|
|
|
21
Заключение
В ходе выполнения данной работы были получены навыки нахождения минимального значения функции методами: золотого сечения, дихотомии, Нелдера-Мида и наискорейшего спуска. По результатам выполнения задания разработаны программы для каждого метода, составлены графики нахождения минимального значения, описан процесс выбора начальных точек и составлены таблицы значений для каждой итерации.
По полученным результатам наиболее эффективным методом для минимизации одномерной функции является метод дихотомии, для минимизации многомерной функции – метод Нелдера-Мида. Метод наискорейшего спуска плохо справляется с функциями, подобными f5(x).
22
Приложение А Метод золотого сечения
decimal a0 = 0; decimal b0 = 10;
decimal alpha = 0.618m; decimal beta = 0.382m; decimal e = 0.001m;
int iteration = 0;
decimal F1(decimal x)
{
decimal y1 = 2 - Convert.ToDecimal(Math.Exp(-Math.Pow(((Convert.ToDouble(x) - 5) / 4), 2)));
return y1;
}
decimal F2(decimal x)
{
decimal y2 = 5 * (x - 1) * (x - 5) * (x - 4); return y2;
}
decimal F3(decimal x)
{
decimal y3 = (x / 2) + 8 * Convert.ToDecimal(Math.Sin(3 * Math.PI * Convert.ToDouble(x) + 1));
return y3;
}
decimal delta = b0 - a0; void GoldenRatio()
{
decimal x_alpha = a0 + (alpha * delta);
23
decimal x_beta = a0 + (beta * delta);
decimal f_alpha = F1(x_alpha);
decimal f_beta = F1(x_beta);
//decimal f_alpha = F2(x_alpha);
//decimal f_beta = F2(x_beta);
//decimal f_alpha = F3(x_alpha);
//decimal f_beta = F3(x_beta);
if (f_beta >= f_alpha)
{
a0 = x_beta;
}
else
{
b0 = x_alpha;
}
delta = delta * alpha;
if (delta < e)
{
Console.WriteLine();
Console.WriteLine($"Отрезок [a; b]: [0; 10]");
Console.WriteLine($"x_alpha = {decimal.Round(x_alpha, 3,
MidpointRounding.AwayFromZero)}; x_beta = {decimal.Round(x_beta, 3,
MidpointRounding.AwayFromZero)}");
Console.WriteLine($"y_alpha = {decimal.Round(f_alpha, 3,
MidpointRounding.AwayFromZero)}; y_beta = {decimal.Round(f_beta, 3,
MidpointRounding.AwayFromZero)}");
24
Console.WriteLine($"Количество итераций: {iteration}");
}
else
{
iteration++;
Console.Write($"x_alpha = {decimal.Round(x_alpha, 3,
MidpointRounding.AwayFromZero)}; x_beta = {decimal.Round(x_beta, 3,
MidpointRounding.AwayFromZero)} ");
Console.Write($"y_alpha = {decimal.Round(f_alpha, 3,
MidpointRounding.AwayFromZero)}; y_beta = {decimal.Round(f_beta, 3,
MidpointRounding.AwayFromZero)} ");
Console.WriteLine($"{iteration}");
GoldenRatio();
}
}
GoldenRatio();
25
Приложение Б Метод дихотомии
decimal a0 = 0; decimal b0 = 10; decimal e = 0.001m; decimal d = 0.0006m; int iteration = 0;
decimal F1(decimal x)
{
decimal y1 = 2 - Convert.ToDecimal(Math.Exp(-Math.Pow(((Convert.ToDouble(x) - 5) / 4), 2)));
return y1;
}
decimal F2(decimal x)
{
decimal y2 = 5 * (x - 1) * (x - 5) * (x - 4); return y2;
}
decimal F3(decimal x)
{
decimal y3 = (x / 2) + 8 * Convert.ToDecimal(Math.Sin(3 * Math.PI * Convert.ToDouble(x) + 1));
return y3;
}
decimal delta = b0 - a0;
void Dichotomy()
{
decimal x1 = (a0 + b0 - d) / 2;
26
decimal x2 = (a0 + b0 + d) / 2;
decimal f1 = F1(x1);
decimal f2 = F1(x2);
//decimal f1 = F2(x1);
//decimal f2 = F2(x2);
//decimal f1 = F3(x1);
//decimal f2 = F3(x2);
if (f1 <= f2)
{
b0 = x2;
}
else
{
a0 = x1;
}
delta = b0 - a0;
if (delta < e)
{
Console.WriteLine();
Console.WriteLine($"x1 = {decimal.Round(x1, 3,
MidpointRounding.AwayFromZero)} x2 = {decimal.Round(x2, 3,
MidpointRounding.AwayFromZero)} ");
Console.WriteLine($"y1 = {decimal.Round(f1, 3,
MidpointRounding.AwayFromZero)} y2 = {decimal.Round(f2, 3,
MidpointRounding.AwayFromZero)} ");
Console.WriteLine($"Количество итераций: {iteration}");
}
27
else
{
iteration++;
Console.Write($"x1 = {decimal.Round(x1, 3,
MidpointRounding.AwayFromZero)} x2 = {decimal.Round(x2, 3,
MidpointRounding.AwayFromZero)} ");
Console.Write($"y1 = {decimal.Round(f1, 3,
MidpointRounding.AwayFromZero)} y2 = {decimal.Round(f2, 3,
MidpointRounding.AwayFromZero)} ");
Console.WriteLine($"{iteration}");
Dichotomy();
}
}
Dichotomy();
28
Приложение В Метод Нелдера-Мида
decimal e = 0.001m; decimal alpha = 1; decimal gamma = 2; decimal beta = 0.5m; int iteration = 0; double t = 1; double n = 2;
decimal F45(decimal x, decimal y)
{
decimal z1 = 5 * Convert.ToDecimal(Math.Pow(Convert.ToDouble(x) - 2, 2)) + 5 * Convert.ToDecimal(Math.Pow(Convert.ToDouble(y) - 3, 2));
return z1;
//decimal z2 = Convert.ToDecimal(Math.Pow(Convert.ToDouble(x) - 5, 2) + Math.Pow(Convert.ToDouble(y) - 6, 2) + 50 * Math.Pow(Convert.ToDouble(y + (4 * x) - 6), 2) + 1.4);
//return z2;
}
decimal a = Convert.ToDecimal((t * (Math.Sqrt(n + 1) + n - 1)) / (Math.Sqrt(2) * n)); decimal b = Convert.ToDecimal((t * (Math.Sqrt(n + 1) - 1)) / (Math.Sqrt(2) * n));
decimal[] x1 = { 0, 0 }; decimal[] x2 = { a, b }; decimal[] x3 = { b, a };
void NelderMead()
{
29
decimal f1 = F45(x1[0], x1[1]); decimal f2 = F45(x2[0], x2[1]); decimal f3 = F45(x3[0], x3[1]);
decimal fmax = Math.Max(f1, Math.Max(f2, f3)); decimal fmin = Math.Min(f1, Math.Min(f2, f3));
decimal[] heavy = new decimal[2]; decimal[] light = new decimal[2]; decimal[] centre = new decimal[2]; decimal[] xi = new decimal[2];
decimal Ostanov(decimal[] heavy, decimal[] light, decimal[] xi, decimal[] centre)
{
decimal ostanovka = Convert.ToDecimal(Math.Sqrt((1 / (n + 1)) * Math.Pow(Convert.ToDouble(F45(heavy[0], heavy[1]) - F45(centre[0], centre[1])), 2) + Math.Pow(Convert.ToDouble((F45(light[0], light[1]) - F45(centre[0], centre[1]))), 2) + Math.Pow(Convert.ToDouble((F45(xi[0], xi[1]) - F45(centre[0], centre[1]))), 2)));
return ostanovka;
}
if (fmax == f1) { heavy = x1; }
else if (fmax == f2) { heavy = x2; } else { heavy = x3; }
if (fmin == f1) { light = x1; }
else if (fmin == f2) { light = x2; } else { light = x3; }
xi[0] = (x1[0] + x2[0] + x3[0]) - (heavy[0] + light[0]);
30