Phương pháp quy hoạch động với bài toán đếm cấu hình tổ hợp

Một phần của tài liệu Cau-truc-du-lieu-Thiet-ke-thuatToan pps (Trang 30 - 33)

Bài toán đếm cấu hình tổ hợp đã được đề cập trong phần trình bày về phương pháp vét cạn. Tương tự các bài toán tối ưu tổ hợp, khá nhiều bài toán đếm cấu hình tổ hợp cũng có thể giải một cách tương đối hiệu quả bằng phương pháp quy hoạch động. Chúng ta sẽ xem xét một số bài toán.

Cho số tự nhiên n. Hãy cho biết có bao nhiêu cách phân tích số n thành tổng các số nguyên dương. Các cách phân tích không xét thứ tự, chẳng hạn 6=1+5=5+1 được coi là một cách. n=0 cũng được coi là 1 cách phân tích.

Để giải bài toán bằng phương pháp quy hoạch động, trước hết ta phải lập được công thức quy hoạch động.

Gọi F(i,j) là số cách phân tích số j thành tổng các số nguyên dương nhỏ hơn hoặc bằng i.

Các cách phân tích chỉ thuộc một trong 2 nhóm:

1. Nhóm thứ nhất không chứa giá trị i. Như vậy, j chỉ được phân tích thành tổng các số nguyên dương nhỏ hơn i và có F(i-1,j) cách như vậy.

2. Nhóm thứ hai có chứa ít nhất 1 giá trị i. Loại bỏ giá trị i này, ta sẽ thấy số cách phân tích j theo kiểu này bằng số cách phân tích j-i thành tổng các số nguyên nhỏ hơn hoặc bằng i, tức là có F(i,j-i) cách. Chú ý rằng điều này chỉ đúng khi ta không xét thứ tự các số hạng trong phân tích. Và j phải lớn hơn hoặc bằng i thì mới phân tích như vậy được.

Tóm lại, ta có công thức quy hoạch động như sau: 1. F(i,0)=1 với mọi i>0.

2. F(i,j)=F(i-1,j) nếu j<i.

3. F(i,j)=F(i-1,j)+F(i,j-i) với j>=i.

Sau khi đã xác định được công thức quy hoạch động, ta dễ dàng xây dựng được thuật toán tính bảng phương án. Về cấu trúc dữ liệu, ta có thể sử dụng một bảng phương án 2 chiều (hoặc áp dụng kĩ thuật cải tiến dựa trên nhận xét: để tính F(i) thì chỉ cần F(i- 1)).

Thuật toán tính bảng phương án:

procedure Calculate; begin F[0,0]:= 1; for j := 1 to n do F[i,0] := 0; for i := 1 to n do begin for j := 0 to n do

if j<i then F[i,j]:=F[i-1,j] else F[i,j] := F[i-1,j]+ F[i,j-i]; end;

end;

Đáp số của bài toán là F(n,n). b) Bài toán dãy số Catalan

1. Có 2n+1 phần tử nguyên dương. Phần tử đầu tiên và cuối cùng bằng 0. 2. Phần tử sau hơn kém phần tử trước 1.

Chẳng hạn, các dãy số Catalan bậc 3 là: 0 1 0 1 0 1 0 0 1 0 1 2 1 0 0 1 2 1 0 1 0 0 1 2 1 2 1 0 0 1 2 3 2 1 0

Bài toán của chúng ta là tính T(n) số dãy Catalan bậc n. Chẳng hạn T(0)=0, T(1)=1, T(2)=2, T(3)=5…

Bước đầu tiên là thiết lập công thức quy hoạch động:

Gọi F(i,j) là số dãy số kiểu Catalan có i phần tử, phần tử cuối cùng là j. Số dãy Catalan của ta sẽ là F(2n+1,0). Dễ dàng chứng minh được công thức truy hồi sau:

1. F(1,0)=1.

2. F(i,0) = F(i-1,1).

3. F(i,j) = F(i-1,j+1) + F(i-1,j-1) nếu j>=1.

4. Công thức áp dụng với i<=1<=2n+1, 0<=j<=n. Với các giá trị i,j khác F(i,j)=0. Sau khi đã có công thức thì việc xây dựng thuật toán trở nên dễ dàng hơn:

procedure Calculate; begin

F[i,j]:=0 với mọi i,j; F[1,0]:= 1;

for i:=2 to 2*n+1 do begin F[i,0]:=F[i-1,1];

for j:=1 to n do F[i,j]:=F[i-1,j-1]+F[i-1,j+1]; end;

end;

Qua các bài toán trên, chúng ta có thể nhận xét một cách có cơ sở rằng quy hoạch động là một phương pháp rất hiệu quả để giải các bài toán đếm cấu hình tổ hợp và tối ưu tổ hợp. Tuy nhiên giải một bài toán bằng quy hoạch động thường gặp 2 khó khăn: thứ nhất là tìm công thức quy hoạch động, thứ 2 là lưu trữ bảng phương án.

Cũng qua hai phương pháp vét cạn và quy hoạch động, ta thấy rằng việc giải nhiều bài toán tối ưu thường đòi hỏi chi phí khá lớn về thời gian tính toán và không gian bộ nhớ. Nhưng trong thực tế, nhiều bài toán không nhất thiết phải tìm nghiệm tối ưu. Trong điều kiện thời gian và không gian hạn chế, chúng ta chỉ cần những nghiệm đủ "tốt" là được. Đó chính là tư tưởng của phương pháp tham lam và các thuật toán xấp xỉ.

Một phần của tài liệu Cau-truc-du-lieu-Thiet-ke-thuatToan pps (Trang 30 - 33)