Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ИДЗ / МО_ИДЗ.odt
Скачиваний:
0
Добавлен:
27.06.2025
Размер:
2.05 Mб
Скачать

Приложение b

using System;

using System.Collections.Generic;

public class DichotomyMethod

{

public static double F1(double x) => 5 - 3 * Math.Exp(-Math.Pow((x - 5) / 3, 2));

public static double F2(double x) => 3 * (x - 4) * (x - 3) * (x - 1);

public static double F3(double x) => (x / 2) + 5 * Math.Sin(5 * Math.PI * x + 4);

public static (double minX, double minVal, int iterCount, List<double> xSequence)

Dichotomy(Func<double, double> f, double a, double b, double tol = 1e-5, int maxIter = 100)

{

List<double> xSequence = new List<double>();

int iterCount = 0;

while ((b - a) > tol && iterCount < maxIter)

{

double c1 = (a + b) / 2 - tol / 2;

double c2 = (a + b) / 2 + tol / 2;

xSequence.Add(c1);

xSequence.Add(c2);

if (f(c1) < f(c2))

{

b = c2;

}

else

{

a = c1;

}

iterCount++;

}

double xMin = (a + b) / 2;

xSequence.Add(xMin);

return (xMin, f(xMin), iterCount, xSequence);

}

public static double[] GenerateLinearSpace(double start, double end, int numPoints)

{

double[] result = new double[numPoints];

double step = (end - start) / (numPoints - 1);

for (int i = 0; i < numPoints; i++)

{

result[i] = start + i * step;

}

return result;

}

public static void Main(string[] args)

{

Func<double, double>[] functions = { F1, F2, F3 };

string[] functionNames = { "f1", "f2", "f3" };

(double, double)[] intervals = { (0, 10), (-2, 8), (-5, 5) };

for (int i = 0; i < functions.Length; i++)

{

Console.WriteLine($"Функция {functionNames[i]}:");

(double minX, double minVal, int iterCount, List<double> xSequence) =

Dichotomy(functions[i], intervals[i].Item1, intervals[i].Item2);

Console.WriteLine($" Метод дихотомии:");

Console.WriteLine($" Начальный отрезок: [{Math.Round(intervals[i].Item1, 2)}, {Math.Round(intervals[i].Item2, 2)}]");

Console.WriteLine($" Число итераций: {iterCount}");

Console.WriteLine($" Найденный минимум: x = {Math.Round(minX, 2)}, f(x) = {Math.Round(minVal, 2)}");

Console.WriteLine($" Последовательность точек: {string.Join(", ", xSequence.ConvertAll(x => Math.Round(x, 2)))}");

}

}

}

Приложение c

using System;

class NelderMeadMethod

{

// Первая целевая функция

static double Function1(double x1, double x2)

{

return 8 * Math.Pow(x1 - 1, 2) + 3 * Math.Pow(x2 - 1, 2);

}

// Вторая целевая функция

static double Function2(double x1, double x2)

{

return Math.Pow(x1 - 5, 2) + Math.Pow(x2 - 1, 2) + 30 * Math.Pow(x2 + x1 - 6, 2) + 9.5;

}

public static void FindMinimum(double[][] simplex, double alpha, double beta,

double gamma, double epsilon, Func<double, double, double> function)

{

int dimensions = simplex[0].Length;

int iterations = 0;

while (true)

{

iterations++;

Array.Sort(simplex, (a, b) => function(a[0], a[1]).CompareTo(function(b[0],

b[1])));

// Лучшая, вторая лучшая и худшая точки

double[] best = simplex[0];

double[] secondBest = simplex[1];

double[] worst = simplex[dimensions - 1];

// Вычисляем центроид

double[] centroid = new double[dimensions];

for (int i = 0; i < dimensions; i++)

{

centroid[i] = 0;

for (int j = 0; j < dimensions - 1; j++)

{

centroid[i] += simplex[j][i];

}

centroid[i] /= (dimensions - 1);

}

// Отражение

double[] reflected = new double[dimensions];

for (int i = 0; i < dimensions; i++)

{

reflected[i] = centroid[i] + alpha * (centroid[i] - worst[i]);

}

if (function(reflected[0], reflected[1]) < function(best[0], best[1]))

{

// Расширение

double[] expanded = new double[dimensions];

for (int i = 0; i < dimensions; i++)

{

expanded[i] = centroid[i] + gamma * (reflected[i] - centroid[i]);

}

if (function(expanded[0], expanded[1]) < function(reflected[0], reflected[1]))

{

simplex[dimensions - 1] = expanded;

}

else

{

simplex[dimensions - 1] = reflected;

}

}

else if (function(reflected[0], reflected[1]) < function(secondBest[0],

secondBest[1]))

{

simplex[dimensions - 1] = reflected;

}

else

{

// Сжатие

double[] contracted = new double[dimensions];

for (int i = 0; i < dimensions; i++)

{

contracted[i] = centroid[i] + beta * (worst[i] - centroid[i]);

}

if (function(contracted[0], contracted[1]) < function(worst[0], worst[1]))

{

simplex[dimensions - 1] = contracted;

}

else

{

// Уменьшение

for (int i = 1; i < dimensions; i++)

{

simplex[i] = new double[dimensions];

for (int j = 0; j < dimensions; j++)

{

simplex[i][j] = best[j] + 0.5 * (simplex[i][j] - best[j]);

}

}

}

}

// Вывод текущих точек симплекса

Console.WriteLine($"Итерация {iterations}:");

for (int i = 0; i < simplex.Length; i++)

{

double f = function(simplex[i][0], simplex[i][1]);

Console.WriteLine($"Точка {i + 1}: x1 = {Math.Round(simplex[i][0], 2)}, x2 = {Math.Round(simplex[i][1], 2)}, f(x1, x2) = {Math.Round(f, 2)}");

}

Console.WriteLine();

// Проверка на сходимость

double range = 0;

for (int i = 0; i < dimensions; i++)

{

range = Math.Max(range, Math.Abs(simplex[i][0] - simplex[0][0]));

range = Math.Max(range, Math.Abs(simplex[i][1] - simplex[0][1]));

}

if (range < epsilon)

{

break;

}

}

Console.WriteLine($"Минимум найден в точке: x1 = {Math.Round(simplex[0][0], 2)}, x2 = {Math.Round(simplex[0][1], 2)}");

Console.WriteLine($"Значение минимума для f(x1, x2): {Math.Round(function(simplex[0][0], simplex[0][1]), 2)}");

Console.WriteLine($"Количество итераций: {iterations}");

}

static void Main(string[] args)

{

// Начальные точки симплекса для первой функции

double[][] simplex1 = new double[][]

{

new double[] { 0.0, 0.0 }, new double[] { 5.0, 5.0 }, new double[] { 10.0, 10.0 }

};

// Начальные точки симплекса для второй функции

double[][] simplex2 = new double[][]

{

new double[] { 0.0, 0.0 }, new double[] { 5.0, 5.0 }, new double[] { 10.0, -10.0 }

};

// Параметры метода Нелдера-Мида

double alpha = 1.0; // коэффициент отражения

double beta = 0.5; // коэффициент сжатия

double gamma = 2.0; // коэффициент расширения

double epsilon = 1e-5; // точность

// Запуск метода Нелдера-Мида для первой функции

Console.WriteLine("Минимизация первой функции:");

FindMinimum(simplex1, alpha, beta, gamma, epsilon, Function1);

Console.WriteLine();

// Запуск метода Нелдера-Мида для второй функции

Console.WriteLine("Минимизация второй функции:");

FindMinimum(simplex2, alpha, beta, gamma, epsilon, Function2);

}

}

Соседние файлы в папке ИДЗ