Tải bản đầy đủ

PHÂN TÍCH VÀ THIẾT KẾ GIẢI THUẬT : CÁC GIẢI THUẬT SẮP XẾP, GIẢI THUẬT TÌM KIẾM NHỊ PHÂN, GIẢI THUẬT THAM LAM , Insertion Sort , Selection Sort , Merge Sort , Quick Sort , Giải bài toán ATM sử dụng giải thuật tham lam

Mục lục


BÁO CÁO BÀI TẬP LỚN 2
Môn : PHÂN TÍCH VÀ THIẾT KẾ GIẢI THUẬT
I.

I. CÁC GIẢI THUẬT SẮP XẾP

1.Insertion Sort :
Ý tưởng của thuận toán : Giả sử ta có trước một dãy số đã theo thứ tự tăng dần, sau đó ta muốn chèn
thêm một phần tử vào dãy thì việc cần làm là tìm một vị trí thích hợp cho phần tử đó để dãy vẫn giữ đúng
thứ tự ban đầu.
-

Do dãy số đang tăng dần, nên để tìm được vị trí đó ta chỉ cần duyệt qua các phần tử trong dãy từ cuối
đến đầu, nếu gặp một phần tử A[i] nào nhỏ hơn hoặc bằng phần tử x cần chèn thì chèn x vào ngay sau A[i],
thì dãy số A vẫn giữ đúng thứ tự tăng dần.
Vậy với dãy số đầu vào A[1..n] không theo thứ tự, ta có thể xem A[1] là một dãy có thứ tự (do chỉ có
1 phần tử), kế tiếp ta tìm vị trí để chèn A[2] vào, sau đó ta đã được dãy A[1..2] có thứ tự. Lặp lại các bước
tương tự cho đến khi A[1..n] có thứ tự


• Các bước thực hiện:
- Bước 1: i = 2 (xem A[1] là dãy số có thứ tự vì nó chỉ có 1 phần tử)
- Bước 2: temp = A[i] (phải lưu A[i] ra biến tạm vì trong lúc hoán đổi vị trí sẽ làm mất giá trị của A[i])
- Bước 3: j = i – 1
- Bước 4: Xét từ j về 1, tìm vị trí thích hợp để chèn temp vào mãng A
o Nếu A[j] > temp thì A[j+i] = A[j]


Nếu j > 1 thì j = j – 1; Lặp lại bước 4
Ngược lại, A[j] = temp;
o Ngược lại: A[j+1] = temp;
- Bước 5: Nếu i < n thì i = i + 1; Quay lại bước 2;
Ngược lại thì ta đã có mảng A[1..n] theo thứ tự tăng dần.
• Cài đặt thuật toán : Ngôn ngữ Java

• Đánh giá độ phức tạp của giải thuật :
Độ phức tạp của giải thuật này là O(n2)
2.Selection Sort:

Ý tưởng của thuật toán :
Đây là thuật toán tự nhiên nhất, rất dễ hiểu và dễ
tưởng của thuật toán như sau:

thực hiện. Tư

+ Chọn phần tử nhỏ nhất trong n phần tử ban đầu,
về vị trí đúng là đầu tiên của dãy hiện hành.

đưa phần tử này

+Sau đó không quan tâm đến nó nữa, xem dãy
còn n-1 phần tử còn lại, bắt đầu từ vị trí thứ 2.

hiện hành chỉ

+Lặp lại quá trình trên cho dãy hiện hành đến khi
chỉ còn 1 phần tử.

dãy hiện hành


+Dãy ban đầu có n phần tử, vậy tóm tắt ý tưởng
thực hiện n-1 lượt việc đưa phần tử nhỏ nhất trong dãy
trí đúng ở đầu dãy.

thuật toán là
hiện hành về vị


Các bước thực hiện:
- Bước 1: i = 1
- Bước 2: Tìm phần tử nhỏ nhất A[min] trong dãy hiện hành từ A[i] đến A[n]
- Bước 3: Hoán vị A[min] và A[i]
- Bước 4: i = i + 1
- Bước 5: Nếu i < n thì quay lại bước 2 (i = n tức là mãng chỉ còn 1 phần tử)

• Cài đặt thuật toán : Ngôn ngữ Java

• Đánh giá độ phức tạp :
Độ phức tạp là: O (n2)


3.Merge Sort :
• Ý tưởng của thuật toán :
Merge Sort là một thuật toán sắp xếp để sắp xếp các danh sách (hoặc bất kỳ cấu trúc dữ liệu nào có
thể truy cập tuần tự, v.d. luồng tập tin) theo một trật tự nào đó. Thuật toán này là một ví dụ tương đối điển
hình của lối thuật toán chia để trị.

Các bước thực hiện thuật toán như sau:


Bước 1 : // Chuẩn bị

k = 1; // k là chiều dài của dãy con trong bước hiện hành



Bước 2 :

Tách dãy a1, a2, ., an thành 2 dãy b, c theo nguyên tắc luân phiên từng nhóm k phần tử: b = a1, ., ak,
a2k+1, ., a3k, . c = ak+1, ., a2k, a3k+1, ., a4k, .



Bước 3 :

Trộn từng cặp dãy con gồm k phần tử của 2 dãy b, c vào a.



Bước 4 : k = k*2;

Nếu k < n thì trở lại bước 2.
Ngược lại: Dừng

• Cài đặt thuật toán : Ngôn ngữ Java


• Đánh giá độ phức tạp :
Ta thấy rằng số lần lặp của bước 2 và bước 3 trong thuật toán MergeSort bằng log 2n do sau mỗi lần lặp
giá trị của k tăng lên gấp đôi. Dễ thấy, chi phí thực hiện bước 2 và bước 3 tỉ lệ thuận bới n. Như vậy, chi phí
thực hiện của giải thuật MergeSort sẽ là O(nlog 2n). Do không sử dụng thông tin nào về đặc tính của dãy cần
sắp xếp, nên trong mọi trường hợp của thuật toán chi phí là không đổi. Ðây cũng chính là một trong những
nhược điểm lớn của thuật toán.


4.Quick Sort :
• Ý tưởng của thuật toán :
Đây là giả thuật sắp xếp nhanh, chỉ tốn O(nlogn). Cài đặt của giả thuật tương đối phức tạp. Chúng ta cần chú
ý đến:
- Pivot: ta gọi là chốt
- Partition: Gọi là điểm phân

hoạch

+ Đối với giải thuật này, chúng ta
phần tử hay mảng có tất cả phần
một mảng có thứ tự.

xem 1 mảng 1
tử giống nhau là

+ Ta sẽ chi mảng thành 2 mảng
phải.

con:

+ Sắp xếp 2 mảng con, và cứ như
mảng còn 1 phần tử.

thế cho đến khi

+Nếu mảng Trái đã có thứ tự và
có thứ tự thì mảng của chúng ta đã
tự.

mảng phải cũng
là mảng có thứ

Trái



A = {59, 31, 12, 33, 27, 97, 91, 19, 18, 63 }

Bước 1: Tìm chốt: Chốt là phần tử lớn nhất trong 2 phần tử khác nhau đầu tiên của mảng. Nếu mảng
có 1 phần tử tất cả phần tử bằng nhau sẽ không có chốt:
Chốt của mảng trên la 59 (vị trí 0).
VD:
+ 1, 1, 5, 3, 2 -> chốt sẽ là 5
+ 5, 5, 5, 3, 1, 2, 3 -> chốt là 5
+ 6 -> không có chốt


+ 7, 7, 7, 7 -> không có chốt
-

Bước 2: Tìm điểm phân hoạch:

+ Dùng 2 cờ: L (trái) và R (Phải)
+ L chạy từ trái qua, dừng lại khi gặp phần tử >= pivot
+ R chạy từ phải qua, dừng lại khi gặp phần tử < pivot
+ Tại điểm dùng: Nếu L < R : Chúng ta sẽ swap A[L] và A[R]
+ Dừng lại khi L > R
+ Partition sẽ là L. Đây sẽ là chỉ số đầu tiên của mảng bên phải
VD: với mảng A = {59, 31, 12, 33, 27, 97, 91, 19, 18, 63 }
PivotLey = 59
L = 0, R = 9:
b1. L dừng lại tại vị trí 0: vì A[L] >= pivot, R dừng lại tại vị trí 8, vì A[R] = 18 < pivot.
Swap: 18, 31, 12, 33, 27, 97, 91, 19, 59, 63
b2, tiếp tục cho đến khi L > R
- Bước 3: Lặp lại như thế (Dùng đệ qui)
• Cài đặt thuật toán : Ngôn ngữ Java


• Đánh giá độ phức tạp :
Độ phức tạp của giải thuật này là O(nlogn)
Là một thuật toán sắp xếp nhanh nhất trong thực tế.
II.

GIẢI THUẬT TÌM KIẾM NHỊ PHÂN

• Ý tưởng của giải thuật tìm kiếm nhị phân :
Tìm kiếm nhị phân ( binary search ) là một thuật toán dùng để tìm kiếm phần tử trong một danh sách đã sắp
xếp ( sorted lists and array ).
So sánh phần tử cần tìm với phần tử nằm chính giữa danh sách để xác định vùng dữ liệu có chứa giá trị cần
tìm. Nếu 2 phần tử bằng nhau thì thuật toán kết thúc. Nếu 2 phần tử không bằng nhau thì tùy vào phần tử nào
lớn hơn, thuật toán lặp lại bước so sánh trên với nửa đầu hoặc nửa sau của danh sách.


Vì sau mỗi bước tìm kiếm, miền dữ liệu cần xét giảm đi một nửa nên thời gian thực thi của thuật toán là hàm
logarit.
Phép tìm kiếm nhị phân được thực hiện trên dãy khoá có thứ tự (xét dãy tăng dần):
a[0]<=a[1]<=a[2]<=...<=a[n-1]. Giá trị cần tìm x.

Chia đôi dãy khoá cần tìm kiếm. So sánh khoá giữa dãy với x, có 3 trường hợp xãy ra:
- Giá trị khoá này bằng x, tìm kiếm thành công
- Giá trị khoá này lớn hơn x, thì ta tiến hành tìm x với nữa bên trái của khoá này
- Giá trị khoá này nhỏ hơn x, thì ta tiến hành tìm x với nữa bên phải của khoá này

Trường hợp tìm kiếm thất bại khi dãy khoá cần tìm không có phần tử nào.

1.Giải thuật tìm kiếm nhị phân không sử dụng đệ quy :
• Cài đặt thuật toán : Ngôn ngữ C++


• Đánh giá độ phức tạp :
– Tốt nhất : O(1) – Phần tử cần tìm ở chính giữa danh sách
– Xấu nhất : O(log2(n)) – Không có phần tử cần tìm trong danh sách
– Trung bình : O(log2(n/2)) – Xác suất các phần tử trong danh sách chứa giá trị cần tìm là như nhau.

2.Giải thuật tìm kiếm nhị phân sử dụng đệ quy :
• Cài đặt thuật toán : Ngôn ngữ C++


• Đánh giá độ phức tạp :
– Tốt nhất : O(1) – Phần tử cần tìm ở chính giữa danh sách

– Xấu nhất : O(log2(n)) – Không có phần tử cần tìm trong danh sách

– Trung bình : O(log2(n/2)) – Xác suất các phần tử trong danh sách chứa giá trị cần tìm là như nhau.


III.

GIẢI THUẬT THAM LAM

1. Bài toán đầu tư sử dụng giải thuật tham lam
• Ý tưởng :
Giải thuật tham lam (Greedy Algorithm) là giải thuật tối ưu hóa tổ hợp. Giải thuật tìm kiếm, lựa chọn
giải pháp tối ưu địa phương ở mỗi bước với hi vọng tìm được giải pháp tối ưu toàn cục.

Giải thuật tham lam lựa chọn giải pháp nào được cho là tốt nhất ở thời điểm hiện tại và sau đó giải bài
toán con nảy sinh từ việc thực hiện lựa chọn đó. Lựa chọn của giải thuật tham lam có thể phụ thuộc vào
lựa chọn trước đó. Việc quyết định sớm và thay đổi hướng đi của giải thuật cùng với việc không bao giờ
xét lại các quyết định cũ sẽ dẫn đến kết quả là giải thuật này không tối ưu để tìm giải pháp toàn cục.
Là một dạng của bài toán tối ưu, nó có dạng tổng quát như sau:




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 thuộc 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 thuộc D sao cho hàm f(X) đạt min (max). Phương án X như vậy gọi là tối
ưu.
Ta có thể tìm thấy phương án tối ưu bằng “vét cạn” nghĩa là xét tất cả các phương án trong tập D (hữu
hạn) để tìm phương án tốt nhất. Mặc dù tậ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 vét cạn ta có thể cần một thời gian hàm mũ.


• Cài đặt giải thuật: Ngôn ngữ Java
Class InVest.java ( Đầu Tư ) :


Class ProJect.java (Dự Án) :


Class ChuongTrinh.java (Test)


2.Giải bài toán ATM sử dụng giải thuật tham lam :
Ý tưởng :
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.
Gọi X = (X1, X2, X3, X4) là một phương án trả tiền, trong đó X1 là số tờ giấy bạc mệnh giá 100.000
đồng, X2 là số tờ giấy bạc mệnh giá 50.000 đồng, X3 là số tờ giấy bạc mệnh giá 20.000 đồng và X4 là số tờ
giấy bạc mệnh giá 10.000 đồng. Theo yêu cầu ta phải có
X1 + X2 + X3 + X4 nhỏ nhất và X1 * 100.000 + X2 * 50.000 + X3 *
20.000 + X4 * 10.000 = n.
Áp dụng kĩ thuật tham ăn để giải bài toán này là: để 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.

• Cài đặt giải thuật: Ngôn ngữ C#




Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay

×