Есть задание
Найти методом деления отрезка пополам минимум функции f(x) = 7sin(2x)
на отрезке [2, 6] с заданной точностью ε (например, 0.01).
Разумеется, его нужно написать
#include <iostream>
#include <math.h>
#include <stdlib.h>
using namespace std;
const double eps = 0.01;
double a, b, t, x, y, t1, s;
double func(double a, double b)
{
s = (a + b) / 2;
y = (7 * sin(2)*s);
return y;
}
int main()
{
a = 2;
b = 6;
while (abs(b - a) < eps);
{
t = (a + b) / 2.0;
y = 7 * sin(2)*(t - eps);
x = 7 * sin(2)*(t + eps);
if (y <= x)
{
a = t;
t1 = func(a, b);
}
else
{
b = t;
t1 = func(a, b);
}
}
cout << "Otvet: " << t1;
return 0;
}
Проблема в том, что преподаватель говорит, что задача решена не рекурсивно. Я утверждаю что решение рекурсивно, так как функция double func
принимает значение из функции int main
. Прав ли я?
Верно будет так (примерны код):
rec(double a, double b){
(здесь все ваши действия с синусами)
if (abs(b - a) < eps) // проверяем новые значения - надо еще раз пересчитать?
rec(a, b) // вызываем саму себя с новыми значениями
else return ... // иначе - возвращаем ответ
}
И в мейне вызываем эту функцию,не забыв передать в нее начальные a и b
Нет, это решение не является рекурсивным. Рекурсия предполагает вызов функции из себя (прямо или косвенно), а в приведённом решении ничего подобного нет.
Более того, приведённое решение визуально кажется мне неверным. Функция не является монотонной, поэтому всякие шаманства со знаками применять, скорее всего, не следует.
На мой взгляд, правильным будет проверять весь отрезок полностью (в условии сказано "методом деления отрезка пополам", но не сказано, что это должен быть бинпоиск, отсекающий половину отрезка).
http://ideone.com/fyRCVW
#include <iostream>
#include <cmath>
using namespace std;
const double EPS = .01;
double f(double x)
{
return 7 * sin(2*x);
}
double solve(double l, double r)
{
double m = l / 2 + r / 2;
if (r-l < EPS)
return m;
double x1 = solve(l, m), x2 = solve(m, r);
return f(x1) < f(x2) ? x1 : x2;
}
int main()
{
cout << solve(2, 6);
return 0;
}
Ответ: 2.35547
.
Рекурсия достигается в вашем случае с изменением "входимости кода" на уровень выше. Оберните цикл while (точнее, замените цикл на рекурсивный вызов) в функцию, и будет вам то, что хочет препод.
Вот готовое решение:
// Найти методом деления отрезка пополам минимум функции f(x) = 7sin(2x) на отрезке [2, 6] с заданной точностью ε (например, 0.01).
#include <iostream>
#include <math.h>
#include <stdlib.h>
using namespace std;
const double eps = 0.01;
double a, b, t, x, y, t1, s;
double func(double a, double b, double e)
{
s = (a + b) / 2 ;
t1 = 7 * sin(2*s + e) ;
return t1;
}
void JustDoIt(double &a,double &b)
{
t = (a + b) / 2.0;
y = func(a, b, - eps);
x = func(a, b, eps);
if (y >= x) a = t;
else b = t;
// чек-блок
cout << "t= " << t <<"\n";
cout << "a= " << a <<" b=" << b <<"\n";
cout << "x= " << x <<" y=" << y <<"\n";
cout << "fabs(b - a)= " << fabs(b - a) <<"\n";
//
if ( fabs(b - a) < eps) return;
JustDoIt( a, b);
}
int main()
{
a = 2;
b = 6;
JustDoIt( a, b);
cout << "Otvet: " << func(a, b,0)<<"\n";
return 0;
}
Вывод:
a= 4 b=6
x= 6.91498 y=6.93535
fabs(b - a)= 2
a= 5 b=6
x= -3.86669 y=-3.74922
fabs(b - a)= 1
a= 5 b=5.5
x= -6.99927 y=-6.99989
fabs(b - a)= 0.5
a= 5.25 b=5.5
x= -6.19085 y=-6.12428
fabs(b - a)= 0.25
a= 5.375 b=5.5
x= -6.80666 y=-6.77263
fabs(b - a)= 0.125
a= 5.4375 b=5.5
x= -6.95725 y=-6.94041
fabs(b - a)= 0.0625
a= 5.46875 b=5.5
x= -6.99191 y=-6.98379
fabs(b - a)= 0.03125
a= 5.48438 b=5.5
x= -6.99901 y=-6.99525
fabs(b - a)= 0.015625
a= 5.49219 b=5.5
x= -6.99999 y=-6.99843
fabs(b - a)= 0.0078125
Otvet: -6.99996
попутно выявились ошибки в вашем коде: while не выполняется из-за ";" , а блок затем проходит только один раз и вместо abs() нужно использовать fabs().
#include <iostream>
#include <math.h>
#include <stdlib.h>
using namespace std;
const double eps = 0.01;
double a, b, t, x, y, t1, s;
double func(double a, double b)
{
s = (a + b) / 2;
t1 = (7 * sin(2)*s);
return t1;
}
double rec(){
while (abs(b - a) < eps);
{
t = (a + b) / 2.0;
y = 7 * sin(2)*(t - eps);
x = 7 * sin(2)*(t + eps);
if (y <= x)
{
a = t;
t1 = func(a, b);
}
else
{
b = t;
t1 = func(a, b);
}
}
}
int main()
{
a = 2;
b = 6;
rec();
cout << "Otvet: " << t1;
return 0;
}
Виртуальный выделенный сервер (VDS) становится отличным выбором
Есть элемент stringgrid в который я вношу данные, могу добавлять, изменять через отдельные формы и результат сохраняется в stringgridНеобходимо сделать...
Использую Вулкан и GLFW для работы в полноэкранном режимеЕсть проблема - при выходе из приложения или просто переключении на рабочий стол возникает...
Как подключить библиотеку SFML к CLion проекту?
Зачем нужен std::vector<>, если есть потенциально более быстрый std::valarray<>?