
- •Конспект лекций по дисциплине «алгоритмизация и программирование»
- •Лекция № 1. Основные понятия
- •Использование ключевого слова using
- •2: Int main()
- •4: Using std::cout; // Вместо этих двух строк можно записать
- •5: Using std::endl; /* одну: using namespace std;*/
- •20: Return 0;
- •Комментарии
- •Функции
- •Переменные
- •Лекция № 3. Операторы
- •Математические операторы
- •Математические функции
- •Логические операторы
- •Операторы отношения
- •Операторы переходов по условию
- •Лекция № 4. Циклы
- •Оператор goto
- •Оператор цикла while
- •Операторы break и continue
- •Оператор цикла do..While
- •Оператор цикла for
- •Int main ()
- •Лекция № 5. Массивы
- •Одномерные массивы
- •Int main()
- •Многомерные массивы
- •Массивы символов (строки)
- •Int main()
- •Лекция № 6. Некоторые простые алгоритмы
- •Поиск максимального (или минимального) числа из выборки чисел
- •Int main()
- •Пузырьковая сортировка (bubble sort)
- •Void exch(double &a, double &b)
- •Лекция № 7. Численное решение уравнений
- •Теоретические основы
- •Метод простого перебора
- •Int RootSearch (double p[], int n, double a, double b, double dx);
- •Int main ()
- •Int RootSearch (double p[], int n, double a, double b, double dx)
- •Метод половинного деления
- •Метод Ньютона-Рафсона
- •Лекция № 8. Основы объектно-ориентированного программирования
- •Введение
- •Void Meow();
- •Закрытые и открытые члены класса
- •Void Meow();
- •Int main()
- •Void Meow();
- •Лекция № 9. Конструкторы и деструкторы
- •Определение
- •Int Weight;
- •Файлы заголовков
- •Встраиваемые функции
- •Лекция № 10. Классы, содержащие другие классы как данные-члены
- •Сложные классы
- •Структуры
-
Метод половинного деления
Метод половинного
деления называется также методом
дихотомии
(от греческого – разделяю на две части).
Англоязычные народы называют его method
of bisection.
Этот метод
не самый скорый, однако наиболее надежный.
Он использует следующий принцип: если
корень находится в интервале
,
то произведение
.
При
использовании метода дихотомии вначале
определяют точку в середине отрезка:
.
Затем находят значение функции в этой
точке
.
Если
,
то корень заключен в интервале
,
а если
,
то – в интервале
.
Далее операцию деления повторяют с тем
отрезком, в котором может находиться
корень. Итерации продолжают до тех пор,
пока интервал поиска не станет меньше
заданной малой величины
:
.
Исходный
интервал
уменьшается до
после одного деления. А после
делений уменьшается до величины
.
Приравнивая
,
и решая это уравнение относительно
,
получим
. (7.3)
В листинге 7.2 представлена программа, решающая заданное уравнение методом половинного деления. Для определения количества делений используется формула (7.3). В данной программе помимо основной функции main() содержатся также функции Bisect()и Func(). В отличие от предыдущего примера (листинг 7.1) данные для вычислений вводятся в самой функции Bisect(), а функция main() используется только для вызова функции Bisect(). Такой подход считается более приемлемым.
Входной
аргумент filter
предназначен
для |контролируфильтрации
возможной сингулярности.
Устанавливая filter=1,
мы заставляем программу проверять,
уменьшается ли величина функции
с каждым делением интервала пополам.
Если нет, искомый «корень», является не
корнем, а сингулярностью. Если есть
уверенность, что сингулярность в данной
задаче отсутствует, следует установить:
filter=0.
Листинг 7.2. Решение уравнения методом дихотомии
#include <iostream.h>
#include <math.h>
int Bisect(); // Прототипы функций
double Func(double p[], int n, double x);
void main()
{
Bisect();
}
int Bisect()
{
int i, n, k, filter;
double p[10];
double a, b, x1, x2, x3, f1, f2, f3, tol, root;
cout<<"Input degree of polynomial: ";
cin>>n;
cout<<endl;
cout<<"Input function:\n";
for (i=0; i<(n+1); i++)
{
cin>>p[i];
}
cout<<endl;
cout<<"Input left limit: ";
cin>>a;
cout<<endl;
cout<<"Input right limit: ";
cin>>b;
cout<<endl;
cout<<"Input tol: ";
cin>>tol;
cout<<endl;
//filter=singularity filter: 0=off (default), 1=on.
cout<<"Input filter (0 or 1): ";
cin>>filter;
cout<<endl;
f1=Func(p, n, a);
if (f1==0.0)
{
root=a;
cout<<"Root: "<<root<<"\n";
char Res;
cin>>Res;
return 0;
}
f2=Func(p, n, b);
if (f2==0.0)
{
root=b;
cout<<"Root: "<<root<<"\n";
char Res;
cin>>Res;
return 0;
}
if (f1*f2>0)
{
cout<<"Root is not bracketed in ("<<a<<", "<<b<<")"<<"\n";
char Res;
cin>>Res;
return 0;
}
k=ceil(log(fabs(b-a)/tol)/log(2.0));
x1=a;
x2=b;
for (
i=1; i<(k+1); i++)
{
x3=0.5*(x1+x2);
f3=Func(p, n, x3);
if ((filter==1)&&(fabs(f3)>fabs(f1))&&(fabs(f3)>fabs(f2)))
{
cout<<"Root is not bracketed in ("<<a<<", "<<b<<")"<<"\n";
char Res;
cin>>Res;
return 0;
}
if (f3==0.0)
{
root=x3;
cout<<"Root: "<<root<<"\n";
char Res;
cin>>Res;
return 0;
}
if (f2*f3<0.0)
{
x1=x3;
f1=f3;
}
else
{
x2=x3;
f2=f3;
}
}
root=0.5*(x1+x2);
cout<<"Root: "<<root<<"\n";
char Res;
cin>>Res;
return 0;
}
double Func (double p[], int n, double x)
{
double Sum=0;
double y=1;
for (int i=0; i<(n+1); i++)
{
Sum=Sum+p[i]*y;
y=y*x;
}
return Sum;
}