"Математика и алгоритмы". Выпуск 5.
Здравствуйте! Сегодняшний выпуск является логичным продолжением предыдущих и
посвящен
вопросам решения нелинейных уравнений и систем нелинейных уравнений.
Нелинейные уравнения (чаще системы таких уравнений) встречаются на практике значительно
чаще линейных,
что обусловлено, в первую очередь, нелинейностью математических моделей нашего
мира.
Для начала рассмотрим простенькие методы численного решения одного нелинейного
уравнения.
Метод дихотомии.
Основная идея алгоритма: разбиваем отрезок пополам и получаем третию точку.
Если значение от третьей точки меньше значения от первой точки, то третью объявляем
первой
точкой и т.д., иначе - объявляем второй точкой. Один нюанс: нужно пробежать набор
точек
так чтобы значение от 3-й точки было меньше значения от последующей
Если это не выполняется, то 3-я точка оъявляется второй и повторяется до тех
пор,
пока разница между первой и второй точкой не будет меньше \epsilon.
Весьма важным при этом является условие унимодельности функции f(x) из уравнения
f(x)=0.
При выполнении условия унимодельности можно применять метод дихотомии.
Пример программы на Си (данная программа не претендует на оптимальность, но полезна
в качестве материала для изучения).
-------------------------------------------------------------
float f(float x) {return exp(x*x)-x*x+4*x+10+sin(x);}
void unimod(float a, float b)
{
int i,k=0;
float h,x1,x2,b1,a1,g,d1,eps=0.01;
b1=b;
a1=a;
m1: if ((b1-a1)>eps)
{k++;
h=(b1-a1)/13;
g=a1;
while(g<b1)
{ if (f(g+h)>f(g))
{ b1=g+h;
a1=g;
goto m1;
}
g=g+h;
}
}
x1=a1;
b1=b;
a1=a;
m2: if ((b1-a1)>eps)
{h=(b1-a1)/13;
g=b1;
while(g>=a1)
{ if (f(g-h)>=f(g))
{ a1=g-h;
b1=g;
goto m2;
}
g=g-0.01;
}
}
x2=b1;
cout<<"минимум справа="<<x2<<" минимум слева "<<x1<<"\n";
if (fabs(x1-x2)<eps)
cout<<"Функция на данном отрезке унимодальна\n";
else cout<<"Функция на данном отрезке не Унимодальна\n";
cout<<"точность="<<eps<<"\n\n";
}
float delenie(float a,float b)
{
int i,k=0;
float h,g,d1,eps=0.001;
m1: if ((b-a)>eps)
{k++;
h=(b-a)/13;
g=a;
while(g<b)
{ if (f(g+h)>f(g))
{ b=g+h;
a=g;
goto m1;
}
g=g+h;
}
}
cout<<"епсилон="<<eps<<"\n";
cout<<"колличество итераций="<<k<<"\n";
cout<<"x_min="<<a<<"\n";
return f(a);
};
void main()
{clrscr();
cout<<" функция e^(3x)-x^(3)+2x на [-4;1]\n";
unimod(-4,1);
cout<<"Дихотомия\n";
cout<<"f_min="<<delenie(-4,1)<<"\n";
}
-------------------------------------------------------------
Результаты работы программы
функция e^(3x)-x^(3)+2x на [-4;1]
минимум справа=-0.869999 минимум слева -0.861629
Функция на данном отрезке унимодальна
точность=0.01
Деление
епсилон=0.001
колличество итераций=4
x_min=-0.861454
f_min=-1.008176