LỜI MỞ ĐẦUHiện nay, trong tất cả các lĩnh vực kinh tế, văn hóa, nông nghiệp… công nghệ thông tin thực sự gắn liền và góp phần làm tăng hiệu quả của các lĩnh vực đó, cụ thể đã có nhiều ph
Trang 1TIỂU LUẬN MÔN
THUẬT TOÁN NÂNG CAO
Giảng viên hướng dẫn: Nguyễn Thanh Bình Học viên : Võ Phi Thanh
Hoàng Công Tiến
Lê Công Vượng
Nguyễn Thị Hà Phương Lớp : Cao học KHMT K24
Đồng Hới, 12/2012
Trang 2LỜI MỞ ĐẦU
Hiện nay, trong tất cả các lĩnh vực kinh tế, văn hóa, nông nghiệp… công nghệ thông tin thực sự gắn liền và góp phần làm tăng hiệu quả của các lĩnh vực
đó, cụ thể đã có nhiều phần mềm phục vụ trong văn hóa nghệ thuật giải trí như phần mềm thống kê tin nhắn bình chọn, phần mềm xử lý hình ảnh, âm thanh; trong nông nghiệp thì người ta chế tạo ra các phương tiện, máy móc phục vụ cho mùa vụ…; trong trí tuệ nhân tạo thì có robot, máy móc tự động hóa… Vậy
để có được những sản phẩm đó phải qua các bước khác nhau trong đó quan trọng nhất là ý tưởng, hay là cách thức để cho sản phẩm đó hoạt động Tóm lại
là thuật toán
Trong tiểu luận của chúng tôi nghiên cứu về một số thuật toán nâng cao nhằm giải quyết một vấn đề trong một số bước hữu hạn hoặc nhằm cung cấp một kết quả từ một tập hợp của các dữ kiện đưa vào Một số thuật toán như sau:
- Chứng minh sự đúng đắn
- Thuật toán sắp xếp Quicksort
- Thuật toán chia để trị
- Thuật toán quy hoạch động
Chúng em xin chân thành cảm ơn thầy Nguyễn Thanh Bình đã hướng dẫn
để tiểu luận của chúng em hoàn thành tốt hơn Tiểu luận này còn nhiều thiếu sót, rất mong quý thầy cô và các bạn đóng góp ý kiến Chúng tôi xin chân thành cảm ơn
Trang 3MỤC LỤC
LỜI MỞ ĐẦU 1
MỤC LỤC 2
CHƯƠNG 1 GIỚI THIỆU VỀ THUẬT TOÁN NÂNG CAO 3
1 1 Khái niệm thuật toán 3
1.2 Các tính chất của thuật toán 3
1.3 Đặc tả thuật toán 4
1.4 Phân tích và đánh giá các thuật toán 4
CHƯƠNG 2 MỘT SỐ THUẬT TOÁN 5
2.1 Chứng minh sự đúng đắn: 5
2.1.1 Tìm bất biến vòng lặp I 5
2.1.2 Tìm hàm dừng T(n) 6
2.2 Thuật toán chia để trị 6
2.2.1 Chứng minh có thể nhân hai đa thức (ax+b) và (cx+d) chỉ với 3 phép nhân 6
2.2.2 Chứng minh hai số nguyên được biểu diễn n bit có thể được nhân bởi thuật toán có độ phức tạp O(nlog3) 8
2.3 Tính độ phức tạp của thuật toán Quicksort 9
2.3.1 Phân tích độ phức tạp: trường hợp tốt nhất: 9
2.3.2 Phân tích độ phức tạp: trường hợp xấu nhất : 9
2.3.3 Độ phức tạp trường hợp trung bình của Quicksort : 10
2.4 Thuật toán quy hoạch động 14
2.4.1 Bài toán 14
2.4.2 Thuật toán đệ quy tính hệ thức truy hồi Function Time(i,t1,t2); 15
2.4.3 Đánh giá độ phức tạp thuật toán đệ quy tính hệ thức truy hồi 15
2.4.4 Thuật toán quy hoạch động 15
2.4.5 Đánh giá độ phức tạp của thuật toán quy hoạch động 16
TÀI LIỆU THAM KHẢO 17
Trang 4CHƯƠNG 1 GIỚI THIỆU VỀ THUẬT TOÁN NÂNG CAO
1 1 Khái niệm thuật toán
Thuật toán là một dãy xác định các thao tác cơ bản áp dụng trên dữ liệu vào nhằm đạt được giải pháp cho một vấn đề
Hai vấn đề:
Tìm một phương pháp giải quyết vấn đề
- Giải pháp cho ax2+bx+c=0: rõ ràng và xác định
- Giải pháp cho ax5+bx4+cx3+dx2+ex=0: Không có giải pháp tổng quát
Tìm một giải pháp hiệu quả Phân biệt giải thuật và chương trình: Chương trình là cài đặt thuật toán bằng một ngôn ngữ lập trình Thuật toán: Thủ tục tính toán nhận tập các dữ liệu vào và tạo các dữ liệu ra
Thuật toán được gọi là đúng đắn nếu thuật toán dừng và cho kết quả đúng với mọi dữ liệu vào
Thuật toán hằng ngày trong cuộc sống đơn giản chỉ là những công việc với các bước tuần tự như nấu cơm, học bài… Thuật toán trong toán học/tin học thì như là nhân hai ma trận, tính tích phân…
1.2 Các tính chất của thuật toán
Thuật toán phải áp dụng cho tất cả các mẫu dữ liệu vào chứ không chỉ là một mẫu dữ liệu vào cụ thể
Ví dụ: Sắp xếp giảm dần một dãy các giá trị
Dữ liệu vào: 6 8 4 5 2
Dữ liệu ra: 8 6 5 4 2
Phương pháp: So sánh hai phần tử liên tiếp nhau từ trái qua phải, nếu không đúng thứ tự thì hoán đổi vị trí chúng
B1: 6 8 4 5 2
B2: 8 6 4 5 2
B3: 8 6 4 5 2
B4: 8 6 5 4 2
Dãy đã được sắp xếp nhưng thuật toán chưa tổng quát
Thuật toán phải dừng sau một bước xác định
Ví dụ: nhập n
While (n<>0) n=n-2
Endwhile
Thuật toán này trong trường hợp n lẻ thì sẽ không dừng mà chạy vô hạn
o Tính không nhập nhằng
Trang 5Các thao tác trong thuật toán phải được đặc tả chặt chẽ Ở mỗi bơpcs thực thi thì bước tiếp theo phải được xác định rõ ràng
Ví dụ: x=0
aa: Tăng x lên 1 hoặc giảm x xuống 1
If (x >=-2) and (x<=2) then goto aa
Thuật toán nhập nhằng vì không biết là phải tăng x hay giảm x
Thuật toán phải sử dụng hiệu quả nguồn tài nguyên máy tính đó là thời gian và bộ nhớ
1.3 Đặc tả thuật toán
Có nhiều cách đặc tả thuật toán:
o Không hình thức: Sử dụng ngôn ngữ tự nhiên
o Nửa hình thức: Kết hợp ngôn ngữ tự nhiên và các ký hiệu toán học bao gồm sơ đồ khối, ngôn ngữ giả,…
o Hình thức: Sử dụng các ký hiệu toán học của ngôn ngữ nào đó
1.4 Phân tích và đánh giá các thuật toán
o Dựa vào các tính chất của thuật toán
o Chứng minh sự đúng đắn
o Đánh giá độ phức tạp
Trang 6CHƯƠNG 2 MỘT SỐ THUẬT TOÁN
2.1 Chứng minh sự đúng đắn:
Viết thuật toán tính n! và chứng minh nó đúng đắn
Thuật toán:
giaithua (n)
Begin
If n=0 then gt:=1
else begin
i:=1; gt:=1;
While i<=n do begin
gt:=gt*i;
i:=i+1;
end_While;
end_If;
return gt;
End
Để chứng minh sự đúng đắn của thuật toán, chúng ta phải xác định được:
- Bất biến vòng lặp I
- Hàm dừng T(n)
2.1.1 Tìm bất biến vòng lặp I
giaithua (n)
Begin
If n=0 then gt:=1
else begin
i:=1; gt:=1;
While i<=n do begin
{q=gtk-1*k, k=1 i}
gt:=gt*i;
i:=i+1;
{q=gtk-1*k, k=1 i}
end_While;
{i=n+1,q=gtk-1*k, k=1 i}
end_If;
return gt;
Trang 7Bất biến vòng lặp:
I={q=gt k-1 *k, k=1 i}
Chứng minh I đúng bằng quy nạp:
- i=1, k=1 1 Khi đó I={q=gt0*1, k=1}=1 nên I đúng
- Giả sử I đúng ở bước lặp i-1
Nghĩa là, I={gtk-1*k, k=1 i-1} đúng
- Ta chứng minh I đúng ở bước lặp i
Nghĩa là, I={gtk-1*k, k=1 i} đúng Thật vậy, Vì q=gti-1*i đúng (do gti-1 đúng ở bước lặp i-1 như giả sử) nên q=gtk-1*k đúng (k=i) Do đó, I={gtk-1*k, k=1 i} đúng
2.1.2 Tìm hàm dừng T(n)
giaithua (n)
Begin
If n=0 then gt:=1
else begin
i:=1; gt:=1;
While i<=n do begin
gt:=gt*i;
i:=i+1;
{ip=ip-1+1}
end_While;
end_If;
return gt;
End
Hàm dừng: T(n)=n-i p +1, Trong đó p là biến đếm vòng lặp
- Chứng minh T(p) luôn giảm: T(p)=n-ip+1, do ip=ip-1+1
nên T(p)=n-ip +1=n-(ip-1+1)+1=n-ip-1=(n-ip-1+1)-1=T(p-1)-1, Do đó T(p)>T(p-1) , hay T(p) luôn giảm
- Chứng minh: Nếu điều kiện c đúng (c=i<=n) thì T(p)>0, nếu T(p)=0 thì
điều kiện c sai.
Nếu n>=ip, điều kiện đúng (c đúng) thì T(n)=n-ip+1>0, Nếu T(p)=0, có nghĩa là n=ip-1 nên n<ip có nghĩa là điều kiện sai
2.2 Thuật toán chia để trị
2.2.1 Chứng minh có thể nhân hai đa thức (ax+b) và (cx+d) chỉ với 3 phép nhân.
Thực hiện phép nhân hai đa thức trên ta sẽ có đa thức Ax2 + Bx +C Trong đó:
Trang 8A= ac
B= bc +ad
C= bd
Như vậy, nếu giữ nguyên các phép tính trên thì phải thực hiện:
+ 4 phép nhân,
+ 1 phép cộng
Để độ phức tạp của bài toán này giảm thì ta sẽ thực hiện biến đổi sao cho giảm phép nhân, có thể tăng phép cộng, trừ lên Ta thực hiện biến đổi B như sau:
B= bc + ad = bc + ad +ac +bd – ac – bd =(bc + bd) + (ad + ac) – ac – bd = (a + b)(c + d) – ac – bd
Vậy:
A= ac
B= (a + b)(c + d) – ac – bd
C= bd
Sau khi biến đổi, bài toán chỉ cần tính:
+ 3 phép nhân: ac, bd, (a + b)(c + d)
+ 2 phép cộng, 2 phép trừ
Vậy phép nhân hai đa thức này chỉ cần thực hiện 3 phép nhân
+) Thuật toán nhân hai đa thức bằng cách chia đa thức thành hai nữa đa
thức, một nữa có bậc từ 1 đến n/2, một nữa có bậc từ n/2+1 đến n:
Function dathuc(M1, M2, n, x)
Begin
{M1, M2 là hai mảng lưu hệ số của hai đa thức}
If n=1 then return (M1[0]*M2[0])
Else
Begin
a:= M1[0]……M1[n/2];
b:= M1[n/2+1]…….M1[n+1];
c:= M2[0]……M2[n/2];
d:= M2[n/2+1]…….M2[n+1];
u:= dathuc(a, c, n/2,x);
q:= dathuc(b, d, n/2),x;
z:= dathuc(a+b, c+d, n/2,x);
return (u*xn + (z-u-q)xn/2 +q);
end;
end;
+) Thuật toán nhân hai đa thức bằng cách chia đa thức thành hai nữa đa thức, một nữa có bậc chẵn, một nữa có bậc lẻ:
Function dathuc(M1, M2, n, x)
Trang 9{M1, M2 là hai mảng lưu hệ số của hai đa thức}
If n=1 then return (M1[0]*M2[0])
Else
Begin
If (n mod 2 = 0) then
Begin
a:= M1[n]……M1[2]M1[0];
b:= M1[n-1]…….M1[1];
c:= M2[n]……M2[2]M2[0];
d:= M2[n-1]…….M2[1];
end else
begin
a:= M1[n-1]……M1[2]M1[0];{hệ số chẵn}
b:= M1[n]…….M1[1]; {hệ số lẻ}
c:= M2[n-1]……M2[2]M2[0];
d:= M2[n]…….M2[1];
end;
u:= dathuc(a, c, n/2,x);
q:= dathuc(b, d, n/2,x);
z:= dathuc(a+b, c+d, n/2);
return (u*xn + (z-u-q)xn/2 +q);
end;
end;
2.2.2 Chứng minh hai số nguyên được biểu diễn n bit có thể được nhân bởi thuật toán có độ phức tạp O(n log3 ).
Giả sử, hai số nguyên n bit là X và Y Phân tích X, Y thành hai phần mỗi phần có n/2 bit Xét đối với n=2k Ta có:
X = A.2n/2 + B
Y = C.2n/2 + D
X.Y = AC2n + (AD + BC)2n/2 + BD
Ta cũng thực hiện phép biến đổi như phần chứng minh ở trên, thì:
X.Y = AC2n + ((A + B)(C + D) – AC – BD)2n/2 + BD
Và bài toán sẽ thực hiện:
+ 3 phép nhân n/2 bit: AC, BD, ((A + B)(C + D)
+ 6 phép cộng, trừ n/2 bit
+ 2 phép chuyển (nhân lũy thừa bậc hai)
Tính độ phức tạp:
Trang 102
n
) + 2*
2
n
+ 1 =3(3C(
4
n
)+2*
4
n
+1) +2*
2
n
+1 =32C(
4
n
)+6* +3 +2*+1 =32(3C(
8
n
)+2*
8
n
+1)+6*
4
n
+3 +2*
2
n
+1 =33C(
8
n
)+9*
4
n
+32 + 3*
2
n
+3 +n +1
=3iC(
2i
n
)+
1
0
3
i k k
+n* 1
0
3 2
k i
k
Đặt n = 2i i = logn
C(n) = 3lognC(1) + 1 3log 1 1
1 3
n
log 1 1
3 1 2 3 1 2
n
= 3logn + 1
2(3logn – 1) + 2
log
3
1 2
n
=nlog3 + 1
2(nlog3 – 1) + 2
3 log
n
Vậy O(nlog3)
2.3 Tính độ phức tạp của thuật toán Quicksort
2.3.1 Phân tích độ phức tạp: trường hợp tốt nhất:
Trường hợp tốt nhất xảy ra với Quicksort là khi mỗi lần phân hoạch chia tập tin
ra làm hai phần bằng nhau
điều này làm cho số lần so sánh của Quicksort thỏa mãn hệ thức truy hồi:
CN = 2CN/2 + N
Số hạnh 2CN/2 là chi phí của việc sắp thứ tự hai nửa tập tin và N là chi phí của việc xét từng phần tử khi phân hoạch lần đầu
2.3.2 Phân tích độ phức tạp: trường hợp xấu nhất :
Một trường hợp xấu nhất của Quicksort là khi tập tin đã có thứ tự rồi
Khi đó, phần tử thứ nhất sẽ đòi hỏi n so sánh để nhận ra rằng nó nên ở đúng vị
trí thứ nhất Hơn nữa, sau đó phân đoạn bên trái là rỗng và và phân đoạn bên phải gồm n – 1 phần tử Do đó với lần phân hoạch kế, phần tử thứ hai sẽ đòi hỏi
n-1 so sánh để nhận ra rằng nó nên ở đúng vị trí thứ hai Và cứ tiếp tục như thế
Như vậy tổng số lần so sánh sẽ là:
n + (n-1) + … + 2 + 1 = n(n+1)/2 =
(n2 + n)/2 = O(n2)
Độ phức tạp trường hợp xấu nhất của Quicksort là O(n2)
Trang 112.3.3 Độ phức tạp trường hợp trung bình của Quicksort :
Cách 1:
Công thức truy hồi chính xác cho tổng số so sánh mà Quick sort cần để sắp thứ tự N phần tử được hình thành một cách ngẫu nhiên:
CN = (N+1) + (1/N) (Ck-1 + CN-k)
với N ³ 2 và C1 = C0 = 0
Số hạng (N+1) bao gồm số lần so sánh phần tử chốt với từng phần tử khác, thêm hai lần so sánh để hai pointer giao nhau Phần còn lại là do sự
kiện mỗi phần tử ở vị trí k có cùng xác xuất 1/N để được làm phần tử chốt mà sau đó chúng ta có hai phân đoạn với số phần tử lần lượt là k-1
và N-k.
Chú ý rằng, C0 + C1 + … + CN-1 thì giống hệt
CN-1 + CN-2 +… + C0, nên ta có
CN = (N+1) + (1/N) 2Ck-1
Ta có thể loại trừ đại lượng tính tổng bằng cách nhân cả hai vế với N và rồi trừ cho cùng công thức nhân với N-1:
NCN – (N-1) CN-1 = N(N+1) – (N-1)N + 2CN-1
Từ đó ta được
NCN = (N+1)CN-1 + 2N
Chia cả hai vế với N(N+1) ta được hệ thức truy hồi:
CN/(N+1) = CN-1/N + 2/(N+1) = CN-2 /(N-1) + 2/N + 2/(N+1)
= C2 /3 + 2/(k+1)
CN/(N+1) » 2 1/k » 2 ò 1/x dx = 2lnN Suy ra:
CN» 2NlnN
Cách 2:
Cũng như trong các thuật toán sắp xếp khác, hai yếu tố đóng vai trò quyết định trong việc đánh giá độ phức tạp của Thuật toán QuickSort là AN, số phép
so sánh khóa, và BN, số phép đổi chỗ (hoán vị 2 mẫu tin) Ta sẽ phân tích hai đại lượng này dưới đây:
a) A N mean A( N)
Gọi P Nk là xác suất để A N k Trong bước phân chia đầu tiênl 1 ,r N Số
phép so sánh khóa trong vòng lặp Repeat…Until là N+1 nên P N k 0 nếu
r
N
k Cũng trong bước này, nếu giả thiết dữ liệu hoàn toàn ngẫu nhiên,
mẫu tin R[1] sẽ được dời đến đúng vị trí S với xác suất N1 Khi ấy ta được 2
mảng con cần xử lý tiếp là (1, S-1) và (S+1, N) Trong việc sắp xếp mảng
Trang 12con (1, S-1) số phép so sánh cần thiết có thể lấy giá trị tùy ý 0 hk N 1 với xác suất P S1,h Đồng thời việc sắp xếp mảng (S+1, N) cần đúng k-N-1-h
phép so sánh Do đó ta có công thức truy chứng:
1 N k N
Nk S h N S k N h
S h
N
Gọi A N (z)là hàm sinh của phân bố xác suất {P } Nk k
Ta có do (7)
1
1
1
( )
1
1
k
k N
S h N S k N h
S k N h
S h N S k h
N
N
³
1 1
1
N N
s
N
Suy ra:
1 1
1
1
1
N
S
N
1
0
2
S
N
Đây chính là công thức truy chứng với kết quả là
1
3
2
Vậy A N O N( log )N
Mặt khác ta có:
1 1
1
( '' (1) '' (1))
N
S N S N
S
N
N
N
Trang 13Như thế x N A'' (1)N thỏa hệ thức truy chứng (17) với hệ số f N Với điều kiện đầu A '' 1 0 thì hệ thức (25), Ngoài ra ta có :
1
2 1
1 1 1
1
2
N
k
N
k
Suy ra:
2
1
1
1 1 1
1 1
1
1
2
2
N
k
N
k
N N
N
k h k
h N k
1 2
1
1
2
N
k
k
h N
Do đó:
1
1 2
N
k
N O N N
Như thế độ lệch б=O(N)O(N) khá bé so với A N O N( log )N
b) B N meanB n
Gọi bNst là xác xuất để trong phép phân chia mảng (1,N), mẩu tin X[1] được dời đến vị trí đúng là S, và có t mẩu tin bên trái được đổi chỗ với t mẩu tin bên phải
Ta có:
N S
t
S t
N
( 1 )! ( )! 1
!
1
Trang 14
1
1
S
S N t S
t
N
Tương tự như trong a) ta có:
N
S
S
t
S N S
Nst
B
1
1
0
1 Thay thế giá trị của bNst vào ta được:
t S
t
S t N
S
S N S
S N t N
S
S t
S t N
N
1
0
1 1
1 1
1
0
1 1
1 Với N,S cố định sao cho 1≤S≤N, số cách chọn tùy ý một tập con S-1 phần tử của {1,2,…,N-1} cũng là số cách chọn 1 tập con E có S-1-t phần tử của {1,2,
…,S-1} và 1 tập con có t phần tử của {S,…,N-1} với 0≤t≤S-1 tùy ý Do đó:
1 1
0
1
S S
t
S N t
S
t
S
hay:
1 1
0
S
t
S t
Mặt khác:
!
1 1
0
1
0
1
t
t S N S N t
t S t
S
N
t
S
t
S
t
1!
1
1
0
1
t
t S N S N
S
t
S t
N S
t S
t
S t S
1
0 1
Lý luận tương tự như trên N S
t S
t
S t
1
0
1
là số cách chọn tập hợp con S-i phần tử của tập hợp N-2 phần tử Do:
2 1
0
S S
N t S
t
S
1
1
N
S N S
Từ (9), (10), (11), ta có:
N
S
S N S
N
S N S N
B
1
1
1
1 1
=
0 1
2 1
2 1 1
1 1
S
N S
N S
B N N
N S
N N
S N
N
N
1
0
2 6
S S
N
N
B
Đây là hệ thức truy chứng đã giải trong ví dụ 3 chương I với kết quả là:
N H N N N
3
1 1 3 4
1 1
3
1