Bài giảng Cơ sở toán học – Bài 1: Thuật toán đánh giá và tiếp cận cung cấp cho người học kiến thức về thuật toán; độ phức tạp thuật toán; tiếp cận giải quyết bài toán. Mời các bạn cùng tham khảo bài giảng để nắm chi tiết nội dung kiến thức.
Trang 1Bài 1 Thuật toán đánh giá và tiếp cận
Trang 2Tính toán độ phức tạp thuật toán
Tiếp cận giải quyết bài toán
Các bước tiếp cận, giải quyết thuật toán
Xu hướng tiếp cận, giải quyết bài toán
Trang 3quyết một bài toán đã cho trong một khoảng thời
gian hữu hạn.
Trang 4Ví dụ: 2.1 Mô tả thuật toán tìm số lớn nhất trong
một dãy hữu hạn các số nguyên
1 Đặt giá trị cực đại tạm thời bằng số nguyên đầu tiên trong
dãy;
2 So sánh số nguyên tiếp theo với giá trị cực đại tạm thời,
Thuật toán
2 So sánh số nguyên tiếp theo với giá trị cực đại tạm thời,
nếu lớn hơn giá trị cực đại tạm thời thì đặt giá trị cực đại tạm thời bằng số nguyên đó.
3 Lặp lại bước 2) nếu còn các số nguyên trong dãy.
4 Giá trị cực đại tạm thời ở thời điểm này chính là số
nguyên lớn nhất trong dãy.
Trang 5Ta có thể viết lại thuật toán trên theo cách thức khác gọi là dạng giả mã:
Dữ liệu vào (input): a[1 n], a là mảng các số nguyên,
Trang 6Như vậy, khi mô tả (hay xây dựng) một thuật toán cần chú ý tới các yếu tố sau:
Dữ liệu đầu vào: Một thuật toán phải mô tả rõ các giá trị đầu vào từ một tập hợp các dữ liệu xác định
Ví dụ, dãy số nguyên a(1), a(2), ,a(n), với n<∞; hai
tử lớn nhất trong a(1), ,a(n); số d là ước chung lớn nhất của a và b;
Trang 71. Tính xác định: Các bước của thuật toán phải được
xác định một cách chính xác, các chỉ dẫn phải rõ ràng, có thể thực hiện được
2. Tính hữu hạn: Thuật toán phải kết thúc sau một số
hữu hạn bước
Thuật toán
hữu hạn bước
3. Tính đúng đắn: Thuật toán phải cho kết quả đúng
theo yêu cầu của bài toán đặt ra
4. Tính tổng quát: Thuật toán phải áp dụng được cho
mọi bài toán cùng loại, với mọi dữ liệu đầu vào như
đã được mô tả
Trang 8Ta xét thuật toán nêu trong ví dụ trên:
Dữ liệu đầu vào: mảng các số nguyên;
Dữ liệu đầu ra: số nguyên lớn nhất của mảng đầu vào;Tính xác định: Mỗi bước của thuật toán chỉ gồm các
Trang 9Tính đúng đắn: Sau mỗi bước kiểm tra và so sánh ta sẽ tìm được số lớn nhất trong các số đã được kiểm tra
Rõ ràng, sau lần kiểm tra cuối cùng thì xác định được
số lớn nhất trong toàn bộ các số đã được kiểm tra,
có nghĩa là toàn bộ dãy
Thuật toán
có nghĩa là toàn bộ dãy
Tính tổng quát: Thuật toán cho phép tìm số lớn nhất
của dãy số nguyên hữu hạn n bất kỳ
Trang 10So sánh hai thuật toán nào tốt hơn?
Nhanh hơn? Ít tốn bộ nhớ hơn?
Dựa vào đâu để so sánh?
Đánh giá độ phức tạp thuật toán
Trang 11- Độ lớn của dữ liệu đầu vào
-> Số lượng ô nhớ cần để giải quyết bài toán
-> Thời gian thực thi (số phép tính cơ bản) thực hiện
Đánh giá độ phức tạp thuật toán
Trang 12Đánh giá độ phức tạp thuật toán
Cho hai hàm số f và g, f: R→R, g: R→R
Trong phần này bàn đến sự so sánh độ tăng của hai hàm f(x) và g(x) khi x → +∞
1 Định nghĩa
Định nghĩa 1.1 Ta nói rằng f(x) = o(g(x)) khi x dần tới dương vô
Định nghĩa 1.1 Ta nói rằng f(x) = o(g(x)) khi x dần tới dương vô cùng, nếu như limx→+∞f(x)/g(x) = 0.
Khi này người ta nói rằng f(x) tăng chậm hơn so với g(x) khi x lớn dần đến +∞.
Ví dụ 1.1
x 2 = o(x 5 )
sin(x) = o(x)
1/x = o(1)
Trang 13Định nghĩa 1.2 Ta nói rằng f(x) là O-lớn của g(x) khi x dần tới dương vô cùng.
Kí hiệu f(x) = O(g(x))
hoặc đôi khi viết f(x) là O(g(x))
nếu như tồn tại hai hằng số C >0 và N >0 sao cho
Đánh giá độ phức tạp thuật toán
nếu như tồn tại hai hằng số C >0 và N >0 sao cho với mọi x > N thì |f(x) | ≤ C.|g(x)|
Trang 14Đánh giá độ phức tạp thuật toán
Ví dụ 1.3
Ta cũng dễ thấy rằng kx2 = O(x3) với k>0,
vì với x ≥ k ta có kx2 ≤ 1.x3
Để ý rằng cặp giá trị C và N, nếu tồn tại, rõ ràng
không phải là duy nhất
không phải là duy nhất
Ví dụ 1.4
1/(1+x2) = O(1)
sin(x) = O(1)
Trang 15Đánh giá độ phức tạp thuật toán
Định nghĩa 1.3 Ta nói rằng f(x) tương đương với g(x) khi x dần tới dương vô cùng,
kí hiệu f(x) ≈ g(x), nếu như limx→+∞f(x)/g(x) = 1
Ví dụ 1.5
Ví dụ 1.5
1+x+x2 ≈ x2, (2x+4)2 ≈ 4x2
Trang 16Đánh giá độ phức tạp thuật toán
Mệnh đề 1.1
Cho f(x) = a0 + a1x1 + a2x2 + + an-1xn-1 + anxn, trong đó ai, i=0,1, n, là các số thực
Trang 17Đánh giá độ phức tạp thuật toán
Mệnh đề 1.1
Cho f(x) = a0 + a1x1 + a2x2 + + an-1xn-1 + anxn, trong đó ai, i=0,1, n, là các số thực
Khi đó f(x) = O(xn)
Chứng minh:
Chứng minh:
Kí hiệu C =| a0 |+ |a1 |+ |a2 |+ + |an-1 |+ |an| Với x>1 ta có xk < xn, với k< n, suy ra
|f(x)| = |a0 + a1x1 + a2x2 + + an-1xn-1 + anxn|
≤|a0| + |a1x1| + |a2x2| + + |an-1xn-1| + |anxn|
=|a0| + |a1| x + |a2| x2 + + |an-1| xn-1 + |an| xn
≤(|a0| + |a1|+ |a2|.+ + |an-1|+ |an|) Xn = C xn
Trang 18Đánh giá độ phức tạp thuật toán
Ví dụ 1.6 Đánh giá tổng n số tự nhiên đầu tiên
S(n) = 1 + 2+ + n
Trang 19Đánh giá độ phức tạp thuật toán
Ví dụ 1.6 Đánh giá tổng n số tự nhiên đầu tiên
S(n) = 1 + 2+ + n < n+n+ + n = n2
Vậy S(n) = O(n2)
Trang 20Đánh giá độ phức tạp thuật toán
Ví dụ 1.6 Đánh giá tổng n số tự nhiên đầu tiên
S(n) = 1 + 2+ + n < n+n+ + n = n2
Vậy S(n) = O(n2)
Nhận xét:
Số mũ 2 trong O(n 2 ) đã phải là nhỏ nhất hay chưa?
Cũng như vậy, biểu thức n 2 đã phải là nhỏ nhất hay chưa?
Việc đánh giá hàm trong O-lớn cũng như bậc của hàm càng sát càng tốt
Ta có nhận xét rằng nếu tồn tại các hằng số N, C1 và C2 sao cho bắt đầu từ x>N ta có C1.g(x) ≤ f(x) ≤ C2.g(x) thì rõ ràng là đánh giá O(g(x)) đối với f(x) được coi là khá chính xác Trong trường
hợp này người ta còn nói rằng f(x) và g(x) là cùng bậc.
Trang 21Đánh giá độ phức tạp thuật toán
Chẳng hạn, f(x) = x2 với g(x) = x2+2x+3 là cùng
bậc,
hoặc f(x) = a0 + a1x1 + a2x2 + + an-1xn-1 + anxn với
xn là cùng bậc
Trong ví dụ 1.3 đã chỉ ra kx2 = O(x3), nhưng rõ ràng
Trong ví dụ 1.3 đã chỉ ra kx2 = O(x3), nhưng rõ ràng
x3 không phải là O(kx2)
Thật vậy, với mọi C và N tuỳ ý ta chỉ cần chọn
x > max{1, C.k, N} khi đó x3 > C.kx2 ; có nghĩa là
không tồn tại các số C và N như trong Định nghĩa 1.1 Như vậy, kx2 và x3 không phải là cùng bậc
Ví dụ 1.4: Đánh giá hàm giai thừa f(n) = n!
Trang 22Rõ ràng n! < nn Điều này chứng tỏ n! = O(nn)
Từ đó suy ra Log(n!) = O(n log n)
Trang 23Đánh giá độ phức tạp thuật toán
Định nghĩa 1.4 Ta nói rằng f(x) = Ω(g(x)) nếu như tồntại C>0 và dãy x1, x2, x3, →+∞, sao cho với mọi i:
f(xi)> C.g(xi)
Ví dụ, x = Ω(log(x))
Định nghĩa 1.5
Định nghĩa 1.5
Ta nói rằng hàm f tăng theo hàm mũ nếu tồn tại c>1
và d sao cho f(x) = Ω(cx) và f(x) = O(dx)
Ví dụ,
f(x) = e2x
f(n) = n!
Trang 24Độ tăng tổ hợp của hàm
Mệnh đề 1.2 Nếu f(x) = O(u(x)) và g(x) = O(v(x)) thì (f+g)(x) = O(max{u(x),v(x)})
Trang 25Đánh giá độ phức tạp thuật toán
Mệnh đề 1.2 Nếu f(x) = O(u(x)) và g(x) = O(v(x)) thì (f+g)(x) = O(max{u(x),v(x)})
Chứng minh:
Từ giả thiết suy ra tồn tại C1, k1, C2, k2 sao cho với
mọi x > k thì f(x) ≤ C u(x), với mọi x > k thì g(x)
mọi x > k1 thì f(x) ≤ C1.u(x), với mọi x > k2 thì g(x)
≤ C2.v(x) Đặt k = max { k1, k2}, và
C=max{C1,C2} Rõ ràng là với mọi x > k thì f(x) ≤
C.u(x) và g(x) ≤ C.v(x), hay f(x)+g(x) ≤ 2.C max{ u(x) , v(x) } Suy ra (f+g)(x) = O(max{u(x),v(x)}) Hiển nhiên, nếu u(x) = v(x), có nghĩa là nếu
f(x) = O(u(x)) và g(x) = O(u(x)),
Trang 26Đánh giá độ phức tạp thuật toán
Mệnh đề 1.3 Nếu f(x) = O(u(x)) và g(x) = O(v(x)) thì (fg)(x) = O(u(x).v(x))
Chứng minh: ( Tương tự chứng minh trên)
Trang 27Đánh giá độ phức tạp thuật toán
Mệnh đề 1.3 Nếu f(x) = O(u(x)) và g(x) = O(v(x)) thì (fg)(x) = O(u(x).v(x))
Chứng minh: ( Tương tự chứng minh trên)
Nhận xét
Một số thuật toán bao gồm một số thủ tục con hợp lại
Một số thuật toán bao gồm một số thủ tục con hợp lại Với dữ liệu đầu vào xác định số các bước cần thiết để giải bài toán là tổng các bước theo các thủ tục con Như thể ta phải tìm cách đánh giá số các bước mà
các thủ tục con thực hiện sau đó tổ hợp các đánh giá
đó lại
Trang 28Đánh giá độ phức tạp thuật toán
Ví dụ 1.5 Tìm đánh giá hàm
f(n)= n log (n!) + (3n2 +2n)log n
Trang 29Đánh giá độ phức tạp thuật toán
Ví dụ 1.5 Tìm đánh giá hàm
f(n)= n log (n!) + (3n2 +2n)log n
Theo các ví dụ đã nêu ở trên ta có
log(n!) = O(n log n), từ đó dễ dàng suy ra rằng
n log (n!) = O(n2 log n);
Mặt khác ta có 3n2 +2n =O(n2), hay suy ra
(3n2 +2n) log n = O(n2 log n)
Cuối cùng ta có: f(n) = O(n2 log n)
Trang 30Đánh giá độ phức tạp thuật toán
Ví dụ 1.6 Tìm đánh giá đối với hàm
f(n) = (n+3) log (n2+4) + 5n2
Trang 31Đánh giá độ phức tạp thuật toán
Ví dụ 1.6 Tìm đánh giá đối với hàm
f(n) = (n+3) log (n2+4) + 5n2
Ta có các đánh giá n+3= O(n)
và log (n2+4)=O(log n)
Thật vậy, đánh giá thứ nhất là hiển nhiên
Xét đánh giá thứ hai Rõ ràng là với n>2 ta có
log(n2+4) < log(2n2) < log 2 + log n2 = log 2 + 2log n
< 3 log n
Từ đây suy ra (n+3) log (n2+4) = O(nlog n)
Ngoài ra ta có 5n2 = O(n2) Từ đây suy ra
f(n) = O(max { nlog n, n2 }) = O(n2)
Trang 32Đánh giá độ phức tạp thuật toán
Ví dụ 1.7
Tìm đánh giá tốt nhất của hàm f(x) = 2x + 23
Trang 33Đánh giá độ phức tạp thuật toán
Ví dụ 1.7
Tìm đánh giá tốt nhất của hàm f(x) = 2x + 23
Hiển nhiên là với mọi x > 5 ta có f(x) < 2×2x
Vì vậy f(x) = O(2x)
Ta cũng dễ thấy được là 2x < f(x) với mọi x>0
Vậy O(2x) là đánh giá tốt nhất đối với f(x)
(hay nói cách khác 2x là cùng bậc với f(x))
Trang 34Độ phức tạp thuật toán
Tính hiệu quả của thuật toán thông thường được đo bởi thời gian tính (thời gian được sử dụng để tính bằng máy hoặc bằng phương pháp thủ công) khi các giá trị đầu vào có kích thước xác định Tính hiệu quả của thuật toán cũng được xem xét theo thước đo
của thuật toán cũng được xem xét theo thước đo
dung lượng bộ nhớ đã sử dụng để tính toán khi kích thước đầu vào đã xác định
Hai thước đo đã nêu ở trên liên quan đến độ
phức tạp tính toán của một thuật toán, được gọi là
độ phức tạp thời gian và độ phức tạp không gian
(còn gọi là độ phức tạp dung lượng nhớ)
Trang 35Độ phức tạp thuật toán
Trong phần đầu, chúng ta sẽ chỉ đề cập đến độ phức tạp thời gian của một thuật toán Độ phức tạp thời gian của một thuật toán thường được biểu diễn
thông qua số phép toán trong khi thực hiện thuật
toán khi các giá trị dữ liệu đầu vào có kích thước
toán khi các giá trị dữ liệu đầu vào có kích thước
xác định
Người ta thường dùng số phép tính làm thước đo
độ phức tạp thời gian thay cho thời gian thực của
máy tính là vì các máy tính khác nhau thực hiện các phép tính sơ cấp (so sánh, cộng, trừ, nhân, chia các
số nguyên) trong những khoảng thời gian khác nhau
Trang 36
Độ phức tạp thuật toán
Chúng ta cũng sẽ không thực hiện việc phân rã các phép toán sơ cấp nêu trên thành các phép toán bit sơ cấp mà máy tính sử dụng vì việc này là khá phức tạp
Mặt khác cách đánh giá được sử dụng ở đây là
Mặt khác cách đánh giá được sử dụng ở đây là cách đánh giá khả năng xấu nhất của thuật toán
Trang 37Độ phức tạp thuật toán
Định nghĩa 1
Một thuật toán được gọi là có độ phức tạp đa thức, hay còn gọi là có thời gian đa thức, nếu số các phép tính cần thiết khi thực hiện thuật toán không vượt quá O(nk), với k nguyên dương nào đó, còn n là kích
quá O(nk), với k nguyên dương nào đó, còn n là kích thước của dữ liệu đầu vào.
Các thuật toán với O(kn), trong đó n là kích thước dữ liệu đầu vào, còn k là một số nguyên dương nào đó gọi là các thuật toán có độ phức tạp hàm mũ hoặc thời gian mũ.
Trang 38Dữ liệu ra (output): max, số lớn nhất trong mảng a;
Dữ liệu ra (output): max, số lớn nhất trong mảng a;int TimMax(a: mảng các số nguyên);
max = a[1];
for i:2 -> n
if (max < a[i] )
max = a[i];
Trang 39Độ phức tạp thuật toán
Vì các phép toán được dùng ở đây là các phép toán
so sánh sơ cấp như ta đã nêu ở trên nên ta sẽ dùng
số các phép toán sơ cấp này để đo độ phức tạp của thuật toán Ta dễ dàng thấy được số các phép toán
so sánh sơ cấp được sử dụng ở đây là 2(n-1) Vì vậy
so sánh sơ cấp được sử dụng ở đây là 2(n-1) Vì vậy
ta nói rằng độ phức tạp của thuật toán nói trên là O(n) (còn nói là độ phức tạp tuyến tính)
Trang 40Độ phức tạp thuật toán
Ví dụ 2.5 Xét độ phức tạp của thuật toán tìm kiếm
tuyến tính Mảng a[1 n], tìm vị trí xuất hiện phần tử x
int TK_TT(a:mảng số nguyên; x: số nguyên)
return index;
Trang 41Số bước của thuật toán trong trường hợp xấu nhất là
Số bước của thuật toán trong trường hợp xấu nhất là
Trang 42Độ phức tạp thuật toán
Ví dụ 2.6 Xét độ phức tạp của thuật toán tìm kiếm nhị phân.
Mảng a[1 n] đã được sắp xếp, vị trí xuất hiện x.
int TimKiem_NP(a:mảng số nguyên; x: số nguyên)
1 first =1; last = n ;
2 found = false ;
2 found = false ;
3 While ( first<=last and not found )
index = ( first + last ) div 2;
If (x = a(index) ) found = true
else if (x< a(index) ) last = index –1
else first = index +1 ;
4 If (not found ) index :=-1;
5 return index;
Trang 44Độ phức tạp thuật toán
Ví dụ 2.7 Độ phức tạp thuật toán tìm ước số chung lớn nhất hai số nguyên dương
void swap(int a, int b)
Đổi chổ giá trị hai biến a, b
int uscln(int a, int b)
Trang 45Độ phức tạp thuật toán
Ví dụ 2.7 Xét độ phức tạp của thuật toán
Số lần thực hiện của một lần đề quy
Số lần đệ quy
Trang 46Độ phức tạp thuật toán
Ví dụ 2.8 Đếm số phần tử lớn nhất của mảng số nguyên a[0 n-1]
int countmax(int a[])
Trang 47Độ phức tạp thuật toán
Ví dụ 2.9 In ra các phần tử, sao cho phần tử trùng lặp chỉ in một lần từ mảng a[0 n-1]
void printone(int a[])
Đánh giá độ phức tạp thuật toán: ?
So sánh độ phức tạp thuật toán của ví dụ 2.8 và 2.9
Trang 49Độ phức tạp thuật toán
tìm số nguyên m lớn nhất mà khi biểu diễn nó theo cơ số 16 thì có các chữ số khác nhau đôi một và tổng các chữ số
khác nhau đôi một và tổng các chữ số (ở cơ số 16) đúng bằng n.
Trang 50Độ phức tạp thuật toán
Do một số lớn nhất có thể thành lập từ các chữ số khác nhau trong hệ đếm 16 là FEDCBA9876543210 (= 18 364 758 544 493 064 720) cho nên số n có giá trị lớn hơn 120 thì không cần kiểm tra
Nếu sử dụng thuật toán tìm kiếm tuần tự thì ta sẽ
Nếu sử dụng thuật toán tìm kiếm tuần tự thì ta sẽ
phải duyệt 18 364 758 544 493 064 720 trường hợp Mỗi trường hợp phải đổi số tương ứng ra cơ số 16, tính tổng các chữ số và so sánh với n Và cuối cùng
là phải tìm số lớn nhất thoả mãn cả hai điều kiện kia Nếu giả định mỗi giây có thể kiểm tra được
1,000,000 trường hợp thì phải mất 5,101,321,817 giờ, hay 212,555,075 ngày, hay 582,343 năm
Trang 51Như vậy, nếu với cùng các chữ số thì việc sắp đặt
sao cho các chữ số giảm dần từ trái sang phải sẽ cho
Trang 53Độ phức tạp thuật toán
không đầy một giây là có kết quả.
Trang 56Ts chính là giá trị của đa thức tại c Số phép toán 3n
Để ý rằng với thuật toán này việc tính các xk, với k = 1,2, ,n một cách riêng rẽ có thể sẽ tạo ra những sốlớn, hoặc gặp phải những sai số lớn
Trang 59Độ phức tạp thuật toán
Ví dụ 2.9 Đánh giá số phép chia số nguyên của thuật toán Euclid để tìm ước số chung lớn nhất của hai số
nguyên a và b, a>b
Trang 62Tiếp cận thuật toán
Bước 1: Xác định bài toán Nhiệm vụ của giai đoạn này
là làm rõ yêu cầu đặt ra của bài toán Có thể đặt ra và trả lời một số câu hỏi: Bài toán đặt ra vấn đề gì phải
giải quyết Giải quyết những vấn đề này trong phạm vi nào? Xếp thứ tự về tầm quan trọng các yêu cầu đặt ra
nào? Xếp thứ tự về tầm quan trọng các yêu cầu đặt ra
Ví dụ, bài toán đặt ra là “Giải hệ phương trình đại số
tuyến tính có số phương trình bằng số ẩn” Yêu cầu của bài toán này là “tìm nghiệm của hệ phương trình đại số tuyến tính n phương trình, n ẩn” Yêu cầu quan trọng nhất là “độ chính xác của nghiệm”