برنامه پیدا کردن ریشه های تابع با روش نابجایی — راهنمای کاربردی
در این مطلب، روش نوشتن برنامه پیدا کردن ریشه های تابع با روش نابجایی بیان و پیادهسازی آن در زبانهای برنامهنویسی گوناگون شامل «سیپلاسپلاس» (++C)، «جاوا» (Java)، «پایتون» (Python)، «سیشارپ» (#C) و «پیاچ پی» (PHP) انجام شده است.
برنامه پیدا کردن ریشه های تابع با روش نابجایی
تابعf(x) روی x و دو عدد a و b داده شده است؛ به طوری که، f(a)*f(b) < 0 وf(x) در [a, b] پیوسته است. در اینجا، f(x) نشانگر یک معادله جبری یا غیر جبری است. هدف، پیدا کردن ریشه تابع در بازه [a, b] (یا پیدا کردن مقدار x به طوری که f(x) برابر با ۰ باشد) است. مثال زیر در این راستا قابل توجه است.
ورودی: یک تابع از x، برای مثال x3 – x2 + 2 و دو مقدار a = -200 و b = 300 به طوری است که f(a)*f(b) < 0، یعنی f(a) و f(b) دارای علامتهای مخالف یکدیگر هستند.
خروجی: مقدار ریشه برابر است با: 1.00- یا هر مقدار دیگر نزدیک به ریشه.
توصیه میشود که پیش از مطالعه این نوشتار، مطلب «برنامه پیدا کردن ریشه های تابع با روش دو بخشی — راهنمای کاربردی» مطالعه شود. در این مطلب، روش نابجایی (Method Of False Position | Regula Falsi) مورد مطالعه قرار خواهد گرفت.
شباهتهای روش نابجایی با روش دوبخشی
روش نابجایی، شباهتهایی با «روش دوبخشی» (Bisection Method) دارد که در ادامه مورد بررسی قرار گرفتهاند.
- فرضیات مشابه: این روش نیز فرض میکند که تابع در بازه [a, b] پیوسته است و دو عدد a و b داده شدهاند، به طوری که f(a) * f(b) < 0.
- همیشه همگرا میشود: این روش نیز مانند روش دوبخشی، همیشه همگرا میشود؛ معمولا همگرایی در این روش، سریعتر از روش دوبخشی به وقوع میپیوندد. اما گاهی نیز همگرایی خیلی کندتر از روش دو بخشی اتفاق میافتد.
تفاوتهای روش نابجایی با روش دو بخشی
این دو روش در این رویکرد با یکدیگر متفاوت هستند که در روش نابجایی، وتری ترسیم میشود که دو نقطه a, f(a)]] و [b, f(b)] را به یکدیگر متصل میکند. سپس، نقطهای در نظر گرفته میشود که وتر، با محور x برخورد میکند و این نقطه، c نامیده میشود.
گامهای روش نابجایی
۱. معادله خطی که دو نقطه را به یکدیگر متصل میکند، نوشته میشود.
y – f(a) = ( (f(b)-f(a))/(b-a) )*(x-a)
اکنون، باید نقطهای پیدا شود که با x برخورد داشته باشد، بنابراین y = 0 قرار داده میشود.
x = a - (f(a)/(f(b)-f(a))) * (b-a)
x = (a*f(b) - b*f(a)) / (f(b)-f(a))
این، در واقع c است که در آن، c = x است.
۲. اگر f(c) == 0، پس c ریشه تابع است.
۳. در غیر این صورت، اگر f(c) != 0:
۱. اگر f(a)*f(c) < 0، پس ریشه بین a و c قرار دارد. بنابراین، تکرار برای a و c انجام میشود.
۲. در غیر این صورت، اگر f(b)*f(c) < 0، پس ریشه بین b و c قرار دارد. بنابراین، تکرار برای b و c انجام میشود.
۳. در غیر این صورت، تابع داده شده از یکی از فرضیات تبعیت نمیکند.
از آنجا که ممکن است ریشه، یک نقطه شناور باشد و در بدترین حالت به آرامی همگرا شود، تکرار به تعداد دفعات بسیار زیادی انجام میشود و همین موجب میشود تا پاسخ به ریشه نزدیکتر شود. در ادامه، پیادهسازی این روش در زبانهای برنامهنویسی گوناگون انجام شده است.
برنامه پیدا کردن ریشه های تابع با روش نابجایی در ++C
1// C++ program for implementation of Bisection Method for
2// solving equations
3#include<bits/stdc++.h>
4using namespace std;
5#define MAX_ITER 1000000
6
7// An example function whose solution is determined using
8// Bisection Method. The function is x^3 - x^2 + 2
9double func(double x)
10{
11 return x*x*x - x*x + 2;
12}
13
14// Prints root of func(x) in interval [a, b]
15void regulaFalsi(double a, double b)
16{
17 if (func(a) * func(b) >= 0)
18 {
19 cout << "You have not assumed right a and b\n";
20 return;
21 }
22
23 double c = a; // Initialize result
24
25 for (int i=0; i < MAX_ITER; i++)
26 {
27 // Find the point that touches x axis
28 c = (a*func(b) - b*func(a))/ (func(b) - func(a));
29
30 // Check if the above found point is root
31 if (func(c)==0)
32 break;
33
34 // Decide the side to repeat the steps
35 else if (func(c)*func(a) < 0)
36 b = c;
37 else
38 a = c;
39 }
40 cout << "The value of root is : " << c;
41}
42
43// Driver program to test above function
44int main()
45{
46 // Initial values assumed
47 double a =-200, b = 300;
48 regulaFalsi(a, b);
49 return 0;
50}
برنامه پیدا کردن ریشه های تابع با روش نابجایی در جاوا
1// java program for implementation
2// of Bisection Method for
3// solving equations
4import java.io.*;
5
6class GFG {
7
8 static int MAX_ITER = 1000000;
9
10 // An example function whose
11 // solution is determined using
12 // Bisection Method. The function
13 // is x^3 - x^2 + 2
14 static double func(double x)
15 {
16 return (x * x * x - x * x + 2);
17 }
18
19 // Prints root of func(x)
20 // in interval [a, b]
21 static void regulaFalsi(double a, double b)
22 {
23 if (func(a) * func(b) >= 0)
24 {
25 System.out.println("You have not assumed right a and b");
26 }
27 // Initialize result
28 double c = a;
29
30 for (int i = 0; i < MAX_ITER; i++)
31 {
32 // Find the point that touches x axis
33 c = (a * func(b) - b * func(a))
34 / (func(b) - func(a));
35
36 // Check if the above found point is root
37 if (func(c) == 0)
38 break;
39
40 // Decide the side to repeat the steps
41 else if (func(c) * func(a) < 0)
42 b = c;
43 else
44 a = c;
45 }
46 System.out.println("The value of root is : " + (int)c);
47 }
48
49 // Driver program
50 public static void main(String[] args)
51 {
52 // Initial values assumed
53 double a = -200, b = 300;
54 regulaFalsi(a, b);
55 }
56}
57
58// This article is contributed by vt_m
برنامه پیدا کردن ریشه های تابع با روش نابجایی در پایتون
1# Python3 implementation of Bisection
2# Method for solving equations
3
4MAX_ITER = 1000000
5
6# An example function whose solution
7# is determined using Bisection Method.
8# The function is x^3 - x^2 + 2
9def func( x ):
10 return (x * x * x - x * x + 2)
11
12# Prints root of func(x) in interval [a, b]
13def regulaFalsi( a , b):
14 if func(a) * func(b) >= 0:
15 print("You have not assumed right a and b")
16 return -1
17
18 c = a # Initialize result
19
20 for i in range(MAX_ITER):
21
22 # Find the point that touches x axis
23 c = (a * func(b) - b * func(a))/ (func(b) - func(a))
24
25 # Check if the above found point is root
26 if func(c) == 0:
27 break
28
29 # Decide the side to repeat the steps
30 elif func(c) * func(a) < 0:
31 b = c
32 else:
33 a = c
34 print("The value of root is : " , '%.4f' %c)
35
36# Driver code to test above function
37# Initial values assumed
38a =-200
39b = 300
40regulaFalsi(a, b)
41
42# This code is contributed by "Sharad_Bhardwaj".
برنامه پیدا کردن ریشه های تابع با روش نابجایی در #C
1// C# program for implementation
2// of Bisection Method for
3// solving equations
4using System;
5
6class GFG {
7
8 static int MAX_ITER = 1000000;
9
10 // An example function whose
11 // solution is determined using
12 // Bisection Method. The function
13 // is x^3 - x^2 + 2
14 static double func(double x)
15 {
16 return (x * x * x - x * x + 2);
17 }
18
19 // Prints root of func(x)
20 // in interval [a, b]
21 static void regulaFalsi(double a, double b)
22 {
23 if (func(a) * func(b) >= 0)
24 {
25 Console.WriteLine("You have not assumed right a and b");
26 }
27 // Initialize result
28 double c = a;
29
30 for (int i = 0; i < MAX_ITER; i++)
31 {
32 // Find the point that touches x axis
33 c = (a * func(b) - b * func(a))
34 / (func(b) - func(a));
35
36 // Check if the above found point is root
37 if (func(c) == 0)
38 break;
39
40 // Decide the side to repeat the steps
41 else if (func(c) * func(a) < 0)
42 b = c;
43 else
44 a = c;
45 }
46
47 Console.WriteLine("The value of root is : " + (int)c);
48 }
49
50 // Driver program
51 public static void Main(String []args)
52 {
53 // Initial values assumed
54 double a = -200, b = 300;
55 regulaFalsi(a, b);
56 }
57}
58
59// This code is contributed by Sam007.
خروجی قطعه کدهای بالا به صورت زیر است.
The value of root is : -1
این روش همیشه همگرا میشود و همگرایی در آن، معمولا سریعتر از روش دو بخشی اتفاق میافتد. اما در بدترین حالت ممکن است بسیار کند باشد.
اگر نوشته بالا برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای برنامه نویسی
- آموزش ساختمان دادهها
- مجموعه آموزشهای ساختمان داده و طراحی الگوریتم
- رنگآمیزی گراف به روش حریصانه — به زبان ساده
- الگوریتم دایجسترا (Dijkstra) — از صفر تا صد
- الگوریتم پریم — به زبان ساده
- متن کاوی (Text Mining) — به زبان ساده
^^