• Đại cương • Phương pháp thiết kế một thuật toán đệ quy • Xây dựng một số thuật toán đệ quy trên một danh sách liên kết đơn 1.. Phương pháp để thiết kế một thuật toán đệ quy • Tham số h
Trang 11 Kỹ thuật đệ quy
2 Kỹ thuật chia để trị
3 Kỹ thuật tham ăn
4 Kỹ thuật quy hoạch động
Chương 2 Thiết kế thuật toán
Trang 2• Đại cương
• Phương pháp thiết kế một thuật toán đệ quy
• Xây dựng một số thuật toán đệ quy trên một danh sách liên kết đơn
1 Kỹ thuật đệ quy
Trang 3Đại cương
• Chương trình đệ quy là chương trình gọi đến chính nó.
• Một chương trình đệ quy thì không thể gọi đến chính nó mãi mãi mà phải có điểm dừng (trường hợp suy biến).
Trang 4Phương pháp để thiết kế một thuật toán đệ quy
• Tham số hoá bài toán
• Phân tích trường hợp chung (biểu diễn bài toán dưới dạng bài toán cùng loại nhưng khác phạm vi giải quyết)
• Xác định trường hợp suy biến
Trang 5Ví dụ: Sắp xếp mảng a gồm n phần tử
• Tham số hoá bài toán:
procedure Sort(dau, cuoi: word);
• Phân tích trường hợp chung:
Thủ tục Sort(dau, cuoi) có biểu diễn bởi các lệnh:
Trang 6procedure Sort(dau, cuoi: word);
Begin
If dau<>cuoi then
begin Sort(dau+1, cuoi);
if a[dau]>a[dau+1] then begin swap(a[dau],a[dau+1]);
Trang 7Ví dụ: Tính an
• Tham số hoá bài toán:
Function Power(a: real; n: byte):real;
• Phân tích trường hợp chung:
an = a.an-1 hay Power(a,n) = a* Power(a,n-1)
• Tr.hợp suy biến: n = 1 ( Power(a,1) = a )
• Độ phức tạp tính toán: O(n)
Trang 8Ví dụ: Tính an (một cách tính khác)
• Phân tích trường hợp chung:
Nếu n chẵn: Power(a,n) = sqr(Power(a,n div 2)) Nếu n lẻ: Power(a,n) = a*sqr(Power(a,n-1 div 2))
• Trường hợp suy biến: n = 1 (Power(a,1) = a)
• Độ phức tạp tính toán: O(log2n)
Trang 9Xây dựng một thuật toán đệ quy trên một danh sách liên kết đơn
• Xét khai báo cho trước như sau:
Type TroNut = ^Nut;
Trang 10Viết chương trình con (hàm/thủ tục)
• Xem thử có thể biểu diễn: CTC(F, ) bởi CTC(F^.next, )
• Ví dụ: Liệt kê giá trị trường Info của mọi nút thuộc danh sách F Procedure List(F: TroNut);
Begin If F<>nil then
begin writeln(F^.Info);
List(F^.Next);
end;
End;
Trang 11Bài tập
1 Sắp xếp một danh sách F
2 Hàm Function LaTangDan(F: TroNut): Boolean
kiểm tra tính tăng dần của danh sách F
Trang 13Hàm Function LaTangDan(F: TroNut): Boolean
kiểm tra tính tăng dần của danh sách F
Function LaTangDan(F: TroNut): Boolean;
Begin
If (F = nil) or (F^.Next = nil) then LaTangDan:= True else LaTangDan:= (F^.Info< F^.Next^.Info)
and LaTangDan(F^.Next); End;
Trang 14• Phương pháp
• Một số bài toán
2 Kỹ thuật chia để trị
Trang 16End;
Trang 17Một số bài toán
1 Bài toán tìm kiếm nhị phân:
Cho một dãy gồm n phần tử sắp xếp tăng dần và một phần tử X Tìm X có trong dãy hay không? Nếu X có trong dãy thì trả về kết quả là True ngược lại là False
Trang 18• Ý Tưởng: Chia đôi dãy, mỗi lần so sánh phần tử giữa của dãy, nếu phần tử X nhỏ hơn thì lấy nửa trái, ngược lại lấy nữa phải
• Mô tả thuật toán:
Input: A[1 n]
Output: True or False
Trang 19Function TKNP(A, X, Dau, Cuoi): Boolean;
If (Dau> Cuoi) then
TKNP:=FalseElse
Begin
Giua:=(Dau + Cuoi) div 2;
If (X=A[Giua]) Then TKNP:=TrueElse
If (X>A[Giua]) Then TKNP(A, X, Giua +1, Cuoi)Else
TKNP(A, X, Dau, Giua -1);
End;
Trang 202 Bài toán MaxMin
• Tìm giá trị Max, Min trong đoạn [l, r] của mảng A[1 n]
• Ý tưởng: Tại mỗi bước chia đôi đoạn cần tìm rồi tìm Max, Min trên mỗi đoạn, sau đó tổng hợp kết quả lại
• Mô tả thuật toán:
Input: A[1 n], l, r (l <=r)
Output: GTMin, GTMax
Trang 21Function MinMax(A, l, r, GTMin, GTMax)
GTMax:=max(GTMax1, GTMax2);
End;
Trang 223 Xếp lịch thi đấu thể thao: xét việc xếp lịch thi đấu thể thao theo thể thức đấu vòng tròn 1 lượt cho n đấu thủ Mỗi đấu thủ phải đấu với các đấu thủ khác và mỗi đấu thủ chỉ đấu nhiều nhất một trận mỗi ngày.
Trang 23• Tổng số trận đấu của toàn giải là:
• Nếu n là một số chẵn (n=2k) thì có thể sắp n/2 cặp thi đấu trong một ngày và do
đó cần ít nhất n-1 ngày
• Ngược lại nếu n là một số lẻ thì n-1 là một số chẵn nên ta có thể sắp (n-1)/2 cặp thi đấu trong một ngày và do đó ta cần n ngày
Trang 24• Lịch thi đấu là một bảng n dòng và n-1 cột
• Các dòng được đánh số từ 1 đến n và các cột được đánh số từ 1 đến n-1, dòng i biểu diễn cho đấu thủ i, cột j biểu diễn cho ngày thi đấu j và ô(i,j) ghi đấu thủ phải thi đấu với đấu thủ i trong ngày j
Trang 25• Ðể sắp lịch cho n đấu thủ, ta sẽ sắp lịch cho n/2 đấu thủ, để sắp lịch cho n/2 đấu thủ, ta sẽ sắp lịch cho n/4 đấu thủ
• Bài toán cơ sở là sắp lịch thi đấu cho 2 đấu thủ Hai đấu thủ này sẽ thi đấu một trận trong một ngày dễ sắp xếp Khó khăn: từ các lịch thi đấu cho hai đấu thủ,
ta tổng hợp lại để được lịch thi đấu của 4 đấu thủ, 8 cấu thủ,
Trang 26• Lịch thi đấu cho 4 đấu thủ: bảng 4 dòng, 3 cột.
• Đã có lịch thi đấu cho 2 đấu thủ 1 và 2 trong ngày thứ 1 Tương tự, ta có lịch thi đấu cho 2 đấu thủ 3 và 4 trong ngày thứ 1 (Ô(3,1) = Ô(1,1) + 2 và Ô(4,1) = Ô(2,1) + 2 )
• Hoàn thành lịch thi đấu cho 4 đấu thủ: lấy góc trên bên trái của bảng lắp vào cho góc dưới bên phải và lấy góc dưới bên trái lắp cho góc trên bên phải.
Trang 27• Lịch thi đấu cho 8 đấu thủ: bảng 8 dòng, 7 cột
• Góc trên bên trái là lịch thi đấu trong 3 ngày đầu của 4 đấu thủ từ 1 đến 4
• Các ô của góc dưới bên trái sẽ bằng các ô tương ứng của góc trên bên trái cộng với 4 là lịch thi đấu cho 4 đấu thủ 5, 6, 7 và 8 trong 3 ngày đầu
• Hoàn thành việc sắp lịch bằng cách lấp đầy góc dưới bên phải bởi góc trên bên trái và góc trên bên phải bởi góc dưới bên trái.
Trang 283 Phương pháp tham lam
a Bài toán tối ưu tổ hợp
• Cho hàm f(X) xác định trên một tập hữu hạn các phần tử D Hàm f(X) được gọi là hàm mục tiêu Mỗi phần
tử X D có dạng X = (x1, x2, xn) được gọi là một phương án Cần tìm một phương án X D sao cho ∈ ∈ hàm f(X) đạt min (max) phương án tối ưu
• Ta có thể tìm thấy phương án tối ưu bằng phương pháp “vét cạn” các phương án trong tập D (hữu hạn) để xác đinh phương án tốt nhất Tập hợp D là hữu hạn nhưng để tìm phương án tối ưu cho một bài toán kích thước n bằng phương pháp “vét cạn” ta có thể cần một thời gian mũ.
• Có một số kĩ thuật giải bài toán tối ưu tổ hợp mà thời gian có thể chấp nhận được
Trang 29b Nội dung kĩ thuật tham ăn
• Tham ăn hiểu một cách dân gian: trong một mâm có nhiều món ăn, món nào
ngon nhất ta sẽ ăn trước và ăn cho hết món đó thì chuyển sang món ngon thứ hai, lại ăn hết món ngon thứ hai này và chuyển sang món ngon thứ ba…
• Thường được sử dụng để giải bài toán tối ưu tổ hợp bằng cách xây dựng một phương án X Phương án X được xây dựng bằng cách lựa chọn từng
thành phần Xi của X cho đến khi hoàn chỉnh (đủ n thành phần) Với mỗi Xi, ta sẽ chọn Xi tối ưu Với cách này thì có thể ở bước cuối cùng ta phải chọn một giá trị cuối cùng còn lại
• Áp dụng kĩ thuật này sẽ cho một giải thuật thời gian đa thức, tuy nhiên chúng ta chỉ đạt được một phương án tốt chứ chưa hẳn là tối ưu
Trang 30c Mô tả thuật toán
Trang 31d Một số bài toán
Bài toán 1: bài toán trả tiền của máy rút tiền tự động ATM
• Trong máy rút tiền tự động ATM, ngân hàng đã chuẩn bị sẵn các loại tiền có mệnh giá 100.000 đồng, 50.000 đồng, 20.000 đồng và 10.000 đồng
• Giả sử mỗi loại tiền đều có số lượng không hạn chế
• Khi có một khách hàng cần rút một số tiền n đồng (tính chẵn đến 10.000 đồng, tức là n chia hết cho 10000)
• Hãy tìm một phương án trả tiền sao cho trả đủ n đồng và số tờ giấy bạc phải trả
là ít nhất
Trang 32• Gọi X = (X1, X2, X3, X4) là một phương án trả tiền Trong đó:
Trang 33• Để có số tờ giấy bạc phải trả (X1 + X2 + X3 + X4) nhỏ nhất thì các tờ giấy bạc mệnh giá lớn phải được chọn nhiều nhất
• Trước hết ta chọn tối đa các tờ giấy bạc mệnh giá 100.000 đồng, nghĩa là X1 là
số nguyên lớn nhất sao cho X1 * 100.000 ≤ n Tức là X1 = n DIV 100.000
• Xác định số tiền cần rút còn lại là hiệu n – X1 * 100000 và chuyển sang chọn loại giấy bạc 50.000 đồng,…
Trang 34Bài toán 2: Bài toán cái ba lô
• Cho một cái ba lô có thể đựng một trọng lượng W và n loại đồ vật
• Mỗi đồ vật i có một trọng lượng gi và một giá trị vi (số lượng không hạn chế)
• Tìm một cách lựa chọn các đồ vật đựng vào ba lô: chọn các loại đồ vật nào, SL mỗi loại sao cho tổng trọng lượng không vượt quá W và tổng giá trị là lớn nhất
Trang 35Phương pháp
1 Tính đơn giá= giá trị/trọng lượng cho các loại đồ vật
2 Xét các loại đồ vật theo thứ tự đơn giá từ lớn đến nhỏ
3 Với mỗi đồ vật được xét sẽ lấy một số lượng tối đa mà trọng lượng còn lại của
ba lô cho phép
4 Xác định trọng luợng còn lại của ba lô và quay lại bước 3 cho đến khi không còn có thể chọn được đồ vật nào nữa
Trang 364 Quy hoạch động
• Giới thiệu phương pháp
• Phương pháp thực hiện
• Một số bài toán
Trang 37• Kĩ thuật chia để trị thường dẫn tới một giải thuật đệ quy có một số giải thuật có
độ phức tạp thời gian mũ, tuy nhiên, thường chỉ có một số đa thức các bài toán con một số bài toán con nào đó đã giải nhiều lần
• Tránh việc giải một số bài toán con nhiều lần tạo một bảng lưu trữ kết quả các bài toán con và khi cần chúng ta sẽ sử dụng kết quả đã được lưu trong bảng mà không cần phải giải lại bài toán đó
• Lấp đầy bảng kết quả các bài toán con theo một quy luật nào đó để nhận được kết quả của bài toán ban đầu được gọi là quy hoạch động (dynamic programming).Giới thiệu phương pháp
Trang 38Ví dụ: Tính phần tử thứ n của dãy số Fibonaci
Function F(n: integer): integer;
Begin If n ≤ 2 then F:=1
else F:= F(n-1)+F(n-2);
End;
Function F(n: integer): integer;
var i: integer; a: array[1 100] of integer; Begin
Trang 39• Phương pháp quy hoạch động sẽ không đem lại hiệu quả trong các trường hợp sau:
– Không tìm được công thức truy hồi
– Số lượng các bài toán con cần giải quyết và lưu giữ kết quả là rất lớn
– Sự kết hợp lời giải của các bài toán con chưa chắc cho ta lời giải của bài toán ban đầu
Trang 40Phương pháp thực hiện
• Phân tích bài toán (biểu diễn bài toán dưới dạng một bài toán nhiều mức)
• Xây dựng giải pháp đệ quy (lập công thức truy hồi)
• Lập bảng (sử dụng các mảng để tính toán các giá trị theo kiểu dưới-lên)
• Tổng hợp kết quả (kiến tạo một lời giải cho bài toán từ các thông tin đã tính toán)
Trang 41Ví dụ tính dãy số Fibonaci
• Phân tích bài toán: Xây dựng hàm:
Function F(n: integer): integer;
Trang 42Ví dụ tính C(k,n)
• Phân tích bài toán: Xây dựng hàm:
Function C(k, n: byte): longint; {giả thiết k<=n}
Trang 43Một số bài toán
Bài toán 1: Chiếc túi xách
• Một cái kho chứa n loại đồ vật có kích thước và giá trị khác nhau Cụ thể:
Loại đồ vật i (i=1 n) có: - kích cỡ m[i] ∈ N*
Trang 44Bài toán chiếc túi xách
• Phân tích bài toán:
– Gọi P(r, s) là bài toán chiếc túi xách, với:
r ∈ N*: kích cỡ chiếc túi
s ∈ N*: số các loại đồ vật khác nhau (bài toán ban đầu là P(p, n))
– Các giá trị cần tìm:
l[r,s]: giá trị cực đại ∑ x[i].c[i] của bài toán P(r, s) u[r,s]: số lượng loại đồ vật s tối ưu cần lấy (tức: x[s]) của bài toán P(r, s)
Trang 46Lập bảng
Procedure LapBang;
Begin
For r:=0 to p do For s:=1 to n do
If s=1 then Tính u[r, 1] và l[r, 1] else Tính u[r, s] và l[r, s];
End;
Trang 48End;
Trang 49Bài toán 2: Bài toán xâu trong cực đại
S là xâu trong của T nếu S nhận được bằng cách xoá đi một số ký tự nào đó Ví dụ:
‘ABC’ là xâu trong của ‘GAHEBOOC’
Cho 2 xâu T1, T2 Tìm một xâu S là xâu trong chung của T1 và T2 có độ dài cực đại.
Ví dụ: T1=‘ABCDAE’ và T2=‘XYACADK’ có xâu ‘ACD’ là xâu trong chung với độ dài cực đại.
Trang 50Phân tích bài toán
• Giả sử ta có:
– Xâu A=“a1 a2…am” , chiều dài: m
– Xâu B=“b1 b2…bn” , chiều dài: n
• Gọi P(i, j) là bài toán xâu con chung cực đại, với
- i ∈ N: Độ dài dãy a1a2…ai ( i ≤ m )
- j ∈ N: Độ dài dãy b1b2…bj (j ≤ n)
- Bài toán ban đầu là P(m, n)
• Các giá trị cần tìm:
- L [i,j]: độ dài cực đại của xâu con chung của bài toán P(i, j)
- S: xâu con chung của bài toán P(i, j)
Trang 51Giải pháp đệ quy
– Nếu (i=0) hoặc (j=0) : L (i,j)=0
– Nếu (i>0) and (j>0) and (ai=bj): L (i,j)= 1 + L (i-1,j-1)
– Nếu (i>0) and (j>0) and (ai<> bj):
L (i,j) = Max(L (i-1,j), L (i,j-1))
Trang 52L[i, j] =
0 nếu i = 0 hoặc j = 0
1 + L[i -1, j -1] nếu ai = bj Max(L[i -1, j], L[i, j -1]) nếu ai <> bj
Trang 53Tổng hợp
• Để tìm xâu kết quả S
– Đi ngược từ ô l[m,n] hướng về l[0,0]
– Nếu ai = bj thì đặt ai hoặc bj vào bên trái dãy S (ở đầu xâu), lùi về L[i - 1, j-1]
– Nếu ai <> bj thì
• lùi về L[i - 1, j] trong trường hợp L[i - 1, j] > L[i, j – 1]
• ngược lại, lùi về L[i, j – 1] trong trường hợp
L[i - 1, j] ≤ L[i, j – 1]
Trang 54• Ví dụ : A=’XYACADK’và B=’ABCDAE’
J i
Trang 552 Bài toán du lịch: Một người đi từ thành phố 0 đến thành phố n và có thể đi qua 1 thành phố khác 1, 2, ,
n-1 , theo lộ trình : 0 → i1 → i2 … → ik → n, trong đó: 0 < i1 < i2 < …< ik < n,Giá vé của xe đi từ thành phố i đến thành phố j là c[i,j] Tìm một lộ trình từ thành phố 0 đến thành phố n sao cho tổng chi phí về giá vé đạt cực tiểu.
3 Bài toán sinh viên ôn thi: Một sinh viên còn m ngày để ôn thi n môn Theo kinh nghiệm của anh ta, nếu ôn
môn j trong i ngày thì được điểm là a[i,j] Giả sử cho biết các a[i,j] (với a[i,j]<=a[i+1,j]).
Tìm bộ x[j] (số ngày ôn môn j, với j=1 n) sao cho ∑ x[j]=n và sinh viên đạt tổng điểm lớn nhất ( ∑ a[x[j], j] → max).
Bài tập
Trang 56Bài toán: người du lịch
• Một người đi từ thành phố 0 đến thành phố n và có thể đi qua (hoặc không đi qua) các thành phố khác 1, 2, , n-1, theo lộ trình:
0 → i1 → i2 … → ik → nTrong đó: 0 < i1 < i2 < …< ik < n,
• Giá vé của xe đi từ thành phố i đến thành phố j là c[i,j] (vớI i < j) Tìm một lộ trình từ thành phố 0 đến thành phố n sao cho tổng chi phí về giá vé đạt cực tiểu
Trang 57Phân tích bài toán
• Gọi ρ(s) là bài toán du lịch, với:
– Thành phố xuất phát : 0
– Thành phố cần đến: n
• Bài toán ban đầu là : ρ(n)
• Các giá trị cần tìm:
– l[s]: chi phí nhỏ nhất để đi từ 0s của bài toán ρ(s)
– u[s]: đỉnh kế cuối trên đường đi từ 0s của bài toán ρ(s)
Trang 59end else Tính l[s] và u[s]
End;
Trang 62Bài toán sinh viên ôn thi
• Một sinh viên còn m ngày để ôn thi n môn Theo kinh nghiệm của anh ta, nếu ôn môn j trong i ngày thì được điểm là a[i,j] Giả sử cho biết các a[i,j] (với a[i,j] ≤
a[i+1,j])
• Tìm bộ x[j] (số ngày ôn môn j, với j=1 n) sao cho Σx[j] = n và sinh viên đạt tổng điểm lớn nhất (hay: Σa[x[j], j] → max)
Trang 63Phân tích bài toán
• Gọi ρ(r,s) là bài toán sinh viên ôn thi, trong đó:
– s là số môn cần ôn thi.
– r là số ngày ôn thi.
• Bài toán ban đầu sẽ là : ρ(m,n)
Trang 65End;
Trang 67procedure tonghop;
begin
r:=m;
for s:=n downto 1 do begin
x[s]:=u[r,s]; r:=r-x[s]; end;
end;