/// <summary> /// Рассчитывает область поиска или кидает исключение по превышении количества операций. /// </summary> /// <returns>область поиска оптимума</returns> public GoldenTriplet GetArea() { // записываем шаг поиска var step = _step; // создаём тройку с нуля var triplet = new GoldenTriplet { A = _start, RightCenter = _start + step }; _logger.Log($"начальная тройка: {triplet}"); // пока не найдём удачную тройку, ищем while (!IsLucky(triplet)) { // если количество операций превысило максимальное, кинуть ошибку if (IsCountDown()) { throw new ApplicationException("не удалось найти область поиска"); } // двигаем провотиположную A сторону на количество шагов triplet.LeftCenter = triplet.B; _logger.Log($"новая тройка поиска: {triplet}"); } ResetCounter(); return(triplet); }
public void TestRightCenter(double left, double right, double expected) { GoldenTriplet = new GoldenTriplet { A = left, B = right }; var got = GoldenTriplet.RightCenter; Assert.AreEqual(expected, got); }
public void TestBFromLeftCenter(double left, double leftCenter, double expected) { GoldenTriplet = new GoldenTriplet { A = left, LeftCenter = leftCenter }; var got = GoldenTriplet.B; // delta подбирается эмпирическим путём Assert.AreEqual(expected, got, delta: 1E-08); }
public void TestLeftCenter(double left, double right, double expected) { GoldenTriplet = new GoldenTriplet { A = left, B = right }; var got = GoldenTriplet.LeftCenter; // delta подбирается эмпирическим путём Assert.AreEqual(expected, got, delta: 1E-08); }
/// <summary> /// Выбирает из двух частей тройки лучшую. /// </summary> /// <remark> /// Учитывает настройку, какой параметр ищем: max / min. /// </remark> /// <param name="old">тройка для рассмотрения</param> /// <returns>новая тройка, оказавшаяся лучше</returns> private GoldenTriplet FindGood(GoldenTriplet old) { if (_lookingForMax) { return _function(old.LeftCenter) > _function(old.RightCenter) ? new GoldenTriplet { A = old.LeftCenter, B = old.B } } : new GoldenTriplet { A = old.A, B = old.RightCenter }; else { return _function(old.LeftCenter) < _function(old.RightCenter) ? new GoldenTriplet { A = old.A, B = old.RightCenter } } : new GoldenTriplet { A = old.LeftCenter, B = old.B }; }
/// <summary> /// Узнаёт, не мала ли тройка. /// </summary> /// <param name="triplet">тройка</param> /// <returns>истина, если тройка меньше точности поиска</returns> private bool IsTooSmall(GoldenTriplet triplet) => Abs(triplet.B - triplet.A) <= _precision;
/// <summary> /// Удачна ли тройка для этой функции. /// </summary> /// <remark> /// Учитывает настройку, какой параметр ищем: max / min. /// </remark> /// <param name="triplet">тройка</param> /// <returns>истина, если тройка удачная</returns> private bool IsLucky(GoldenTriplet triplet) => _lookingForMax ? _function(triplet.RightCenter) >= _function(triplet.A) && _function(triplet.RightCenter) >= _function(triplet.B) : _function(triplet.RightCenter) <= _function(triplet.A) && _function(triplet.RightCenter) <= _function(triplet.B);