TRƯỜNG ĐẠI HỌC CÔNG NGHIỆP VIỆT - HUNG
KHOA CÔNG NGHỆ THÔNG TIN
…..o0o…..
BÁO CÁO KẾT THÚC HỌC PHẦN
LINUX VÀ PHẦN MỀM MÃ NGUỒN
MỞ
Giảng viên hướng dẫn
: Ths.Hà Đăng Tồn
Nhóm sinh viên thực hiện
: Nguyễn Khắc Mạnh
: Phùng Quang Huy
Lớp
: K43CNT2
*
Hà Nội - Năm 2023
MỤC LỤC
Phần A: GIẢI THUẬT MÜLLER'S METHOD...................................................1
1.1. Müller's method là gì...................................................................................................................1
1.2. Tài liệu Müller's method..............................................................................................................1
1.3. Mã giả..........................................................................................................................................4
1.4. Kết quả đạt được.........................................................................................................................6
1.4.1. Mã nguồn chương trình.......................................................................6
1.4.2. Chương trình chạy kiểm thử................................................................9
DANH MỤC TÀI LIỆU THAM KHẢO..............................................................1
NHẬN XÉT...........................................................................................................2
KÍ HIỆU CÁC CỤM TỪ VIẾT TẮT
OS
Operating System
Phần A: GIẢI THUẬT MÜLLER'S METHOD
A.1. Müller's method là gì
Phương pháp Muller là một thuật tốn tìm nghiệm cho việc tìm nghiệm của một
phương trình dạng f(x) = 0. Nó được khám phá bởi David E. Muller vào năm 1956.
Thuật toán bắt đầu bằng ba ước đoán ban đầu về nghiệm, sau đó xây dựng một
đường parabol thơng qua ba điểm này và lấy giao điểm của trục x với đường parabol
làm ước tính tiếp theo. Q trình này tiếp tục cho đến khi tìm thấy một nghiệm với độ
chính xác mong muốn.
Phương pháp Muller là một trong những phương pháp tìm nghiệm cùng với các
phương pháp khác như Phương pháp Chia đôi, Phương pháp Regula - Falsi, Phương
pháp Tiếp tuyến và Phương pháp Newton - Raphson. Nhưng nó cung cấp một số lợi
ích so với các phương pháp này, như sau:
Tốc độ hội tụ, tức là khoảng cách chúng ta di chuyển gần hơn đến nghiệm ở mỗi
bước, là khoảng 1,84 ở Phương pháp Muller, trong khi nó là 1,62 cho phương pháp
Tiếp tuyến và là tuyến tính, tức là 1 cho cả Phương pháp Regula - falsi và Phương
pháp Chia đơi. Do đó, Phương pháp Muller nhanh hơn so với Phương pháp Chia đôi,
Regula - Falsi và Phương pháp Tiếp tuyến.
Mặc dù vậy, nó chậm hơn Phương pháp Newton - Raphson, có tốc độ hội tụ là 2,
nhưng nó vượt qua một trong những điểm hạn chế lớn nhất của Phương pháp NewtonRaphson, đó là tính đạo hàm ở mỗi bước.
A.2. Tài liệu Müller's method
Nhắc lại rằng phương pháp secant (tangent tiếp tuyến) tìm một ước lượng nghiệm
bằng cách vẽ một đường thẳng nối hai giá trị hàm số tại hai điểm trên trục hồnh (Hình
7.3a). Phương pháp của Müller cũng tương tự nhưng thay vì dùng đường thẳng, sử
dụng một đường parabol đi qua ba điểm (Hình 7.3b).
Phương pháp này bao gồm việc tìm các hệ số của đường parabol đi qua ba điểm
đó. Sau đó, các hệ số này được thay vào công thức bậc hai để tìm ra điểm mà đường
parabol cắt trục hồnh - đó chính là ước lượng nghiệm. Phương pháp này được dễ
dàng hơn khi viết phương trình của đường parabol dưới dạng thuận tiện.
f 2 ( x ) a ( x x2 ) 2 b( x x2 ) c
Chúng ta muốn đường parabol này cắt qua ba điểm [x0, f(x0)], [x1, f(x1)], và [x2,
f(x2)]. Hệ số của phương trình (7.17) có thể được tính bằng cách thay thế từng điểm
trong số ba điểm để được.
f ( x0 ) a ( x0 x2 )2 b ( x0 x2 ) c
f ( x1 ) a ( x1 x2 ) 2 b( x1 x2 ) c
f ( x2 ) a ( x2 x2 )2 b ( x2 x2 ) c
Lưu ý rằng chúng ta bỏ chỉ số “2” của hàm số để gọn hơn. Vì chúng ta có ba
phương trình, nên có thể giải cho ba hệ số không biết a, b, và c. Vì hai trong số các
thuật ngữ trong phương trình (7.20) bằng khơng, nó có thể được giải ngay lập tức để
tìm c f ( x2 ) Do đó, hệ số c đơn giản chỉ bằng giá trị của hàm số tại điểm thử thứ ba,
x2. Kết quả này sau đó có thể được thay vào các phương trình (7.18) và (7.19) để thu
được hai phương trình với hai hệ số không biết:
f ( x0 ) f ( x2 ) a( x0 x2 ) 2 b( x0 x2 )
f ( x1 ) f ( x2 ) a ( x1 x2 ) 2 b( x1 x2 )
Sau đó, ta có thể sử dụng phép biến đổi đại số để giải cho các hệ số còn lại, a và b.
Một cách để làm điều này là định nghĩa một số hiệu khác nhau,
h0 x1 x0
0
h1 x2 x1
f ( x1 ) f ( x0 )
x1 x0
1
f ( x2 ) f ( x1 )
x2 x1
Sau đó, chúng ta có thể thay các hiệu này vào các phương trình (7.21) và (7.22) để
được:
h0 h1 b h0 h1
h1b h 21 a h11
2
a h0 0 h11
Từ đó, ta có thể giải phương trình để tìm a và b. Kết quả có thể được tóm tắt như
sau:
1 0
h1 h0
b ah1 1
a
c f x2
Để tìm nghiệm, chúng ta áp dụng cơng thức bậc hai cho phương trình (7.17). Tuy
nhiên, do lỗi làm trịn có thể xảy ra, thay vì sử dụng dạng thông thường, chúng ta sử
dụng công thức thay thế [phương trình (3.13)] để được:
x3 x2
2c
b b 2 4ac
Hoặc cô lập x3 không xác định ở phía trái dấu bằng, ta được:
x3 x2
2c
b b 2 4ac
Lưu ý rằng việc sử dụng cơng thức bậc hai có nghĩa là có thể tìm được cả các
nghiệm thực và phức. Điều này là một lợi ích lớn của phương pháp.
Ngồi ra, Phương trình (7.27a) cung cấp một phương pháp gọn nhẹ để xác định sai
số xấp xỉ. Bởi vì phía trái đại diện cho sự khác biệt giữa ước tính nghiệm hiện tại (x 3)
và trước đó (x2), nên sai số có thể được tính tốn như sau.
a
x3 x2
100%
x3
Một vấn đề với Phương trình (7.27a) là nó cho ra hai nghiệm, tương ứng với dấu 6
trong mẫu số. Trong phương pháp Müller, chọn dấu phù hợp với dấu của b. Lựa chọn
này sẽ dẫn đến mẫu số lớn nhất và do đó, sẽ cho ước tính nghiệm gần nhất với x 2.
Sau khi xác định được x3, quá trình được lặp lại. Điều này đưa ra vấn đề về việc bỏ
đi điểm nào. Hai chiến lược chung thường được sử dụng:
1. Nếu chỉ tìm các nghiệm thực, chúng ta chọn hai điểm ban đầu gần nhất với
ước tính nghiệm mới, x3.
2. Nếu cả nghiệm thực và phức đều được đánh giá, phương pháp tuần tự được
áp dụng. Tức là, giống như phương pháp tiếp tuyến, x 1, x2, và x3 thay thế
cho x0, x1, và x2.
A.3. Mã giả
SUB Muller(xr, h, eps, maxit)
x2 5 xr
x1 5 xr 1 h*xr
x0 5 xr 2 h*xr
DO
iter 5 iter 1 1
h0 5 x1 2 x0
h1 5 x2 2 x1
d0 5 (f(x1) 2 f(x0)) / h0
d1 5 (f(x2) 2 f(x1)) / h1
a 5 (d1 2 d0) / (h1 1 h0)
b 5 a*h1 1 d1
c 5 f(x2)
rad 5 SQRT(b*b 2 4*a*c)
If |b1rad| . |b2rad| THEN
den 5 b 1 rad
ELSE
den 5 b 2 rad
END IF
dxr 5 22*c y den
xr 5 x2 1 dxr
PRINT iter, xr
IF (|dxr| , eps*xr OR iter .5 maxit) EXIT
x0 5 x1
x1 5 x2
x2 5 xr
END DO
END Müller
Đây là một đoạn mã (code) bằng ngơn ngữ lập trình khơng rõ ràng ràng về định
dạng, tuy nhiên có thể hiểu được rằng đây là thuật toán Muller's Method được triển
khai trong hàm `SUB Muller(xr, h, eps, maxit)`:
Đầu vào: `xr` là giá trị ban đầu, `h` là khoảng cách giữa `xr` và `x1`, `eps` là độ
lỗi mong muốn, `maxit` là giới hạn số lần lặp.
Ở đoạn lệnh tiếp theo, thuật toán sẽ lặp lại cho đến khi đạt được độ chính xác
mong muốn hoặc đạt được giới hạn số lần lặp được xác định trước:
Trong q trình lặp lại, thuật tốn sẽ lần lượt tính các giá trị `h0, h1, d0, d1, a, b,
c` để xác định các hệ số của đa thức bậc hai tương ứng. Lặp lại đoạn lệnh này cho đến
khi đủ độ chính xác, thuật tốn sẽ tính tốn nghiệm gần đúng và in ra kết quả sau mỗi
lần lặp. Ngoài ra, các giá trị `x0, x1, x2` sẽ được cập nhật trong q trình lặp lại để tính
tốn các giá trị mới.
Cuối cùng, thuật toán sẽ trả về giá trị là `xr` - nghiệm gần đúng của phương trình
f(x) = 0.
A.4. Kết quả đạt được
A.4.1. Mã nguồn chương trình
Đây là một đoạn mã Python triển khai thuật toán Muller's Method để giải phương
trình phi tuyến. Bên dưới là giải thích chi tiết từng phần của đoạn code này:
1. Dòng đầu tiên khai báo thư viện math và kiểu trả về Tuple.
import math
from typing import Tuple
2. Hàm `f(x)` được định nghĩa để tính giá trị của hàm số f(x). Trong đoạn code
này, hàm `f(x)` được lựa chọn là `f(x)= x^3 - 13x - 12`.
def f(x):
return (x**3 - 13 * x - 12)
3. Hàm `muller(xr, h, eps, maxit)` được triển khai theo thuật tốn Muller's
Method để giải phương trình phi tuyến. Các tham số đầu vào cho hàm này bao
gồm:
`xr`: giá trị đầu vào để bắt đầu thuật toán
`h`: khoảng cách giữa `x2` và `x1`
`eps`: độ lỗi mong muốn
`maxit`: số lần lặp tối đa.
def muller(xr: float, h: float, eps: float, maxit: int) -> Tuple[float, int]:
4. Các biến cần thiết được khởi tạo:
a. `x0`, `x1`, `x2` là các giá trị `xr` ban đầu cùng với khoảng cách `h`.
b. `iter` là biến đếm số vòng lặp.
x0 = xr - h * xr
x1 = xr + h * xr
x2 = xr
iter = 0
5. Lặp lại việc tính tốn giá trị của `xr` đến khi đạt được độ chính xác cần thiết
hoặc đến khi số lần lặp của vòng lặp đạt giới hạn tối đa.
print(iter, xr)
while True:
iter += 1
# tính các giá trị cần thiết
h0 = x1 - x0
h1 = x2 - x1
d0 = (f(x1) - f(x0)) / h0
d1 = (f(x2) - f(x1)) / h1
a = (d1 - d0) / (h1 + h0)
b = a * h1 + d1
c = f(x2)
rad = math.sqrt(b ** 2 - 4 * a * c)
if abs(b + rad) > abs(b - rad):
den = b + rad
else:
den = b - rad
dxr = -2 * c / den
xr = x2 + dxr
print(iter, xr)
if abs(dxr) < eps * xr or iter >= maxit:
break
x0 = x1
x1 = x2
x2 = xr
a. Các biến `h0`, `h1`, `d0`, `d1`, `a`, `b`, `c` được tính để xác định nghiệm gần
đúng cho `xr`.
b. Giá trị `xr` mới được đưa ra với công thức của Muller's method.
c. Kiểm tra điều kiện kết thúc thuật toán. Nếu tốc độ hội tụ của `xr` đủ chính xác
hoặc số lần lặp vượt tối đa, thuật toán sẽ dừng.
d. Biến `x0`, `x1`, và `x2` được cập nhật để chuẩn bị cho vòng lặp tiếp theo.
6. Cuối cùng, các tham số cần thiết được truyền vào hàm `muller()`, và hàm này
được gọi để thực thi thuật toán.
h=1
xr = 5
eps = 0.0001
imax = 100
muller(xr, h, eps, imax)
Khi thực thi, đoạn mã này sẽ tính tốn và in ra các giá trị của `xr` tại mỗi vòng lặp
cho tới khi hội tụ với độ lỗi mong muốn hoặc đạt số lần lặp tối đa gần đúng.
A.4.2. Chương trình chạy kiểm thử
DANH MỤC TÀI LIỆU THAM KHẢO
1. />2. />3. Giáo trình Numerical Methods for Engineers
NHẬN XÉT
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………