// Метод для поиска минимума методом золотого сечения (Algo8-1.c). // Возвращает значение аргумента: public static double Optimum_1(Functional_1 fun, // fun - минимизируемая функция (функционал) double A, double B, //границы интервала double Delta, double Epsilon) { // точности по абсциссе и ординате double Rone = (Math.Sqrt(5.0) - 1.0) / 2.0; // Determine constants double Rtwo = Rone * Rone; /* for golden search */ double YA, YB; /* function values at A and B */ double C, D; /* interior points */ double H; /* width of interval */ double P, YC, YD, YP; /* minimum and function values */ YA = fun(A); YB = fun(B); H = B - A; C = A + Rtwo * H; YC = fun(C); D = A + Rone * H; YD = fun(D); while (Math.Abs(YA - YB) > Epsilon || H > Delta) { if (YC < YD) { B = D; YB = YD; D = C; YD = YC; H = B - A; C = A + Rtwo * H; YC = fun(C); } else { A = C; YA = YC; C = D; YC = YD; H = B - A; D = A + Rone * H; YD = fun(D); } } P = A; YP = YA; if (YB < YA) { P = B; YP = YB; } return(P); }//Optimum_1
/// <summary> /// Find minimum's point. /// </summary> /// <param name="fun"> Function </param> /// <param name="left"> Left bound </param> /// <param name="right"> Right bound </param> /// <param name="delta"> Eps X </param> /// <param name="epsilon"> Eps Y </param> /// <returns> Minimum's point </returns> public static double Optimum_1(Functional_1 fun, double left, double right, double delta, double epsilon) { if (fun is null || right < left || delta < 0 || epsilon < 0) { throw new Exception("Error passing parameters"); } // Declare require variable. var rOne = (Math.Sqrt(5) - 1) / 2.0; var rTwo = rOne * rOne; double yLeft, yRight; double h; // Можно было делать обычное присваивание, но так лаконичней. // Set value in variables. (yLeft, yRight, h) = (fun(left), fun(right), right - left); var c = left + rTwo * h; var yC = fun(c); var d = left + rOne * h; var yD = fun(d); // Function start. while (Math.Abs(yLeft - yRight) > epsilon || h > delta) { if (yC < yD) { (right, yRight) = (d, yD); (d, yD, h) = (c, yC, right - left); c = left + rTwo * h; yC = fun(c); } else { (left, yLeft, c, yC) = (c, yC, d, yD); h = right - left; d = left + rOne * h; yD = fun(d); } } return((yRight < yLeft) ? right : left); }