Do an thuat toan tim kiem trong c+

12 5 0
Do an   thuat toan tim kiem trong c+

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Thuật tốn tìm kiếm C++ Phần I Giới thiệu thuật tốn tìm kiếm Trong ngành khoa học máy tính, giải thuật tìm kiếm thuật tốn lấy đầu vào toán trả kết lời giải cho tốn đó, thường sau cân nhắc loạt lời giải Hầu hết thuật tốn nghiên cứu nhà khoa học máy tính để giải toán thuật toán tìm kiếm Tập hợp tất lời giải tốn gọi khơng gian tìm kiếm Thuật tốn thử sai (brute-force search) hay thuật tốn tìm kiếm "sơ đẳng" khơng có thơng tin sử dụng phương pháp đơn giản trực quan Trong đó, thuật tốn tìm kiếm có thơng tin sử dụng heuristics để áp dụng tri thức cấu trúc khơng gian tìm kiếm nhằm giảm thời gian cần thiết cho việc tìm kiếm Tìm kiếm khơng có thơng tin Một giải thuật tìm kiếm khơng có thơng tin giải thuật khơng tính đến chất cụ thể tốn Khi đó, giải thuật dạng cài đặt tổng quát, cài đặt sử dụng diện rộng toán (do sử dụng trừu tượng hóa) Nhược điểm giải thuật phần lớn khơng gian tìm kiếm kích thước lớn, q trình tìm kiếm (đặc biệt tìm kiếm theo cây) cần khoảng thời gian đáng kể cho ví dụ nhỏ Do đó, để tăng tốc độ q trình tìm kiếm, đơi dùng giải thuật tìm kiếm có thơng tin Tìm kiếm danh sách Có lẽ giải thuật tìm kiếm danh sách loại giải thuật tìm kiếm Mục đích tìm tập hợp phần tử chứa khóa Do tốn thường gặp khoa học máy tính, nên độ phức tạp tính tốn thuật tốn nghiên cứu kỹ Thuật toán đơn giản tìm kiếm tuyến tính Thuật tốn kiểm tra phần tử danh sách theo thứ tự danh sách Nó có thời gian chạy lớn: O(n), n số phần tử danh sách, sử dụng thẳng cho danh sách mà khơng cần tiền xử lý Tìm kiếm nhị phân thuật toán cao cấp với thời gian chạy O(log n) Đối với danh sách lớn, thuật tốn tốt hẳn tìm kiếm tuyến tính, địi hỏi danh sách phải xếp từ trước (xem thuật toán xếp) đòi hỏi khả truy nhập ngẫu nhiên (random access) Tìm kiếm nội suy (Interpolation search) tốt tìm kiếm nhị phân danh sách lớn với phân bố gần Thuật toán Grover thuật toán lượng tử cho phép tăng tốc độ gấp lần so với tìm kiếm tuyến tính truyền thống danh sách chưa xếp Bảng băm (hash table) dùng cho tìm kiếm danh sách Nó địi hỏi thời gian số trường hợp trung bình, lại cần nhiều phụ phí không gian nhớ thời gian chạy O(n) cho trường hợp xấu Một phương pháp tìm kiếm khác dựa cấu trúc liệu chuyên biệt sử dụng tìm kiếm nhị phân cân (self-balancing binary search tree) đòi hỏi thời gian chạy O(log n); giải thuật loại coi mở rộng tư tưởng tìm kiếm nhị phân phép chèn xóa nhanh Xem mảng liên kết (associative array) để biết thêm cấu trúc liệu tìm kiếm danh sách Đa số giải thuật tìm kiếm danh sách, chẳng hạn tìm kiếm tuyến tính, tìm kiếm nhị phân, tìm kiếm nhị phân cân bằng, mở rộng với chút chi phí bổ sung để tìm tất giá trị nhỏ lớn khóa cho trước - phép tốn gọi tìm kiếm khoảng (range search) Bảng băm ngoại lệ, tìm kiếm khoảng khơng thể thực cách hiệu bảng băm Tìm kiếm Tìm kiếm trung tâm kỹ thuật tìm kiếm Các thuật tốn tìm kiếm gồm nút, tường minh xây dựng dần trình tìm kiếm Nguyên lý là: nút lấy từ cấu trúc liệu, nút xem xét bổ sung vào cấu trúc liệu Bằng cách thao tác cấu trúc liệu này, tìm kiếm duyệt theo thứ tự khác nhau, chẳng hạn theo mức (tìm kiếm theo chiều rộng) tới nút trước quay lui (tìm kiếm theo chiều sâu) Các ví dụ khác tìm kiếm bao gồm: tìm kiếm lặp sâu dần, tìm kiếm chiều sâu giới hạn, tìm kiếm hai chiều tìm kiếm chi phí Tìm kiếm đồ thị Nhiều tốn lý thuyết đồ thị giải thuật tốn tìm kiếm, chẳng hạn thuật toán Dijkstra, thuật toán Kruskal, giải thuật láng giềng gần giải thuật Prim Các thuật tốn coi mở rộng thuật tốn tìm kiếm Tìm kiếm có thơng tin Trong tìm kiếm có thơng tin, người ta sử dụng đánh giá heuristic đặc thù cho tốn cần giải với vai trị hướng dẫn cho trình tìm kiếm Một cách đánh giá heuristic tốt làm cho q trình tìm kiếm có thông tin hoạt động hiệu hẳn phương pháp tìm kiếm khơng có thơng tin Có vài thuật tốn tìm kiếm có thơng tin trội dành cho danh sách Một số bảng băm với hàm băm heuristic dựa toán giải Đa số thuật tốn tìm kiếm có thơng tin tìm kiếm Trong có tìm kiếm theo lựa chọn tốt A* Cũng thuật toán khơng có thơng tin, thuật tốn mở rộng để làm việc đồ thị Tìm kiếm đối kháng Trong trị chơi cờ vua hay cờ tướng, có trị chơi bao gồm tất nước hai đấu thủ cấu hình bàn cờ kết nước Ta tìm kiếm để có chiến lược chơi hiệu Dạng toán có đặc điểm độc vơ nhị ta phải tính đến nước mà đối thủ ta sử dụng Để làm điều này, chương trình máy tính chơi cờ, dạng khác trí tuệ nhân tạo lập kế hoạch tự động (machine planning), thường sử dụng thuật tốn tìm kiếm thuật tốn minimax, tỉa tìm kiếm, tỉa alpha-beta (alpha-beta pruning) Thỏa mãn ràng buộc Đây loại tìm kiếm để giải tốn thỏa mãn ràng buộc mà đó, thay tìm đường đi, lời giải đơn giản tập giá trị gán cho tập biến Do biến xử lý theo thứ tự tùy ý, thuật tốn thơng thường dành cho tìm kiếm khơng hiệu Các phương pháp giải toán ràng buộc bao gồm tìm kiếm tổ hợp quay lui, hai tận dụng đặc điểm tự có liên quan đến toán ràng buộc Phần II Vì cần có thuật tốn tìm kiếm? Trong thực tế, có nhiều tốn, tất chúng quy toán nhất, tốn tìm kiếm Ví dụ bạn giải tốn, bạn có làm cách mục đích cuối bạn tìm lời giải tốn Hay bạn thực xếp, lọc phần tử danh sách, mục đích bạn tìm kiếm phần tử thỏa mãn yêu cầu Từ nhu cầu thực tế đó, tốn tìm kiếm dẫn đến phải tạo thuật tốn tìm kiếm để giải Vậy thuật tốn tìm kiếm gì? Thuật tốn tìm kiếm (searching algorithm) thuật tốn giúp ta tìm tập liệu cho nhiều phần tử thỏa mãn yêu cầu tìm kiếm Tùy theo cấu trúc liệu mà có thuật tốn tìm kiếm khác phù hợp cho cấu trúc Do đó, khơng nên học thuộc lịng thuật tốn tìm kiếm tập liệu, cấu trúc liệu ngơn ngữ cụ thể Hãy học ý tưởng thuật tốn áp dụng linh hoạt cho cấu trúc liệu khác ngơn ngữ lập trình khác Trong này, dùng C++ để minh họa cho thuật tốn tìm kiếm, bạn áp dụng cho ngơn ngữ lập trình mà bạn thích Java hay Python… Phần III Các thuật tốn tìm kiếm Trong phần này, em giới thiệu thuật tốn tìm kiếm phổ biến nhất: tìm kiếm tuyến tính, tìm kiếm nhị phân tìm kiếm nội suy Tìm kiếm tuyến tính Tìm kiếm tuyến tính (linear search) hay tìm kiếm (sequential search) thuật tốn tìm kiếm cách duyệt qua tất phần tử danh sách gặp phần tử cần tìm hết danh sách Do cách tìm kiếm duyệt từ đầu đến cuối này, độ phức tạp thời gian thuật toán O(n) Chúng ta có mảng A có n phần tử vị trí Để tìm kiếm phần tử x mảng A này, ta làm sau: Gán i = So sánh giá trị A[i] x: Nếu A[i] == x dừng trả giá trị i (vị trí x mảng A) Nếu A[i] != x sang bước 3 Gán i = i + 1: Nếu i == n (tức hết mảng) dừng lại trả kết -1 (khơng tìm thấy x) Nếu i < n quay lại bước Tìm kiếm tuyến tính Dựa thao tác trên, viết lại code C++ sau: int LinearSearch(int A[], int n, int x){ int i = 0; while (i < n && A[i] != x) i++; if (i == n) return -1; // khơng tìm thấy x return i; // tìm thấy x, trả vị trí x mảng a} Thông thường, bạn hay sử dụng for cho đơn giản sau: int LinearSearch(int A[], int n, int x){ for (int i = 0; i < n; i++) if (A[i] == x) return i; return -1; // duyệt hết mảng, khơng tìm thấy x} Chúng ta cải tiến chút phương pháp đặt lính canh sau: gán A[n] = x, lúc kiểm tra không cần kiểm tra i < n chạy đến cuối gặp x “lính” vừa đặt Vậy thuật toán trở thành: int LinearSearch(int A[], int n, int x){ int i = 0; A[n] = x; while (A[i] != x) i++; if (i == n) return -1; return i;} Tìm kiếm nhị phân Tìm kiếm nhị phân (binary search) hay số tên gọi khác tìm kiếm nửa khoảng (half-interval search), tìm kiếm logarit (logarithmic search), chặt nhị phân (binary chop) thuật tốn tìm kiếm dựa việc chia đơi khoảng xét sau lần lặp, sau xét tiếp nửa khoảng có khả chứa giá trị cần tìm, không chia đôi khoảng Thuật tốn tìm kiếm nhị phân áp dụng cho danh sách có thứ tự hay xếp Ví dụ bạn có dãy số tăng từ đến 100, yêu cầu bạn tìm số 30 Bạn xem phần tử dãy số thấy số 50, bạn biết 30 nằm khoảng 50 thơi, giới hạn tìm kiếm thu hẹp lại nửa Ví dụ tìm số 70 chẳng hạn 50 lại nhỏ 70, ta biết 70 nằm khoảng từ 51 đến 100 Cứ tiếp tục tìm gặp khơng thể chia đơi khoảng Do cách tìm kiếm chia đơi khoảng này, sau lần lặp, khoảng xét lại chia đôi, tiếp tục khoảng tiếp lại chia đôi khoảng chia trước Do đó, độ phức tạp thời gian thuật toán O(log(n)), tốt rất nhiều so với tìm kiếm tuyến tính Cho mảng A có n phần tử vị trí 0, mảng A xếp tăng dần (lưu ý thứ tự tăng dần, giảm dần có cách cài đặt khác chút trình bày bên dưới) Để tìm phần tử có giá trị x mảng A cài đặt thuật tốn tìm kiếm nhị phân sau: Gán left = 0, right = n – Gán mid = (left + right) / (lấy phần nguyên, phần tử khoảng tại) Nếu A[mid] == x: Dừng lại trả giá trị mid (chính vị trí x mảng A) Nếu A[mid] > x (có thể x nằm nửa khoảng trước): right = mid – // giới hạn khoảng tìm kiếm lại nửa khoảng trước Nếu A[mid] < x (có thể x nằm nửa khoảng sau): left = mid + // giới hạn khoảng tìm kiếm lại nửa khoảng sau Nếu left x: o left = mid + Tìm kiếm nội suy Tìm kiếm nội suy (interpolation search) thuật toán cải tiến từ thuật tốn tìm kiếm nhị phân Thay xác định điểm danh sách, thuật tốn tìm kiếm nội suy xác định điểm gần với vị trí phần tử cần tìm, tối ưu thời gian so với thuật tốn tìm kiếm nhị phân Độ phức tạp thời gian mà tốt O(log(log(n))) Tuy nhiên, thuật tốn tìm kiếm nhị phân ổn định với độ phức tạp thời gian O(log(n)), thuật tốn tìm kiếm nội suy lại khơng Trong trường hợp xấu dãy tăng/giảm phân bố khơng đều, thuật tốn tìm kiếm đạt độ phức tạp O(n), khơng khác dùng thuật tốn tìm kiếm tuyến tính Do đó, bạn nên sử dụng thuật tốn tìm kiếm nhị phân để đảm bảo độ phức tạp O(log(n)) Vẫn mảng A, n phần tử tăng dần Tìm x mảng dùng thuật tốn tìm kiếm nội suy sau: Gán left = 0, right = n – Gán mid = left + (right – left) * (x – a[left]) / (a[right] – a[left]): Nếu A[mid] == x: Dừng lại trả giá trị mid Nếu A[mid] > x: right = mid – Nếu A[mid] < x: left = mid + Nếu left = A[left] x x: o left = mid + Giờ xem cài đặt thuật tốn tìm kiếm nội suy C++ với mảng tăng: int InterpolationSearch(int A[], int n, int x){ int left = 0; int right = n - 1; int mid; while (left = A[left] && x x) right = mid - 1; else if (A[mid] < x) left = mid + 1; } return -1; // Khơng tìm thấy x} Lưu ý: sử dụng thuật tốn tìm kiếm nhị phân nội suy, mảng chưa xếp, nên sử dụng kèm với thuật tốn xếp có hiệu suất cao Quick Sort hay Merge Sort để xếp nhằm tối ưu hóa thuật tốn Nếu tìm kiếm nhanh mà xếp chậm khơng có ý nghĩa tập liệu lớn Phần III Tổng kết Trên loại thuật tốn tìm kiếm phổ biến Các thuật tốn giúp ta tìm tập liệu cho nhiều phần tử thỏa mãn yêu cầu tìm kiếm ... thuật tốn tìm kiếm cách duyệt qua tất phần tử danh sách gặp phần tử cần tìm hết danh sách Do cách tìm kiếm duyệt từ đầu đến cuối này, độ phức tạp thời gian thuật toán O(n) Chúng ta có mảng A có n... thể chia đơi khoảng Do cách tìm kiếm chia đơi khoảng này, sau lần lặp, khoảng xét lại chia đôi, tiếp tục khoảng tiếp lại chia đôi khoảng chia trước Do đó, độ phức tạp thời gian thuật toán O(log(n)),... Thay xác định điểm danh sách, thuật tốn tìm kiếm nội suy xác định điểm gần với vị trí phần tử cần tìm, tối ưu thời gian so với thuật tốn tìm kiếm nhị phân Độ phức tạp thời gian mà tốt O(log(log(n)))

Ngày đăng: 17/07/2022, 11:26

Tài liệu cùng người dùng

Tài liệu liên quan