Giới thiệu Bài luận này không có tham vọng trình bày lại tất cả các luận điểm của các thuậttoán, mà chỉ có mục đích khái quát lại các thuật toán, nguyên tắc, xen kẽ những lập luận,nhưng
Trang 11 Giới thiệu
Bài luận này không có tham vọng trình bày lại tất cả các luận điểm của các thuậttoán, mà chỉ có mục đích khái quát lại các thuật toán, nguyên tắc, xen kẽ những lập luận,nhưng ý kiển chủ quan của cá nhân về các nguyên tắc xuất hiện trong các thuật toánđồng thời đưa ra các ví dụ cụ thể để làm sáng rõ các thuật toán này
2 Các bước giải quyết một vấn đề bài toán và áp dụng nguyên lý
Trong bất cứ hoạt động gì của cuộc sống, kể cả học tập, làm việc đến những hoạtđộng hàng ngày chúng ta luôn phải đối mặt với các vấn đề Bạn đang lo lắng làm sao đểhọc kì này đạt được một suất học bổng, bạn đang lo lắng ngày mai là sinh nhật ngườibạn thân, phải mua gì đây? Làm sao xin được tiền của ba mẹ để đi tham quan cùnglớp… Như tôi khi viết bài báo cáo này cũng rất đang lo lăng: làm sao viết được bài báocáo thật rõ ràng, đáp ứng yêu cầu đề ra, lượng kiến thức cũng như khả năng lập luận, khảnăng viết bài được nâng cao, làm sao truyền tải được hết ý của mình đến người đọc đặcbiệt là người thầy sẽ chấm điểm môn này :D
Kỹ năng giải quyết vấn đề là một điểm mấu chốt trong nghiên cứu khoa học, để đạt đượcnhững kết quả tốt trong quá trình nghiên cứu và học tập của mình người làm khoa họccần rèn luyện cho mình khả năng giải quyết công việc và vấn đề
Khi đối mặt với các vấn đề, mỗi người trong chúng ta lại có cách giải quyết riêng củamình, tùy vào đặc tính và khả năng cá nhân, nhưng nhìn chung cách giải quyết đểu đượcđưa ra dưới dạng mô hình sau:
Cần xác định A, B, các thao tác để đi từ A đến B.
giải không minh bạch?
Chúng đa đưa ra một tiến trình để giải quyết các vấn đề nói chung như sau:
Bước 1: Xác định vấn đề - bài toán
A → B
giả thiết giải pháp mục tiêu
Trang 2Bước 2: Lựa chọn phương pháp giải.
Bước 3: Xây dựng thuật toán hoặc thuật giải
Bước 4: Cài đặt chương trình
Bước 5: Hiệu chỉnh & Thực hiện chương trình
Bước 6: Lưu trữ, Bảo trì
3 Khái quát về các thuật toán, thuật giải, cấu trúc dữ liệu
Trong tin học chúng ta có thể chia các phương pháp giải quyết bài toán thành hai mảnglớn: phương pháp trực tiếp và phương pháp gián tiếp
Chúng ta sẽ đi vào từng thuật toán và giải quyết các bài toán tin học cụ thể từ các thuậttoán này
Phương pháp thử sai
Phương pháp Heuristic
Phương pháp trí tuệ nhân tạo
Trang 3Phương pháp này chủ yếu tận dụng khả năng tính toán của máy tính, giải quyết bài toánbàng cách đưa dữ liệu vào, còn những thao tác thực thi hoàn toàn do máy tính thực hiện.a) Chính xác
Giải phương trình bậc nhất một ẩn: y = ax+b
Phương trình trên được giải quyết theo toán học như sau:
TH1: a = 0
Nếu y = b: phương trình có vô số nghiệm
Nếu y<>b: phương trình vô nghiệm
TH2: a<>0
Phương trình có nghiệm duy nhất x = (y-b)/a
Việc giải quyết bài toán chỉ là việc thực hiện lại một cách trưc tiếp các chỉ dẫn toánhọc trên
Tìm một giá trị của x làm cho f(x) = 0;
Bài toán không yêu cầu phải tìm đầy đủ 2 nghiệm của phương trình
Vấn đề đầu tiên là, phương trình đã cho liệu có nghiệm không?
Rõ ràng ta thấy rằng tich a*c của phương trình trên <0, do đó phương trình trên
có nghiệm
Phương án giải
Phương trình có nghiệm ở đâu?
Mặt khác ta lại thấy f(-1)*f(-3)<0
=>nghiệm của phương trình nằm trong khoảng [-3;1]
Tìm bằng cách nào khi đã biết nghiệm ?
Ở đây chúng ta sẽ dùng một phương pháp ước lượng ngiệm gần đúng Tức làchúng ta sẽ thắt chặt nghiệm từ 2 đầu đã biết trước này
Trang 4 F( c ) >0 => nghiệm nằm trong [c;b]; gán a = c; quay lại B2
F(c) <0 => nghiệm nằm trong [a;c]; gán b =c; quay lại B2
Bài toán giai thừa:
Trang 5Chúng ta hãy bàn luận một chút về bản chất của đệ quy
Mỗi thuật toán đệ quy mô hình chung đều có 2 phần: phần điều kiện dừng và phần
đệ quy Như ví dụ về tính giai thừa phía trên phần điều kiện dừng chính là khitham số đầu vào là 1 hoặc 0 Còn phần để quy là n*GT(n-1)
Bản chất về cấu trúc của thuật toán đệ quy là stack hóa Sau mỗi lần thực hiệnhàm, kết quả lại được lưu vào trong stack.Quá trình thực hiện stack với hàmGT(3):
Đệ quy được chia làm các loại sau:đệ quy đuôi, đệ quy rẽ nhánh, đệ quy hỗ tương
Đệ quy đuôi: là dạng đệ quy mà trong một cấp đệ quy, chỉ có một lời gọi đệquy duy nhất xuống cấp thấp (ví dụ về hàm tính giai thừa phía trên)
Đệ quy nhánh: là dạng đệ quy mà trong suốt quá trình thực hiện hàm đệ quy,lời gọi đệ quy được thực hiện nhiều hơn một lần
Một ví dụ điển hình là bài toán tháp Hà Nội:
Bài toán: Bài toán tháp Hà Nội (tiếng Anh gọi là Tower of Hanoi hay Towers of
Hanoi) xuất phát từ trò chơi đố Tháp Hà Nội
Mục đích của bài toán là thực hiện được yêu cầu của trò chơi Dạng bài toán thôngdụng nhất là: "Người chơi được cho ba cái cọc và một số đĩa có kích thước khácnhau có thể cho vào các cọc này Ban đầu sắp xếp các đĩa theo trật tự kích thướcvào một cọc sao cho đĩa nhỏ nhất nằm trên cùng, tức là tạo ra một dạng hình nón.Người chơi phải di chuyển toàn bộ số đĩa sang một cọc khác, tuân theo các quy tắcsau:
+ một lần chỉ được di chuyển một đĩa
+ một đĩa chỉ có thể được đặt lên một đĩa lớn hơn (không nhất thiết hai đĩa nàyphải có kích thước liền kề, tức là đĩa nhỏ nhất có thể nằm trên đĩa lớn nhất)"
Trang 6Phân tích phương án giải:
Với trường hợp 2 đĩa,giả sử 3 cột lần lượt là A,B,C;Với A là cột chứa các đĩa theothứ tự nhỏ đến lớn; ta chỉ cần chuyển: 1 đĩa trên cùng qua B, 2.dĩa còn lại qua C;
3 Đĩa từ B qua C là đã thỏa mãn yêu cầu bài toán
Trang 7Thì f(b) = f(a)*2+1;Có quy luật trên là do với n= b ta phải 2 lần công việc của n =
a cộng thêm một lần vận chuyển đĩa nữa
Thuật toán:
Việc vận chuyển như trên phụ thuộc vào 2 yếu tố: vai trò của các cột di chuyển và
số lượng đĩa được di chuyển Thuật toán được nêu ra để thực hiện việc vần chuyểnnày đó là(với n đĩa ban đầu : A – nguồn, B-Trung gian, C - đích)
B1: vận chuyển n-1 đĩa từ nguồn A qua B
B2: vận chuyển đĩa còn lại qua C
B3: vận chuyển n-1 đĩa từ B qua C
Sự đệ quy sẽ suất hiện trong B1 và B3 khi này n đã giảm đi 1 đơn vị Cùng với sự
đệ quy này là sự thay đổi vai trò của các cột: ở B1 cột A là nguồn, cột B là đích, C
là trung gian; ở B2 : B- là nguồn, C là đích, A là trung gian
Trong bài toán này chúng ta dã sử dụng đệ quy trong 2 nhánh B1 và B3
Cài đặt: code
Đệ quy hỗ tương: là dạng đệ quy mà trong đó có sự gọi quay vòng như A gọi
B, B gọi C rồi C gọi lại A
d) Quy hoạch động
Trong nghành Khoa học máy tính và toán học người ta sử dụng phương phápquy hoạch đông(dynamic programming) để giải quyết các vấn đề phức tạp bằngcách chia nhỏ vấn đề phức tạp đó thành các vấn đề đơn giản hơn
Chúng ta vừa tiếp cận một số phương pháp giải toán : tính trực tiếp chính xác, gầnđúng và đệ quy Các phương pháp đó chỉ có thể giải quyết các bài toán mang tínhchất đơn giản, gần gũi với khả năng tính toán của con người Để giải quyết các vấn
đề phức tạp hơn, có sự biến thiên các giá trị trong một vùng xác định người ta sửdụng đến quy hoạch động
Trang 8Phương pháp quy hoạch động có thể được khái quát bởi hình ảnh sau:
Hướng tiếp cận của quy hoạch động có thể là bottm-top hoặc top-down,trong đó 2tính chất của nó luôn được đảm bảo: tối ưu hóa các cấu trúc con thànhphần(optimal substructure) và giải quyết các vấn đề con theo hướng từng bước,bước này dựa vào các bước trước đó(overlapping subproblems)
Chúng ta hãy xet bài toán về dãy Fibonaci quen thuộc.Bài toán này được giải bằng
đệ quy như sau:
int Fib(int n) {
Giả sử n nhập vào là 5 sự đệ quy được miêu tả như sau:
-TOP-DOWN OPTIMAL SUBSTRUCTURE
Trang 9Ta dễ dàng nhận thấy là (ví dụ) Fib(3) được tính đến 2 lần! Có cách nào để chỉtính Fib(3) một lần thôi không ?
Chúng ta đều biết ưu điểm của đệ quy là diễn đạt dễ dàng và cài đặt dễ dàng Tuynhiên nó có nhược điểm rất lớn đó là sử dụng stack để lưu vết các bước trước đó.Điều này đôi khi làm cho đệ quy trở thành một phương pháp sử dụng tài nguyênquá nhiêu, đặc biệt trong trường hợp đệ quy với đầu vào có giá trị lớn
Thay vì việc dùng đệ quy chúng ta có thể sử dụng quy hoạch động Sau đây là 2hướng tiếp cận bài toán trên sử dụng quy hoạch động:
Tiếp cận top-down:
Hàm này giải quyết bài toán bằng việc tính số fibonaci thứ n
Ta có một mảng các chỉ mục (mảng m) chỉ đến các giá trị tương ứng của dãyfibonaci với 2 giá trị mặc định m[0] = m[1]=1;ta muốn lấy giá trị của số thứ n Nộidung thuật toán ta làm như sau:
B1:gán m[1]=m[0]=1
B2:kiểm tra m[n] sẽ có 2 trường hợp xảy ra:
Tồn tại số fibonaci tại m[n] đến bước 4
Không tồn tại số fibonaci tại m[n] đến bước 3
B3: tính số Fibonaci theo công thức quy nạp: Fib(n) = Fib(n-1)+Fib(n-2)
B4:trả về giá trị của số Fibonaci thứ n Kết thúc
Tiếp cận bottom –top:
Cách này sự dụng cách tính trực tiếp, thuật toán như sau:
B3.Trả về giá trị của số fibonaci thứ n currenceF
Cài đặt: code (xem file)
Cái nào là optiminal substructure cái nào là overlapping subproblems ?
Phân tích tính tối ưu về cấu trúc con(optimal substructure):
Trong 3 thuật toán để giải bài toán nêu trên chúng ta đều thấy vấn đề được chianhỏ dần thành các vấn đề nhỏ hơn, và giải quyết Vấn đề nhỏ nhất được chia là khin=1 và n=0
Trang 10Chúng ta hãy để ý đến cấu trúc chia nhỏ này, rõ ràng đối với quy hoạch động cáccấu trúc được tối ưu tốt nhất, tài nguyên được đảm bảo sử dụng ít nhất có thể.
Phân tích về giải quyết các vấn đề từng bước, bước hiện tại dựa vào các bướctrước (overlapping subproblems):
Rõ ràng từ các vấn đề cơ bản (f1=f0=1), chúng ta sử dụng để giải quyết các vấn đềlớn hơn Từ các vấn đề vừa giải quyết chúng ta lại sử dụng để giải quyết các vấn
B1.1: 0<= j<= 33 làm công việc sau:
B1.1.1 0<=k <= 100 và k chia hết cho 3 làm công việc sau:
Kiểm tra biểu thức : i+j+k = 100 (1)
5i+3j+k/3 = 100 (2)
Trang 11Nếu biểu thức đúng thì gán Timduocnghiem = true.Thoái khỏi vòng lặp3
Ngược lại tiếp tục lặp
Kiểm tra Timduocnghiem = true thì thoat khỏi vòng lặp 2
Ngược lại tiếp tục lặp
Kiểm tra Timduocnghiem = true In ra nghiệm và thoát khỏi vòng lặp 1 Ngược lại tiếp tục lặp
Hàm cài đặt:
Nguyên lý vét cạn được mô hình hóa dưới dạng toán học như sau:
Gọi D(Domain) là không gian của vấn đề - bài toán (hay tập tất cả trường hợp,khả năng có thể xảy ra của bài toán)
Trang 12Để tìm kiếm lời giải của bài toán, ta liệt kê (theo một thứ tự nào đó) và lần lượt xéttất cả các phần tử của tập D, nếu phần tử X = (x1,x2, ,xn) thỏa f(X) = True thì X
là một lời giải của bài toán
Rõ ràng phương pháp vét cạn là một phương pháp “thuần túy”, và khá “thôngthường”.Có thể hiểu đơn giản là muốn tìm được lời giải ta sét từng trường hợp xảy
ra cho tới khi tìm được lời giải hoặc hết trường hợp Làm như thế rõ ràng là khảchắc chắn, nếu có lời giải nhất định ta sẽ tìm ra Điều này đã lợi dụng được sức
mạnh tính toán của máy tính Tuy nhiên, đối với không gian tìm kiếm quá lớn thì
phương pháp này khó có thể áp dụng
Chúng ta sẽ xem xét một vài ví dụ có thể áp dụng được thuật toán này:
Ví dụ 1: Tìm một số có 3 chữ số sao nó bẳng tổng lập phương của từng chữ số
Ví dụ 2: Có tờ 1 đồng, 2 đồng, 5 đồng Hỏi cần bao nhiêu tờ 1 đồng, 2 đồng, 5đồng để có 200 đồng
b) Nguyên lý mắt lưới
Chúng ta thấy được nhược điểm của vét cạn toàn bộ đó là không gian tìm kiếm
Để giảm bớt yếu điểm này người ta đưa ra một nguyên lý: mắt lưới
Dựa vào đặc điểm của vấn đề mà ta có thể loại bớt một số trường hợp và do đóloại bớt không gian tìm kiếm Trở lại ví dụ phía trên phần vét cạn Ta thấy đượckhác với i và j, k được tăng 3 đơn vị mỗi vòng lặp, như vậy đã giảm bớt được khánhiều trường hợp không cần thiết
Chúng ta hãy xét một bài toán cụ thể sau:
Cho hàm số y = f(x) liên tục trong đoạn [a,b] Giải phương trình f(x) = 0 trongđoạn [a,b] với độ chính xác /x-x0/<epsilon Với x0 là một trong các nghiệm củabài toán
Vấn đề bài toán đặt ra là tìm được nghiệm của bài toán thỏa mãn độ chính xácepsilon Chắc chắn một điểu rằng, nghiệm cần tìm nằm trong đoạn [a,b] Thôngthường theo nguyên lý vét cạn ta sẽ tìm mọi điểm trên đoạn này và thử xem cáinào làm cho f(x) = 0 Rõ ràng việc xét được tất cả các giá trị của x trên đoạn này làđiều không thể trong trường hợp x là kiểu số hữu tỉ hay số thực Số lượng x là qualớn Để giải quyết vấn đề này và để hạn chế không gín tìm kiếm người ta sử dụngnguyên lý mắt lưới Do độ chính xác là epsilon nên ta sẽ chia nhỏ đoạn [a,b] thành
n đoạn có độ dài epsilon Ta tìm đoạn có hai đầu lần lượt là x1,x2 thỏa:
Trang 13Về bản chất, tư tưởng của phương pháp là thử từng khả năng cho đến khi tìm thấylời giải đúng Đó là một quá trình tìm kiếm theo độ sâu trong một tập hợp các lờigiải Trong quá trình tìm kiếm, nếu ta gặp một hướng lựa chọn không thỏa mãn, taquay lui về điểm lựa chọn nơi có các hướng khác và thử hướng lựa chọn tiếp theo.Khi đã thử hết các lựa chọn xuất phát từ điểm lựa chọn đó, ta quay lại điểm lựachọn trước đó và thử hướng lựa chọn tiếp theo tại đó Quá trình tìm kiếm thất bạikhi không còn điểm lựa chọn nào nữa.
Quy trình đó thường được cài đặt bằng một hàm đệ quy mà trong đó mỗi thể hiệncủa hàm lấy thêm một biến và lần lượt gán tất cả các giá trị có thể cho biến đó, vớimỗi lần gán trị lại gọi chuỗi đệ quy tiếp theo để thử các biến tiếp theo Chiến lượcquay lui tương tự với tìm kiếm theo độ sâu nhưng sử dụng ít không gian bộ nhớhơn, nó chỉ lưu giữ trạng thái của một lời giải hiện tại và cập nhật nó
Để tăng tốc quá trình tìm kiếm, khi một giá trị được chọn, trước khi thực hiện lờigọi đệ quy, thuật toán thường xóa bỏ giá trị đó khỏi miền xác định của các biến cómâu thuẫn chưa được gán (kiểm tra tiến - forward checking) và kiểm tra tất cả cáchằng số để tìm các giá trị khác đã bị loại trừ bởi giá trị vừa được gán (lan truyềnràng buộc - constraint propagation)
Trang 14Theo nguyên lý Mê Cung ta phải xây dựng dần các thành phần của lời giải bằngcách thử lần lượt tất cả các khả năng có thể có Nếu tồn tại một khả năng chấpnhận được thì xây dựng thành phần kế tiếp, ngược lại, ta phải lùi lại thành phầntrước để thử các khả năng chưa được thử qua Chúng ta hãy xét bài toán sau:
Bài toán đặt ra ở đây đó là tìm cách nào để có thể đi từ ô màu xanh qua ô màuđỏ??
- Ta phải xét đường đi cho tất cả các đỉnh mà ta đến Việc chuyển đỉnh mới khi
có lối đi tiếp theo
- Tại mỗi đỉnh xét tất cả các khả năng cho đến khi tìm được trạng thái mới Việcxét sẽ kết thúc khi tìm được trạng thái mới
- Với mỗi vị trí đi qua , cần được đánh dấu là đã đi qua rồi
- Quay lui được thực hiện bởi đệ quy (stack)
- Có một số trạng thái của thuật giải được lưu: lưu các nút đã đi qua Lưu cácbước đi qua ma hiện tại cho là đúng Biến lưu 1 trạng thái hiện tại và biến lưu cáctrạng thái có thể đi tiếp theo
Giải thuật sau được đưa ra: (chú ý rằng đây là thuật giải không phải thuật toán)
procedure Try(i: Integer);
begin
for (mọi giá trị có thể gán cho xi) do
begin
Trang 15< cho xi := V>;
if (xi là phần tử cuối cùng trong cấu hình) then
<Thông báo cấu hình tìm được>
else
begin
<Ghi nhận việc cho xi nhận giá trị V (Nếu cần)>;
Try(i + 1); {Gọi đệ qui để chọn tiếp xi + 1}
<Nếu cần, bỏ ghi nhận việc thử xi := V, để thử giá trị khác>;
Trang 16Chúng ta đều biết rằng mỗi thuật toán phải có đủ 3 tính chất cơ bản: tính đúng đắn,tính dừng và tính xác định
Trong quá trình nghiên cứu giải quyết các vấn đề – bài toán, người ta đã đưa ra nhữngnhận xét như sau:
- Có nhiều bài toán cho đến nay vẫn chưa tìm ra một cách giải theo kiểu thuậttoán và cũng không biết là có tồn tại thuật toán hay không
- Có nhiều bài toán đã có thuật toán để giải nhưng không chấp nhận được vì thờigian giải theo thuật toán đó quá lớn hoặc các điều kiện cho thuật toán khó đápứng
- Có những bài toán được giải theo những cách giải vi phạm thuật toán nhưngvẫn chấp nhận được
Từ những nhận định trên, người ta thấy rằng cần phải có những đổi mới cho kháiniệm thuật toán Người ta đã mở rộng hai tiêu chuẩn của thuật toán: tính xác định và tínhđúng đắn Việc mở rộng tính xác định đối với thuật toán đã được thể hiện qua các giảithuật đệ quy và ngẫu nhiên Tính đúng của thuật toán bây giờ không còn bắt buộc đối vớimột số cách giải bài toán, nhất là các cách giải gần đúng Trong thực tiễn có nhiều trườnghợp người ta chấp nhận các cách giải thường cho kết quả tốt (nhưng không phải lúc nàocũng tốt) nhưng ít phức tạp và hiệu quả Chẳng hạn nếu giải một bài toán bằng thuật toántối ưu đòi hỏi máy tính thực hiên nhiều năm thì chúng ta có thể sẵn lòng chấp nhận mộtgiải pháp gần tối ưu mà chỉ cần máy tính chạy trong vài ngày hoặc vài giờ
Các cách giải chấp nhận được nhưng không hoàn toàn đáp ứng đầy đủ các tiêuchuẩn của thuật toán thường được gọi là các thuật giải.Heristic là một trong những thuậtgiải
Một ví dụ
Trang 17Không gian tìm kiếm là một đồ thị trạng thái
Tìm hành trình ngắn nhất: xác định bởi việc cực tiểu hóa giá thành bằng giải thuật ATTìm kiếm với tri thức bổ sung: hướng tìm kiếm được xác định bằng tri thức bổ sung saumỗi bước đi bằng giải thuật AKT
Giải thuật AT (Algorthm of Tree)
Trong không gian tìm kiếm, mỗi đỉnh n tương ứng với môt số g(n) giá thành đi từ đỉnhban đầu đến đỉnh n
Đỉnh đóng là những đỉnh đã được xét
Đỉnh mở là những đỉnh sẽ được xét
Gọi OPEN là tập chứa những đỉnh mở