Cấu trúc dữ liệu và giải thuật 2008-2009 - Thiết kế thuật toán

Chia bài toán lớn thành các bài toán nhỏ cùng dạng với bài toán lớn nhưng có kích thước nhỏ hơn. • Giải quyết các bài toán nhỏ ñộc lập • Kết hợp nghiệm của nhửng bài toán nhỏ ñể thu ñược bài toán lớn

pdf14 trang | Chia sẻ: tuandn | Lượt xem: 2280 | Lượt tải: 2download
Bạn đang xem nội dung tài liệu Cấu trúc dữ liệu và giải thuật 2008-2009 - Thiết kế thuật toán, để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
Thiết kế thuật toán Lê Sỹ Vinh Bộ môn Khoa Học Máy Tính – Khoa CNTT ðại Học Công Nghệ - ðHQGHN Email: vinhioi@yahoo.com Chia ñể trị (Divide and Conquer) • Chia bài toán lớn thành các bài toán nhỏ cùng dạng với bài toán lớn nhưng có kích thước nhỏ hơn. • Giải quyết các bài toán nhỏ ñộc lập • Kết hợp nghiệm của nhửng bài toán nhỏ ñể thu ñược bài toán lớn Ví dụ: Merge sort ðể sắp xếp một mảng A[start…end], ta chia mảng A thành 2 mảng con A1 và A2. Sắp xếp A1 và A2, sau ñó hòa nhập chúng thành một ñể ñược mang A ñã sắp xếp. void MergeSort( Item A[ ], int start, int end) { if (start < end) { int mid = (start + end)/2; MergeSort ( A, start, mid ); MergeSort ( A, mid+1, end); Merge ( A, start, mid, end); } } Ví dụ: Quick sort Tư tưởng của Quick sort: Phân chia danh sách dữ liệu cần sắp xếp ra thành hai phần “phần bên trái” và “phần bên phải” sao cho các phần tử ở phần bên trái nhỏ hơn hoặc bằng các phần tử ở phần bên phải. Sau khi phân chia, tiếp tục thực hiện “quick sort trên hai phần dữ liệu trên. Void quickSort (Item A[], int start, int end) { if (start < end) { pivotLocation = partition (A, start, end); quickSort (A, start, pivotLocation – 1); quickSort (A, pivotLocation + 1, end) } } Binary search BinarySearch (lookingData, items, start, end) { if (start > end) return (-1) else { mid = (start + end) / 2; if (items[mid] == lookingData) return mid else if (items[mid] > lookingData) BinarySearch (lookingData, items, start, mid -1) else BinarySearch (lookingData, items, mid + 1, end) } } Tìm phần tử lớn nhất trong danh sách findMax (int start, int end, items) { if (start == end) return items[start] else { int med = (start + end) / 2; Item max1 = findMax (start, med, items); Item max2 = findMax (med + 1, end, items); return Max (max1, max2); } } Chiến lược vét cạn (Backtracking) Lần lượt duyệt qua tất cả các trạng thái có thể trong không gian tìm kiếm • A = (a0, a1,..an-1): Là một trạng thái gồm N thành phần, nếu trạng thái A thỏa mãn các yêu cầu của bài toán thì gọi là vector nghiệm. Trong ñó ai ∈ Si • ðể liệt kê ñược tất cả các trạng thái A có thể, ta tiến hành gọi ñệ quy qua N vòng, tại bước thứ i sẽ lần lượt tiến hành thử tất cả các ai ∈ Si Chiến lược vét cạn (Backtracking) Backtracking (A, i) { for ai ∈ Si { A = A ⋃ ai ; if (i < N) Backtracking (A, i+1) else CheckConfiguration (A); A = A – {ai} } } Ví dụ: Liệt kê tất cả xâu nhị phân ñộ dài N Void Binary (A, i) { for (int v = 0; v < 2; v ++) { A[i] = v; if (i < N) Binary (A, i+1) else A.print (); A[i] = -1; } } Ví dụ: Liệt kê tất cả hoán vị ñộ dài N Void Permutation (A, dd, i) { for (int v = 1; v <= N ; v ++) if (not dd[v]) { A[i] = v; dd[v] = true; if (i < N) Permutation(A, dd, i+1) else A.print (); A[i] = -1; dd[v] = false; } } Tìm ñường ñi ngắn nhất qua tất cả các ñỉnh của ñồ thị Bài toán cái ba lô Có N ñồ vật, ñồ vật i có khối lượng wi và giá trị ti. Một tên trộm có 1 chiếc ba lô có thể mang ñược không qúa M kg. Hãy tìm cách mang một số ñồ vật ñể tổng giá trị lấy ñược là lớn nhất.