Найти максимум функции методом золотого сечения C#
Имеется код на шарпе, для вычисления минимума функции одной переменной. Необходимо его адаптировать под нахождение максимума функции. Прикладываю непосредственно класс в котором непосредственно описана вся логика. Подскажите, что именно здесь необходимо изменить, что бы адаптировать данный класс. Пробовала изменить сама, но успехом не увенчалось.
using System;
namespace ZolotoeSecheniye
{
/// <summary>
/// Класс для оптимизации одномерной функции методом золотого сечения
/// </summary>
public class Optimizer
{
private const double Phi = 1.61804d;
private const int IntervalSearchIterations = 100;
public int Iterations { get; set; }
public Optimizer()
{
Iterations = 0;
}
/// <summary>
/// Класс для представление отрезка, с точкой по середине
/// </summary>
private class Triple
{
public double A { get; set; }
public double B { get; set; }
public double C { get; set; }
public override string ToString()
{
return "("+A+","+B+","+C+")";
}
}
/// <summary>
/// Функция для поиска минимума функции fotx
/// </summary>
/// <param name="fotx">Функция</param>
/// <param name="x0">Старт поиска интервала поиска</param>
/// <param name="h">Шаг и точность поиска</param>
/// <returns>Минимум функции</returns>
public double MinFunc(Func<double, double> fotx, double x0, double h)
{
double x0left = x0 - h;
double x0right = x0 + h;
bool isRightDirection = fotx(x0right) < fotx(x0left);
return SearchMin(
fotx,
FindMinSearchInterval(fotx, x0, isRightDirection ? x0right : x0left),
h
);
}
private double SearchMin(Func<double, double> fotx, Tuple<double, double> searchInterval, double h)
{
Iterations++;
Console.WriteLine();
Console.WriteLine("Количество итераций - " + Iterations);
Tuple<double, double> newPoints = GetSearchPoints(searchInterval.Item1, searchInterval.Item2);
Console.WriteLine("Интервал поиска решения - " + TupleToString(searchInterval));
Console.WriteLine("Точки x1, x2: " + TupleToString(newPoints));
Tuple<double, double> newCoords;
if(fotx(newPoints.Item1) >= fotx(newPoints.Item2))
{
newCoords = new Tuple<double, double>(newPoints.Item1, searchInterval.Item2);
}
else
{
newCoords = new Tuple<double, double>(searchInterval.Item1, newPoints.Item2);
}
Console.WriteLine("Обновленные концы интервала поиска - " + TupleToString(newCoords));
//Console.WriteLine("Разница (A-C) - " + (newCoords.Item2 - newCoords.Item1));
if(Math.Abs(newCoords.Item2 - newCoords.Item1) < h)
{
return (newCoords.Item1 + newCoords.Item2) / 2;
}
else
{
return SearchMin(fotx, newCoords, h);
}
}
private Tuple<double, double> GetSearchPoints(double a, double b)
{
return new Tuple<double, double>(
b - (b-a)/Phi,
a + (b-a)/Phi
);
}
private Tuple<double, double> FindMinSearchInterval(Func<double, double> fotx, double x0, double x1)
{
double a = x0, b = x1, c = CalcIntervalEnding(a, b);
//Console.WriteLine("Ищем интервал поиска...");
for (int i = 0; i < IntervalSearchIterations; i++)
{
bool isLuckyTriple = fotx(a) > fotx(b) && fotx(c) > fotx(b);
if (isLuckyTriple)
break;
a = b;
b = c;
c = CalcIntervalEnding(a, b);
}
Triple returning = new Triple()
{
A = a,
B = b,
C = c
};
//Console.WriteLine("Найден интервал поиска. Удачаная золотая тройка - " + returning);
return new Tuple<double, double>(returning.A, returning.C);
}
private String TupleToString(Tuple<double, double> tuple)
{
return "(" + tuple.Item1 + "," + tuple.Item2 + ")";
}
private double CalcIntervalEnding(double a, double b)
{
return (a * (1/Phi) - b) / ((1/Phi) - 1);
}
}
}
Ответы (1 шт):
Автор решения: Igor
→ Ссылка
public double MaxFunc(Func<double, double> fotx, double x0, double h)
{
return MinFunc((a) => -fotx(a), x0, h);
}