public static double findMinimum(Interval searchInterval, double eps, int funcNumber) { bool searchEnd = false; // Конец поиска double x_min; // Значение x, при котором функция будет принимать минимальное значение double[] x_values = new double[4]; // Набор значений x double x_answer; // Найденный ответ // Начало расчетов по методу Пауэлла LoggerEvs.writeLog("Powell's method has been started!"); // Шаг первый x_values[0] = searchInterval.LeftEdge; x_values[1] = 0.5 * (searchInterval.LeftEdge + searchInterval.RightEdge); x_values[2] = searchInterval.RightEdge; LoggerEvs.writeLog(string.Format("Step 1: (x1, x2, x3) = ({0:f4}, {1:f4}, {2:f4}).", x_values[0], x_values[1], x_values[2])); for (int iter = 0; !searchEnd; iter++) { // Шаг второй x_min = findMinimum(x_values[0], x_values[1], x_values[2], funcNumber); LoggerEvs.writeLog(string.Format("Step 2: x_min value, when function has minimum value: {0:f4}.", x_min)); // Шаг третий x_values[3] = findXFour(x_values[0], x_values[1], x_values[2], funcNumber); LoggerEvs.writeLog(string.Format("Step 3: count x4; x4 = {0:f4}.", x_values[3])); // Шаг четвертый if (Math.Abs(x_values[3] - x_min) <= eps) { LoggerEvs.writeLog(string.Format("Step 4: |x4 - x_min| <= eps, |{0:f4} - {1:f4}| <= {2:f4} go to step 7!", x_values[3], x_min, eps)); // Перейти на шаг седьмой, поиск окончен searchEnd = true; } else { // Шаг пятый LoggerEvs.writeLog("Step 5: Sorting x values: x1 < x2 < x3 < x4"); sort(ref x_values); // Шаг шестой double[] funcValues = new double[4]; // Вычислить значения функций от каждого аргумента for (int i = 0; i < 4; i++) funcValues[i] = countFunctionValue(funcNumber, x_values[i]); // Отсортировать аргументы, чтобы получить первые три, при которых значения функций будут наименьшими LoggerEvs.writeLog("Step 6: Sorting x values, for get first 3 values with which function's values will be minimal..."); sortXValues(ref x_values, funcValues); } } // Шаг седьмой x_answer = x_values[3]; LoggerEvs.writeLog(string.Format("Step 7: Answer is {0:f4}", x_values[3])); return x_answer; }
public static double findMinimum(Interval searchInterval, double eps, int funcNumber) { LoggerEvs.writeLog("Dichotomy method has been started!"); double x_end = 0; // Найденное значение x double x_1, x_2; // Границы промежуточных отрезков bool countStop = false; // Остановка расчетов double delta = eps / 10; // Константа "различимости" double f_x_1, f_x_2; LoggerEvs.writeLog("Counting: delta = eps / 10 = " + delta); for (int i = 0; !countStop; i++) { // Шаг первый x_1 = 0.5 * (searchInterval.LeftEdge + searchInterval.RightEdge) - delta; x_2 = 0.5 * (searchInterval.LeftEdge + searchInterval.RightEdge) + delta; LoggerEvs.writeLog(string.Format("Step 1: counting x_1 = {0:f4}, x_2 = {1:f4}", x_1, x_2)); // Шаг второй (вычисление) и третий (сравнение) f_x_1 = countFunctionValue(funcNumber, x_1); f_x_2 = countFunctionValue(funcNumber, x_2); if (f_x_1 <= f_x_2) { searchInterval.RightEdge = x_2; LoggerEvs.writeLog(string.Format("Step 3: f({0:f4}) = {1:f4} <= f({2:f4}) = {3:f4}; b = x_2 = {4:f4}.", x_1, f_x_1, x_2, f_x_2, x_2)); } else { searchInterval.LeftEdge = x_1; LoggerEvs.writeLog(string.Format("Step 3: f({0:f4}) = {1:f4} > f({2:f4}) = {3:f4}; a = x_1 = {4:f4}.", x_1, f_x_1, x_2, f_x_2, x_1)); } // Шаг четвертый double diff = (searchInterval.RightEdge - searchInterval.LeftEdge)/2; if ( diff < eps) { countStop = true; LoggerEvs.writeLog(string.Format("Step 4: (b-a)/2 = {0:f4} < eps = {1:f4}; STOP SEARCHING!", diff, eps)); } LoggerEvs.writeLog("Iter " + i + ": Answer is in the range: [" + searchInterval.LeftEdge.ToString("f4") + "; " + searchInterval.RightEdge.ToString("f4") + "]"); } // Шаг пятый x_end = (searchInterval.LeftEdge + searchInterval.RightEdge) / 2; // Вывод результата LoggerEvs.writeLog("Step 5: x_end = (a+b)/2; Minimum x* is: " + x_end.ToString("f4")); return x_end; }
private void btnCount_Click(object sender, EventArgs e) { // Кнопка "Рассчитать" нажата // Проверить размер шага if(correctDatainput()) { setFunctionNumber(); argInterval = DSKMethodCounter.countInterval(funcNumber, Convert.ToDouble(nudH.Value), Convert.ToDouble(nudX0.Value)); // Выбор метода расчета double answer = 0; if (rbDichotomy.Checked) { answer = DichotomyMethodCounter.findMinimum(argInterval, Convert.ToDouble(nudEpsilon.Value), funcNumber); tbDichotomyAnswer.Text = answer.ToString("f4"); } else if (rbPowell.Checked) { answer = PowellMethodCounter.findMinimum(argInterval, Convert.ToDouble(nudEpsilon.Value), funcNumber); tbPowellAnswer.Text = answer.ToString("f4"); } } }
public static Interval countInterval(int funcNumber, double h, double x_0) { LoggerEvs.writeLog("DSK method started!"); Interval answer = new Interval(0, 1); // Убрать инициализацию int functionNumber = 0; // Номер функции double f_x_0; // Значение функции в точке x_0 double f_x_0_h; // Значение функции в точке x_0 + h bool searchEnd = false; // Конец поиска List<double> x_values = new List<double>(); // Коллекция значений x_0 x_values.Add(x_0); // Шаг 1 f_x_0 = countFunctionValue(funcNumber, x_0); f_x_0_h = countFunctionValue(funcNumber, x_0 + h); int k = 0; LoggerEvs.writeLog("Step 1: f(x_0)=" + f_x_0.ToString("f4") + ", f(x_0 + h)=" + f_x_0_h.ToString("f4") + "; k=0;"); // Шаг 2 if (f_x_0 > f_x_0_h) { answer.LeftEdge = x_0; double x_tmp = x_0 + h; x_values.Add(x_tmp); k = 2; LoggerEvs.writeLog("Step 2: a=" + x_0.ToString("f4") + ", x_1=" + x_tmp.ToString("f4") + ", k=2; Go to step 4!"); // Перейти на шаг 4 } else { // Шаг 3 if (countFunctionValue(funcNumber, x_0 - h) >= f_x_0) { answer.LeftEdge = x_0 - h; answer.RightEdge = x_0 + h; LoggerEvs.writeLog("Step 3: a=" + answer.LeftEdge.ToString("f4") + ", b=" + answer.RightEdge.ToString("f4") + "; Go to step 6!"); // Перейти на шаг 6 searchEnd = true; } else { answer.RightEdge = x_0; x_values.Insert(1, x_0 - h); h = -h; k = 2; LoggerEvs.writeLog("Step 3: b=" + x_0.ToString("f4") + ", x_1=" + (x_0 - h).ToString("f4") + ", h=" + h.ToString("f4") + ", k=2."); } } while (!searchEnd) { // Шаг 4 x_values.Insert(k, 0); x_values[k] = x_0 + Math.Pow(2, k - 1) * h; LoggerEvs.writeLog("Step 4: x_k=" + x_values[k].ToString("f4")); // Шаг 5 if (countFunctionValue(funcNumber, x_values[k - 1]) <= countFunctionValue(funcNumber, x_values[k])) { if (h > 0) { answer.RightEdge = x_values[k]; LoggerEvs.writeLog("Step 5: h > 0; b=x_k=" + answer.RightEdge.ToString("f4")); } else { answer.LeftEdge = x_values[k]; LoggerEvs.writeLog("Step 5: h < 0; a=x_k" + answer.LeftEdge.ToString("f4")); } searchEnd = true; } else { if (h > 0) { answer.LeftEdge = x_values[k - 1]; LoggerEvs.writeLog("Step 5: h > 0; a=x_(k-1)=" + answer.LeftEdge.ToString("f4")); } else { answer.RightEdge = x_values[k - 1]; LoggerEvs.writeLog("Step 5: h > 0; b=x_(k-1)=" + answer.RightEdge.ToString("f4")); } // Перейти на шаг 4 k++; LoggerEvs.writeLog("k = k + 1 = " + k + "; Go to step 4!"); } } // Шаг 6 LoggerEvs.writeLog("Step 6: Interval is: [" + answer.LeftEdge.ToString("f4") + " ; " + answer.RightEdge.ToString("f4") + "]"); return answer; }