Метод парабол. Найти минимум заданной функции [latex]y=f(x)[/latex], двигаясь от заданной точки [latex]x_{0}[/latex] по методу парабол:
[latex]x_{i+1}=x_{i}-\frac{h}{2}\frac{f\left( x_{i}+h\right)-f\left( x_{i}-h\right)}{f\left( x_{i}+h\right)-2f\left( x_{i}\right)+f\left( x_{i}-h\right)}, i=0,1,\ldots[/latex], пока не будет достигнута заданная точность.Функция [latex]x^{3}+10\sin (5x)[/latex]:
[latex]x_{0}[/latex] | [latex]\varepsilon[/latex] | Точка минимума по графику. | Точка минимума по программе. | Комментарий. |
0 | 0,001 | -0,315353 | -0,315353 | Тест пройден. |
1 | 0,0001 | 0,932048 | 0,932048 | Тест пройден. |
2 | 0,0001 | 2,14327 | 2,14327 | Тест пройден. |
-3 | 0,01 | -2,93616 | -2,93616 | Тест пройден. |
-2 | 0,0001 | -1,6017 | -1,6017 | Тест пройден. |
Код программы (C++):
Для функции [latex]x^{3}+10\sin (5x)[/latex] (функцию всегда можно изменить, достаточно исправить строку 6):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#include <iostream> #include <math.h> using namespace std; double f(double x) { return x*x*x+10*sin(5*x); } int main() { double h=0.001; double x, pogr; cin >> x >> pogr; if (x==0) x+=0.1; while ((f(x+h)-2*f(x)+f(x-h))/(h*h)<=0) x+=0.1; double x1; x1=x-0.5*h*(f(x+h)-f(x-h))/(f(x+h)-2*f(x)+f(x-h)); while (fabs(x1-x)>pogr) { x=x1; x1=x-0.5*h*(f(x+h)-f(x-h))/(f(x+h)-2*f(x)+f(x-h)); } cout << x1; return 0; } |
Java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
import java.util.*; import java.lang.*; import java.io.*; class Ideone { public static double f (double x) { return x*x*x+10*Math.sin(5*x); } public static void main (String[] args) throws java.lang.Exception { Scanner in = new Scanner (System.in); double h=0.001; double x, pogr; x=in.nextDouble(); pogr=in.nextDouble(); if (x==0) x+=0.1; while ((f(x+h)-2*f(x)+f(x-h))/(h*h)<=0) x+=0.1; double x1; x1=x-0.5*h*(f(x+h)-f(x-h))/(f(x+h)-2*f(x)+f(x-h)); while (Math.abs(x1-x)>pogr) { x=x1; x1=x-0.5*h*(f(x+h)-f(x-h))/(f(x+h)-2*f(x)+f(x-h)); } System.out.format ("%f%n", x1); } } |
Чтобы сделать программу, я почитала “Численные методы” Н. Н. Калиткина, где и было сказано, что в качестве вспомогательного шага [latex]h[/latex] при расчётах на ЭВМ обычно выбирают значение 0,001.
Далее пользователю предоставляется возможность ввести значение [latex]x_{0}[/latex] и задать точность [latex]\varepsilon[/latex]. Корень [latex]x[/latex] является минимумом функции тогда и только тогда, когда вторая производная этой функции больше 0. Поэтому мы запускаем цикл, который будет сдвигать наше [latex]x_{0}[/latex] в положительном направлении оси [latex]x[/latex], пока вторая производная функции не будет удовлетворять условию задачи.
Далее мы вычисляем значение [latex]x_{i+1}[/latex], и запускаем цикл, который будет продолжаться до тех пор, пока разница между [latex]x_{i}[/latex] и [latex]x_{i+1}[/latex] не будет меньше заданной погрешности [latex]\varepsilon[/latex].
Затем на экран выводится сама точка минимума функции.
Программу можно посмотреть здесь (C++) и здесь (Java).
— Не нужно повторять номер задачи в начале условия.
— Забыли сделать ссылку на код в ideOne?
— Рисунок и значения минимума для тестирования лучше взять отсюда.
— Не проще было так сделать?
— Вы даёте ссылку на книгу Н.Н.Калиткина «Численные методы». Лучше указать источник.
— Запустил первый тест. Не сработало.
Исправила: номер задачи, вставила ссылку на ideOne (изначально её не было, так как программа писалась не там), график и тесты взяла с вольфрама, исправила ссылку на источник, исправила баг с первым тестом.
Спасибо за замечания.
«Тесты (в виде графиков, так как посчитать это я не представляю возможным»
Я же дал ссылку, где указано несколько минимумов. Почему нельзя указать их в тестах?
Протестировал для 5 0.0001. Получил 2.93616. Это точка максимума, а не минимума.
Я зачёл Вам работу, несмотря на указанную проблему, поскольку задача слишком сложна для начинающих математиков. Вы можете продолжать работать над ней, когда будет время. Задача интересная.
Формулы не отображаются. Что-то случилось?