1. Trang chủ >
  2. Giáo án - Bài giảng >
  3. Cao đẳng - Đại học >

PHẦN I: MỘT SỐ THUẬT TOÁN CƠ BẢN

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (113.58 KB, 14 trang )


Việc sử dụng máy tính điện tử để giải quyết một bài toán nào đó thường được hiểu

một cách không đầy đủ. Nhiều người cho rằng đó chỉ là việc lập trình thuần túy. Thực ra,

giải một bài toán trên máy tính điện tử là một quá trình phức tạp, bao gồm nhiều giai

đoạn phát triển, mà lập trình chỉ là một trong các giai đoạn đó.

Ta hãy xét bài toán giải hệ phương trình đại số tuyến tính trên máy tính. Đây là

một bài tập khá quen thuộc đối với sinh viên các chuyên ngành kỹ thuật. Với một đầu vào

như vậy, không ít sinh viên cho rằng chỉ còn một việc duy nhất, đó là viết chương trình.

Về mặt lý thuyết, toán học đã giải quyết khá đầy đủ: từ phát biểu bài toán, thuật toán và

xây dựng các phân tích về nghiệm của hệ phương trình trong các trường hợp khác nhau.

Nhưng khi viết chương trình trên máy tính để giải bài toán trên sẽ có một số vấn đề phải

làm rõ. Thậm chí có những vấn đề gặp phải ngay từ khi viết những dòng đầu tiên trong

chương trình như kích thước của hệ phương trình chẳng hạn. Số ẩn và số phương trình tối

đa là bao nhiêu? Nếu để ý tiếp ta sẽ thấy ngay một số thông tin mà người lập trình phải

biết như: Số ẩn và số phương trình có bằng nhau hay không? Trong trường hợp hệ có

nhiều nghiệm thì phải viết ra bao nhiêu nghiệm và những nghiệm nào? Dữ liệu về các hệ

số của phương trình được nhập từ tệp hay từ bàn phím? Giá trị các hệ số đó có quá lớn,

quá nhỏ không?

Như vậy, rõ ràng là với một bài toán, người lập trình cần có đầy đủ những thông

tin về những yêu cầu chi tiết của đầu bài liên quan đến giới hạn của bộ nhớ, giới hạn của

màn hình, giới hạn về thời gian và giới hạn về sai số. Trong một số trường hợp những

thông tin này được xác định ngay trong đầu bài nhưng trong nhiều trường hợp phải qua

một quá trình phân tích mới làm rõ được các thông tin này.

Người lập trình phải giải quyết một vấn đề, một bài toán trên máy tính cần phải

thực hiện một bước rất quan trọng, đó là phân tích bài toán. Việc phân tích đầu bài nhằm

làm rõ một số thông tin:

a) Yêu cầu của bài toán: Bài toán đòi hỏi giải quyết cái gì trên máy tính. Nếu

giải quyết vấn đề này trên máy tính thì có gặp khó khăn gì về bộ nhớ, về thời gian tín, về

cách giải quyết?

b) Dữ liệu đầu vào và dữ liệu đầu ra của bài toán là gì và như thế nào?

2



c) Với cách giải quyết đã được lựa chọn có sẵn thuật toán hỗ trợ hay không?

Trả lời được một số câu hỏi trên người lập trình mới có thể viết được chương

trình đáp ứng yêu cầu đề ra trong bài toán.

1. Thuật toán

Thuật toán là một bản liệt kê các chỉ dẫn, các quy tắc cần thực hiện theo từng bước

xác định nhằm giải quyết một bài toán đã cho trong một khoảng thời gian hữu hạn.

Ví dụ 1: Tìm số lớn nhất trong một dãy hữu hạn các số nguyên.

Thuật toá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, 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.

Trên đây là những chỉ dẫn cụ thể từng bước được thể hiện bằng ngôn ngữ thông

thường. Chúng ta sẽ tìm cách thể hiện lại thuật toán giải bài toán trên theo cách thức

khác:

-



Dữ liệu vào (input): A là mảng chứa n số nguyên.

Dữ liệu ra (output): max, số lớn nhất trong mảng A.

Procedure Tim_max (A: mảng có n số nguyên);

a) Đặt max:= A (1);

b) Xét từ i = 2 đến n

Nếu max < A (i) thì đặt max:=A(i);



Bảng mô tả thuật toán có các yếu tố:

a) 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.

b) 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.

c) 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.

d) 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ả.

Khi mô tả một thuật toán cần đảm bảo các yếu tố sau đây:



3



- 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 số nguyên

dương a và b.

- Dữ liệu đầu ra: Từ một tập các giá trị đầu vào, thuật toán sẽ tạo ra các giá trị

đầu ra. Các giá trị đầu ra chính là nghiệm của bài toán. Ví dụ, số max là phần tử lớn nhát

trong a(1), a(2),…,a(n); số d là ước chung lớn nhất của a và b.

Ta xét thuật toán tìm số lớn nhất trong một dãy số nguyên nêu ở ví dụ trên:

- Tính xác định: Mỗi bước của thuật toán chỉ gồm các phép gán, mệnh đề kéo theo.

- Tính hữu hạn: Thuật toán dừng sau khi tất cả các thành phần của mảng đã được

kiểm tra.

- Tí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.

- 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ỳ.

Dữ liệu đầu vào đầu ra được mô tả rõ ràng:

+ Dữ liệu đầu vào: Mảng chứa n số nguyên.

+ Dữ liệu đầu ra: Số nguyên lớn nhất của mảng đầu vào.

Ví dụ 2: Cho dãy số nguyên A và số nguyên x. Hãy xác định xem số nguyên x có trong

mảng A hay không. Nếu có, hãy chỉ ra vị trí của x trong mảng A.

Thuật toán:

-



Input: Mảng A gồm n các số nguyên và số nguyên x.

Output: Chỉ số Index của x nếu thấy hoặc -1 nếu không tìm được x.



Procedure Timkiem_TT (A: Mảng số nguyên; x: số nguyên):

+ Index:=1;

+ While (Index <=n) and (x# A (Index)) Do Index:=Index + 1;

+ If Index > n Then Index:=-1;

Thuật toán tìm kiếm nêu trên được gọi là thuật toán tìm kiếm tuần tự hay còn gọi

là tìm kiếm tuyến tính.



4



Ví dụ 3: Cho mảng số nguyên A đã được sắp xếp không gian và số nguyên x. Hãy xác

định xem số nguyên x có trong mảng A hay không. Nếu có, hãy chỉ ra vị trí của x trong

mảng A.

Dữ liệu đầu vào của bài toán này khác với bài toán trước ở chỗ mảng A được sắp

xếp không giảm. Nhờ thế mà chúng ta có thể lựa chọn thuật toán tìm kiến nhị phân để

giải bài toán này.

Thuật toán:

- Input: Mảng A gồm n các số nguyên đã được sắp xếp tăng dần và số nguyên x

cần tìm trong danh sách.

- Output: Chỉ số Index, chỉ số Index bằng chỉ số phần tử bằng x, hoặc bằng 0 nếu

không tìm dược x.

Prucedure Timkiem_NP(A: mảng số nguyên; x: số nguyên)

+ CS trái :=1; CS phải :=n;

+ Chưa tìm thấy :=True;

+ While (còn khoảng tìm) and (chưa tìm thấy) Do

• Index:= Chỉ số ở giữa CS trái và CS phải;

• If x =A(i) Then đặt chưa tìm thấy = false

Else khoảng tìm sẽ bị co hẹp;

If x< A(Index) Then CS phải = Index -1

Else CS trái = Index + 1;

+ If chưa tìm thấy Then đặt Index :=0;

Trước khi giải một bài toán trên máy tính người lập trình phải phân tích bài toán,

hiểu rõ các yêu cầu và ràng buộc của nó sau đó mới xây dựng thuật giải. Thuật giải cũng

có thể được lựa chọn trong các thuật toán quen biết, cũng có thể do người lập trình xây

dựng thông qua hiểu biết và cảm nhận của mình.

2. Biễu diễn thuật toán

Để có thể thảo luận về thuật toán (hay thuật giải) hoặc chuyển thuật toán thành

chương trình trên máy tính, người ta phải tìm cách biểu diễn thuật toán. Trong các ví dụ

được nêu chúng ta đã biểu diễn chính bằng ngôn ngữ gần tự nhiên hoặc ngôn ngữ gần với



5



ngôn ngữ lập trình (tựa ngôn ngữ lập trình hay còn gọi là giả mã). Trong phần này chúng

ta xem xét kỹ hai ngôn ngữ thường được dùng là sơ đồ khối và giả mã.

2.1. Sơ đồ khối

Sơ đồ khối là một ngôn ngữ dùng để biểu diễn thuật toán. Sơ đồ khối là một công

cụ giúp cho người lập trình có được một cách xem xét sự làm việc của thuật toán khá chi

tiết và cu thể. Sơ đồ khối được quy ước bao gồm các nút là hình elip, chữ nhật hoặc hình

thoi được nối với nhau bởi các đường chỉ hướng chuyển động trong sơ đồ.

Băt đầu

Kết thúc

-



Hai loại nút giới hạn Bắt đầu và Kết thúc thường có hình dạng elip;

Nút chỉ các thao tác, công việc có dạng hình chữ nhật;



i=i+1

- Nút chỉ các điều kiệnBắt

cóđầu

dạng hình thoi: Trong các đường nối với nút điều kiện

này có hai đường đi ra ứng với hai trường hợp điều kiện đúng hoặc điều kiện sai:

- Các đường nối các nút với nhau.

Nhập n, A[1…n]



max:= A(1)

i:=2



True

ĐK



S

False

Ví dụ, sơ đồ khối sau đây

mô tả thuật toán tìm giá trị lớn nhất trong mảng số A có

i<=n

n phần tử.

Đ

S

Max < A(i)



max:= A(i)



i := i + 1



6



In giá trị max



Kết thúc



Đ



2.2. Giả mã

a) Cấu trúc tuần tự: Liệt kê các công việc, các thao tác theo thứ tự. Để hỗ trợ cho việc

theo dõi được thuận tiện cũng có thể thêm số thứ tự.

b) Cấu trúc rẽ nhánh:

 If (điều kiện) Then (công việc);

 If (điều kiện) Then (công việc 1) Else (Công việc 2);

c) Cấu trúc lặp:











For (biến):= (giá trị đầu) to (giá trị cuối) do (công việc);

For (biến):= (giá trị đầu) downto (giá trị cuối) do (công việc);

While (điều kiện) do (công việc);

Repeat

- (công việc 1);

- (công việc 2);

- .....

- (công việc k);

Until (điều kiện);



2.3. Một số thuật toán quy hoạch động

- Bài toán nhân ma trận.

7



- Tìm đường đi ngắn nhất.

- Dãy con dài nhất.



Phần II: BÀI TOÁN TÌM KIẾM

1. Định nghĩa Bài toán tìm kiếm

Bài toán tìm kiếm là: Tìm kiếm một phương án, đáp án theo yêu cầu đầu vào.

VD:



- Cho một danh sách xác định vị trí xuất hiện của một phần tử trong danh sách.

- Tìm kiếm giải pháp lựa chọn để đạt giá trị cực đại trong bài toán cái túi.



Bài toán xảy ra trong hai tình huống:

- Dữ liệu xuất hiện được coi là ngẫu nhiên.

- Dữ liệu thỏa mãn một số ràng buộc nhất định.

2. Phân loại

-Tìm kiếm tuần tự

- Tìm kiếm nhị phân

- Tìm kiếm dựa trên quy hoạch

.......

3. Đánh giá hiệu quả của 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 (thời gian được

sử dụng để tính bằng máy hoặc bằng phương pháp thủ công) – độ phức tạp thời gian, 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 dung lượng bộ nhớ đã sử dụng để tính toán khi kích thước đầu vào đã

xác định – độ phức tạp không gian.

Độ phức tạp không gian gắn liền với việc xem xét các cấu trúc dữ liệu đặc biệt

được dùng để thể hiện 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 xác

định.

4. Giải thuật tìm kiếm

Bài toán

8



Giả sử R là mảng gồm n bản ghi, bản ghi thứ k có một khóa X(k), với k=1,2...,n. Hãy

tìm bản ghi có khóa bằng (hoặc bé hơn, lớn hơn) giá trị b cho trước.

Giá trị b được gọi là khóa tìm kiếm hay đối trị tìm kiếm. Bài toán được gọi là giải

xong nếu như tìm được bản ghi thứ k nào đó mà X(k) = b hoặc khẳng định được rằng

không có bản ghi nào thỏa mãn điều kiện đặt ra, tức là X(k) b với mọi k=1,2,...,n.

4.1.Tìm kiếm tuần tự (Sequential Searching)

Ý tưởng

Bắt đầu từ bản ghi thứ nhất (k=1), lần lượt so sánh khóa tìm kiếm b với khóa tương

ứng của các bản ghi trong mảng, cho tới khi hoặc là tìm được bản ghi thỏa mãn điều kiện

hoặc là hết mảng mà không thấy.

Thuật toán

Input: Mảng X[1..n], giá trị b

Output: Chỉ số k [1..n] mà tại đó X(k)=b hoặc 0 nếu X(k) b với k [1..n]

Function TKTT (X: mảng; b: Khóa tìm kiếm): Chỉ số;

Begin

k:=1;

While (X(k) b & (k



n) do k:=k+1;



If k=n+1 then TKTT:=0 else TKTT:=k;

End;

Đánh giá thuật toán

Trong trường hợp xấu nhất ta cần 2n phép so sánh. Tuy nhiên nếu ta thực hiện một

cải tiến nhỏ như sau:

Input: Mảng X[1..n+1], giá trị b

Output: Chỉ số k [1..n] mà tại đó X(k)=b hoặc 0 nếu X(k) b với k [1..n]

Function TKTT (X: mảng; b: Khóa tìm kiếm): Chỉ số;

Begin

9



Xem Thêm
Tải bản đầy đủ (.doc) (14 trang)

×