الفرنسية: Méthode de dichotomie
المبدأ
ننشئ متتالية مجال [an, bn]، تضم الجدر ، بحيث an أو bn تكون منتصف المجال السابق [an-1, bn-1] .
الخوارزم
ليكن و بحيث f(a) f(b) < 0
تهيئ: a0 = a, b0 = b
تكرار:
مثال
نعتبر المعادلة : f(x) = (x+3)/(x-1) - x + 2 = 0
هذه المعادلة تقبل جذرين هما : 2 + و 2 -
حساب رقمي للجذر السالب، نعتبر مجال الانطلاقa = -1 وb = 0 .
الكرتان الأوليتان
f(a0) = f(-1) = (-1+3)/(-1-1) - (-1) + 2 = 2
f(b0) = f(0) = (0+3)/(0-1) - 0 + 2 = -1
c1 = (a0+b0)/2 = (-1 + 0)/2 = -1/2
f(c1) = f(-1/2) = (-1/2+3)/(-1/2-1) - (-1/2) + 2 = 5/6
f(a0) و لهما نفس الإشارة f(c1)
a1 = c1 = -1/2 , b1 = b0 = 0
f(a1) = f(c1) = 5/6 , f(b1) = f(b0) = -1
c2 = (a1+b1)/2 = (-1/2 + 0)/2 = -1/4
f(c2) = f(-1/4) = (-1/4+3)/(-1/4-1) - (-1/4) + 2 = 1/20
f(a1) و f(c2) لهما نفس الإشارة
a2 = c2 = -1/4 , b2 = b1 = 0
البرمجة
#include <math.h> #include <conio.h> #define ITERMAX 51
double eq_f(double x) { return((x+3.0)/(x-1.0)-x+2.0); }
void eq_dicho(double a,double b,double eps,double t[ITERMAX]);
main() { int i; double a,b,eps,vr_rac,err,c; double t[ITERMAX]; clrscr(); vr_rac=2.0-sqrt(5.0); printf("Méthode de Dichotomie\n"); a=-1.0;b=0.0;eps=1e-16; eq_dicho(a,b,eps,t); for(i=1;i<ITERMAX;i++) if (t[i]!=0) { err=fabs(t[i]-vr_rac); printf("c%2d = %.17e err = %.3e",i,t[i],err); printf("\n"); } }
نتيجة البرنامج
c 1 = -5.0000000000000000e-01 err = 2.64e-01 c 2 = -2.5000000000000000e-01 err = 1.39e-02 c 3 = -1.2500000000000000e-01 err = 1.11e-01 c 4 = -1.8750000000000000e-01 err = 4.86e-02 c 5 = -2.1875000000000000e-01 err = 1.73e-02 c 6 = -2.3437500000000000e-01 err = 1.69e-03 c 7 = -2.4218750000000000e-01 err = 6.12e-03 c 8 = -2.3828125000000000e-01 err = 2.21e-03 c 9 = -2.3632812500000000e-01 err = 2.60e-04 c10 = -2.3535156250000000e-01 err = 7.16e-04 c11 = -2.3583984375000000e-01 err = 2.28e-04 c12 = -2.3608398437500000e-01 err = 1.60e-05 c13 = -2.3596191406250000e-01 err = 1.06e-04 c14 = -2.3602294921875000e-01 err = 4.50e-05 c15 = -2.3605346679687500e-01 err = 1.45e-05 c16 = -2.3606872558593750e-01 err = 7.48e-07 c17 = -2.3606109619140625e-01 err = 6.88e-06 c18 = -2.3606491088867188e-01 err = 3.07e-06 c19 = -2.3606681823730469e-01 err = 1.16e-06 c20 = -2.3606777191162109e-01 err = 2.06e-07 c21 = -2.3606824874877930e-01 err = 2.71e-07 c22 = -2.3606801033020020e-01 err = 3.28e-08 c23 = -2.3606789112091064e-01 err = 8.64e-08 c24 = -2.3606795072555542e-01 err = 2.68e-08 c25 = -2.3606798052787781e-01 err = 3.03e-09 c26 = -2.3606796562671661e-01 err = 1.19e-08 c27 = -2.3606797307729721e-01 err = 4.42e-09 c28 = -2.3606797680258751e-01 err = 6.97e-10 c29 = -2.3606797866523266e-01 err = 1.17e-09 c30 = -2.3606797773391008e-01 err = 2.34e-10 c31 = -2.3606797726824880e-01 err = 2.32e-10 c32 = -2.3606797750107944e-01 err = 1.29e-12 c33 = -2.3606797738466412e-01 err = 1.15e-10 c34 = -2.3606797744287178e-01 err = 5.69e-11 c35 = -2.3606797747197561e-01 err = 2.78e-11 c36 = -2.3606797748652752e-01 err = 1.33e-11 c37 = -2.3606797749380348e-01 err = 5.99e-12 c38 = -2.3606797749744146e-01 err = 2.35e-12 c39 = -2.3606797749926045e-01 err = 5.29e-13 c40 = -2.3606797750016995e-01 err = 3.80e-13 c41 = -2.3606797749971520e-01 err = 7.45e-14 c42 = -2.3606797749994257e-01 err = 1.53e-13 c43 = -2.3606797749982888e-01 err = 3.92e-14 c44 = -2.3606797749977204e-01 err = 1.77e-14 c45 = -2.3606797749980046e-01 err = 1.08e-14 c46 = -2.3606797749978625e-01 err = 3.44e-15 c47 = -2.3606797749979336e-01 err = 3.66e-15 c48 = -2.3606797749978981e-01 err = 1.11e-16 c49 = -2.3606797749978803e-01 err = 1.67e-15 c50 = -2.3606797749978892e-01 err = 7.77e-16
الدالة الرئيسية eq_dicho
معايير هذه الدالة هي كالتالي:
a و b: حدي المجال ]a, b[
eps : الدقة المطلوبة
t : جدول ذي الدرجة ITERMAX.
تستدعي الدالة الرئيسة دالة أخرى هي كالتالي:
double eq_f(double x)
التي يجب أن تعرف في البرنامج الأساسي وهي تمثل الدالة الرياضية f.
ترجع الدالة في الجدول t التكرارات المتتالية للخوارزم الثنائي.
الثابتة الصحيحة ITERMAX تساوي العدد القصوي للتكرارات المطلوبة (+1).
void eq_dicho(double a,double b,double eps,double t[ITERMAX])
{
double c,fa,fb,fc;
int n,stop;
for(n=0;n<ITERMAX;n++)
t[n]=0;
n=0;
stop=0;
fa=eq_f(a);
fb=eq_f(b);
if(fa*fb > 0) stop=1;
if(fa==0) {t[1]=a;stop=1;}
if(fb==0) {t[1]=b;stop=1;}
while ((b-a > eps) && (stop==0) && (n < ITERMAX-1))
{
n++;
c=(a+b)/2.0;
fc=eq_f(c);
t[n]=c;
if(fc != 0)
{
if(fa*fc > 0)
{
a=c;
fa=fc;
}
else
{
b=c;
fb=fc;
}
}
else stop=1;
}
}