Ngăn xếp, hàng đợi, heap, cây nhị phân, graph, độ phức tạp, hàm băm,Giải thuật tìm kiếm theo chiều sâu , BFS,Thuật toán Dijkstra,Thuật toán Bellman – Ford,Thuật toán Rabin – Karp, thuật toán Knuth – Morris – Pratt
1 Giải thuật 1.1 Tổng quan giải thuật 1.1.1 Tổng quan môn học Giới thiệu kiến thức Giải thuật a) Giải thuật Giải thuật (hay cịn gọi thuật tốn - tiếng Anh Algorithms) tập hợp hữu hạn thị để thực thi theo thứ tự để thu kết mong muốn Nói chung giải thuật độc lập với ngơn ngữ lập trình, tức giải thuật triển khai nhiều ngơn ngữ lập trình khác Một số giải thuật quan trọng: Giải thuật Tìm kiếm: Giải thuật để tìm kiếm phần tử cấu trúc liệu Giải thuật Sắp xếp: Giải thuật để xếp phần tử theo thứ tự Giải thuật Chèn: Giải thuật để chèn phần từ vào cấu trúc liệu Giải thuật Cập nhật: Giải thuật để cập nhật (hay update) phần tử tồn cấu trúc liệu Giải thuật Xóa: Giải thuật để xóa phần tử tồn từ cấu trúc liệu b) Đặc điểm giải thuật: Một giải thuật nên có đặc điểm sau Tính xác định: Giải thuật nên rõ ràng không mơ hồ Mỗi giai đoạn (hay bước) nên rõ ràng mang mục đích định Dữ liệu đầu vào xác định: Một giải thuật nên có nhiều liệu đầu vào xác định Kết đầu ra: Một giải thuật nên có nhiều liệu đầu xác định, nên kết nối với kiểu kết bạn mong muốn Tính dừng: Các giải thuật phải kết thúc sau số hữu hạn bước Tính hiệu quả: Một giải thuật nên thi hành với nguồn có sẵn, tức có khả giải hiệu vấn đề điều kiện thời gian tài nguyên cho phép Tính phổ biến: Một giải thuật có tính phổ biến giải thuật giải lớp vấn đề tương tự Độc lập: Một giải thuật nên có thị độc lập với phần code lập trình c) Phân tích giải thuật: Hiệu giải thuật phân tích dựa góc độ: trước triển khai sau triển khai: Phân tích lý thuyết: Có thể coi phân tích dựa lý thuyết Hiệu giải thuật đánh giá việc giả sử tất yếu tố khác (ví dụ: tốc độ vi xử lý, …) số không ảnh hưởng tới triển khai giải thuật Phân tích tiệm cận: Việc phân tích giải thuật tiến hành sau tiến hành ngơn ngữ lập trình Sau chạy kiểm tra đo lường thông số liên quan hiệu giải thuật dựa thông số thời gian chạy, thời gian thực thi, lượng nhớ cần dùng, … d) Độ phức tạp giải thuật Độ phức tạp giải thuật hàm ước lượng (có thể khơng xác) số phép tính mà giải thuật cần thực (từ dễ dàng suy thời gian thực giải thuật) liệu đầu vào (Input) có kích thước n Trong đó, n số phần tử mảng trường hợp toán xếp tìm kiếm, độ lớn số toán kiểm tra số nguyên tố, … Giả sử X giải thuật n kích cỡ liệu đầu vào Thời gian lượng nhớ sử dụng giải thuật X hai nhân tố định hiệu giải thuật X: + Nhân tố thời gian (Time complexity): Thời gian đánh giá việc tính số phép tính (chẳng hạn phép so sánh thuật toán xếp) + Nhân tố nhớ (Space complexity): Lượng nhớ đánh giá việc tính lượng nhớ tối đa mà giải thuật cần sử dụng Giới thiệu kiến thức Cấu trúc liệu a) Cấu trúc liệu (Data structure) Cấu trúc liệu cách lưu trữ, tổ chức liệu có thứ tự, có hệ thống để liệu sử dụng cách hiệu Hai khái niệm tảng hình thành nên cấu trúc liệu: Interface: Mỗi cấu trúc liệu có Interface Interface biểu diễn tập hợp phép tính mà cấu trúc liệu hỗ trợ Một Interface cung cấp danh sách phép tính hỗ trợ, loại tham số mà chúng chấp nhận kiểu trả phép tính Implementation (có thể hiểu triển khai): Cung cấp biểu diễn nội cấu trúc liệu Implementation cung cấp phần định nghĩa giải thuật sử dụng phép tính cấu trúc liệu b) Đặc điểm Cấu trúc liệu Chính xác: Sự triển khai Cấu trúc liệu nên triển khai Interface cách xác Độ phức tạp thời gian (Time Complexity): Thời gian chạy thời gian thực thi phép tính cấu trúc liệu phải nhỏ Độ phức tạp nhớ (Space Complexity): Sự sử dụng nhớ phép tính cấu trúc liệu nên nhỏ c) Tại cấu trúc liệu cần thiết: Các vấn đề cần lưu ý: Tìm kiếm liệu: Giả sử có triệu hàng hóa lưu giữ vào kho hàng hóa Và giả sử có ứng dụng cần để tìm kiếm hàng hóa Thì thực tìm kiếm, ứng dụng phải tìm kiếm hàng hóa triệu hàng hóa Khi liệu tăng lên việc tìm kiếm trở lên chậm tốn Tốc độ vi xử lý: Mặc dù vi xử lý có tốc độ cao, nhiên có giới hạn lượng liệu lên tới hàng tỉ ghi tốc độ xử lý khơng cịn nhanh Đa yêu cầu: Khi hàng nghìn người dùng thực phép tính tìm kiếm Web Server cho dù Web Server có nhanh đến việc phải xử lý hàng nghìn phép tính lúc thực khó d) Độ phức tạp thời gian thực thi cấu trúc liệu giải thuật: Có trường hợp để so sánh thời gian thực thi cấu trúc liệu khác nhau: Trường hợp xấu (Worst Case): tình mà phép tính cấu trúc liệu tốn thời gian tối đa (thời gian dài nhất) Ví dụ với ba số 1, 2, xếp theo thứ tự giảm dần thời gian thực thi dài (và trường hợp xấu nhất); xếp theo thứ tự tăng dần thời gian thực thi ngắn (và trường hợp tốt nhất) Trường hợp trung bình (Average Case): miêu tả thời gian thực thi trung bình phép tính cấu trúc liệu Trường hợp tốt (Best Case): tình mà thời gian thực thi phép tính cấu trúc liệu Ví dụ e) Thuật ngữ Cấu trúc liệu Dữ liệu: Dữ liệu giá trị tập hợp giá trị Phần tử liệu: Phần tử liệu đơn vị đơn lẻ giá trị Các phần tử nhóm: Phần tử liệu mà chia thành phần tử gọi phần tử nhóm Các phần tử bản: Phần tử liệu mà bị chia nhỏ thành phần tử gọi phần tử Thuộc tính Thực thể: Một thực thể mà chứa vài thuộc tính đó, thuộc tính gán giá trị Tập hợp thực thể: Các thực thể mà có thuộc tính tương tự cấu thành tập hợp thực thể Trường: Trường đơn vị thông tin biểu diễn thuộc tính thực thể Bản ghi: Bản ghi tập hợp giá trị trường thực thể cho File: Là tập hợp ghi thực thể tập hợp thực thể cho 1.1.2 Một số toán giải thuật độ phức tạp thuật toán ● Đệ quy Python Đệ quy Python hay cịn gọi recursion python Nói tốn học đệ quy thuật tốn giải tốn cách gọi lại thuật tốn đó, thao tác thực liên tục gặp điều kiện dừng VD: Ta sử dụng đệ quy để xác định dãy Fibonacci, tìm ước số chung lớn nhất,… ● Khái niệm BigO Khái niệm Big O hoạc với tên gọi khác tiếng Việt “độ phức tạp thuật toán” thuật ngữ thường dùng để khoảng thời gian tiêu hao để chạy thuật tốn Các lập trình viên thường sử dụng Big O phương tiện để so sánh mức độ hiệu nhiều cách xử lý khác cho vấn đề ● Cách tính BigO + Gọi T độ phức tạp thuật tốn cần tìm + Tính biểu thức T cách cộng thời gian thực thi câu lệnh thuật toán + Xét số hạng có tốc độ tăng nhanh n tiến đến +∞ + Lược bỏ giá trị lược bỏ theo quy tắc + Giá trị số hạng cuối sót lại độ phức tạp thuật tốn cần tìm ● Một số độ phức tạp thuật tốn thường gặp + O(n): Độ phức tạp tuyến tính Xét hàm tính tổng số từ đến n sau: Với giá trị khác n số lần thực thi vịng lặp n lần Chính thời gian thực thi chương trình phụ thuộc vào giá trị đầu vào n Ta nói độ phức tạp chương trình O(n) (thực O(n+2)) + O(1): Độ phức tạp số Cũng tốn tính tổng số từ đến n Xét đoạn chương trình sau: Khơng giống hàm tính tổng trên, với đoạn chương trình với giá trị đầu vào chương trình thực thi câu lệnh return Do đó, ta nói độ phức tạp chương trình O(1) + O(n²): Thường gặp có vịng lặp lồng Xét hàm xếp đổi chỗ trực tiếp (interchange Sort) sau: Trong hàm này, i chạy từ đến n - Ứng với giá trị i vòng for chạy n - i - lần (j từ i + đến n - 1), số phép so sánh cần thực Σ(n - i - 1) (với i chạy từ đến n - 2) = (n - 1) + (n - 2) + (n - 3) + + + = (n - 1)*n/2 = n²/2 - n/2 Ta nói độ phức tạp thuật tốn O(n²) (thực O(n²/2 - n/2)) + O(logn): Hiểu đơn giản thuật tốn để tìm kiếm phần tử có giá trị x có mảng arr xếp tăng dần Để tìm giá trị đó, ý tưởng phân hoạch mảng làm đôi, xét phần tử giữa, phần tử lớn giá trị cần tìm xét tiếp nửa bên trái phần tử đó, ngược lại xét nửa bên phải, tiếp tục phân hoạch tìm phần tử có giá trị cần tìm (có thể khơng tìm thấy giá trị cần tìm khơng có mảng) Trong trường hợp xấu nhất, phải phân hoạch mảng phân hoạch phần tử (nếu khơng phải giá trị cần tìm trả - 1) Khi để đưa mảng có n phần tử phần tử ta cần thực logn (hiểu log số 2) lần phân hoạch Do ta nói thuật tốn có độ phức tạp O(logn) Ngồi cịn có số độ phức tạp thường gặp O(nlogn), O(n!), O(2^n), O(n³), Dưới biểu đồ thể độ hiệu độ phức tạp thường gặp 1.2 Giải thuật tham lam Giải thuật tham lam (tiếng Anh: Greedy algorithm) thuật toán giải tốn theo kiểu metaheuristic để tìm kiếm lựa chọn tối ưu địa phương bước với hy vọng tìm tối ưu tồn cục VD: Ở bước đến thành phố gần thành phố nhất", tốn phân nhóm trẻ, tốn xếp balo 1.1.3 thành phần giải thuật tham lam o Một tập hợp ứng viên (candidate), để từ tạo lời giải o Một hàm lựa chọn, để theo lựa chọn ứng viên tốt để bổ sung vào lời giải o Một hàm khả thi (feasibility), dùng để định ứng viên dùng để xây dựng lời giải o Một hàm mục tiêu, ấn định giá trị lời giải lời giải chưa hoàn chỉnh o Một hàm đánh giá, ta tìm lời giải hoàn chỉnh 1.1.4 thành phần định sử dụng thuật tốn Tham Lam: Tính chất lựa chọn tham lam Thuật toán tiến triển theo kiểu thực chọn lựa theo vòng lặp, lúc thu nhỏ tốn cho toán nhỏ Đấy khác biệt thuật toán giải thuật quy hoạch động Giải thuật quy hoạch động duyệt hết đảm bảo tìm thấy lời giải Tại bước thuật tốn, quy hoạch động đưa định dựa định bước trước, xét lại đường bước trước hướng tới lời giải Giải thuật tham lam định sớm thay đổi đường thuật tốn theo định đó, khơng xét lại định cũ Đối với số tốn, thuật tốn khơng xác Cấu trúc tối ưu Một tốn gọi "có cấu trúc tối ưu", lời giải tối ưu toán chứa lời giải tối ưu toán lớn 1.3 Giải thuật chia để trị 1.1.5 Giới thiệu giải thuật Ý tưởng phương pháp đơn giản dễ hiểu: Khi cần giải tốn, ta tiến hành chia tốn thành toán nhỏ Tiếp tục chia tốn nhỏ khơng thể chia thêm nữa, ta giải toán nhỏ cuối kết hợp giải pháp tất toán nhỏ để tìm giải pháp tốn ban đầu o Tiến trình 1: Chia nhỏ (Devide/Break) Chia tốn ban đầu thành toán Mỗi toán nên phần tốn ban đầu Nói chung, bước sử dụng phương pháp đệ qui để chia nhỏ tốn khơng thể chia thêm Khi đó, tốn gọi "atomic – nguyên tử", chúng biểu diễn phần tốn ban đầu o Tiến trình 2: Giải tốn (Conquer/Solve) Các tốn giải o Tiến trình 3: Kết hợp lời giải (Merge/Combine) Kết hợp chúng cách đệ qui để tìm giải pháp cho tốn ban đầu 1.1.6 Hạn chế Tồn hạn chế: + Làm để chia tách toán cách hợp lý thành tốn con, toán giải thuật tốn khác phức tạp + Việc kết hợp lời giải toán thực Một số giải thuật xây dựng dựa phương pháp chia để trị: + Giải thuật xếp trộn (Merge Sort) + Giải thuật xếp nhanh (Quick Sort) + Giải thuật tìm kiếm nhị phân (Binary Search) … 1.1.7 Tìm kiếm tuyến tính (Linear search) Linear Search giải thuật tìm kiếm Trong kiểu tìm kiếm này, hoạt động tìm kiếm liên tiếp diễn qua tất phần tử Mỗi phần tử kiểm tra tìm thấy kết nối phần tử cụ thể trả về; khơng tìm thấy trình tìm kiếm tiếp tục diễn tìm kiếm hết liệu Các bước cho giải thuật tìm kiếm tuyến tính: Bước 1: Thiết lập i thành Bước 2: Nếu i > n chuyển tới bước Bước 3: Nếu A[i] = x chuyển tới bước Bước 4: Thiết lập i thành i + Bước 5: Tới bước Bước 6: In phần tử x tìm thấy mục i tới bước Bước 7: In phần tử khơng tìm thấy Bước 8: Thốt 1.1.8 Tìm kiếm nhị phân (Binary search) Binary Search tìm kiếm phần tử cụ thể cách so sánh phần tử vị trí tập liệu Nếu tìm thấy kết nối mục phần tử trả Nếu phần tử cần tìm lớn giá trị phần tử phần tử cần tìm tìm mảng nằm bên phải phần tử giữa; khơng tìm mảng nằm bên trái phần tử Tiến trình tiếp tục mảng tìm hết phần tử mảng Bài tốn ví dụ: Trị chơi màu khác nhau, Phép nhân đa thức, Giải thuật định lý thợ Ý tưởng thuật tốn tìm kiếm nhị phân Thuật tốn u cầu mảng xếp Vì đầu vào thuật toán mảng xếp Các bước thực tìm kiếm nhị phân mảng: So sánh x với phần tử Nếu x khớp với phần tử giữa, trả số Nếu x lớn phần tử giữa, x nằm nửa phân đoạn bên phải sau phần tử mid Vì vậy, tìm kiếm phải mảng Nếu x nhỏ phần tử tiếp tục tìm nửa bên trái Lặp lại đến tìm x trả null x không nằm mảng Cài đặt đệ quy Cài đặt vịng lặp Giải thích minh họa: + Mỗi bucket danh sách liên kết + John Smith Sandre Dee có giá trị hàm hash 152, nên bucket 152, ta có danh sách liên kết chứa phần tử ● Open addressing Tư tưởng Open Addressing là, xảy Hash collision, ta lưu vào vị trí bảng băm Ví dụ: • Trong hình minh họa: + John Smith Sandra Dee có giá trị Hash 152 Vì ta lưu lưu John Smith vào bucket 152, nên ta buộc phải lưu Sandra Dee vào bucket 153 + Ted Baker có giá trị Hash 153, lúc bucket 153 lưu thông tin Sandra Dee, nên ta phải lưu giá trị Ted Baker vào bucket 154 • Chú ý: + Để cài đặt cách này, Load factor phải nhỏ + Khi tìm kiếm phần tử, ta phải kiểm tra tất bucket bucket giá trị Hash, đến bucket trống (ví dụ ta tìm Sandra Dee phải tìm bucket 152, 153; tìm Ted Baker phải tìm bucket 152, 153, 154 Nếu ta tìm người khác có giá trị Hash 152, phải tìm bucket 152, 153, 154 155 (chỉ bucket 155 trống, ta chắn người khơng có Hash table) 1.12 Đồ thị - Các thao tác 3.1.15 Giới thiệu đồ thị Trong toán học tin học, đồ thị đối tượng nghiên cứu lý thuyết đồ thị Một cách khơng thức, đồ thị tập đối tượng gọi đỉnh nối với cạnh Thông thường, đồ thị vẽ dạng tập điểm (đỉnh, nút) nối với đoạn thẳng (cạnh) Tùy theo ứng dụng mà số cạnh có hướng Một cách khơng thức, đồ thị tập đối tượng gọi đỉnh nối với cạnh Một đồ thị kí hiệu là: G = (V, E) Trong đó: + V tập đỉnh đồ thị Đỉnh biểu diễn đối tượng đồ thị, thường đánh dấu số kí hiệu chữ in thường u,v,… + E tập cạnh đồ thị Cạnh nối đỉnh x với đỉnh y tập gồm hai phần tử x, y thường vẽ dạng đoạn thẳng nối hai đỉnh 3.1.16 Cấu trúc liệu đồ thị (Graph) Đỉnh (Vertex): Mỗi nút hình biểu diễn đỉnh Trong ví dụ đây, hình trịn biểu diễn đỉnh Do đó, điểm từ A tới G đỉnh Chúng ta biểu diễn đỉnh sử dụng mảng, đỉnh A nhận diện mục 0, điểm B mục 1, … Cạnh (Edge): Cạnh biểu diễn đường nối hai đỉnh Trong hình dưới, đường nối A B, B C, … cạnh Chúng ta sử dụng mảng hai chiều để biểu diễn cạnh Trong ví dụ dưới, AB biểu diễn hàng 0; BC hàng 1, cột 2, … Kề nhau: Hai đỉnh kề chúng kết nối với thơng qua cạnh Trong hình dưới, B kề với A; C kề với B, … Đường: Đường biểu diễn dãy cạnh hai đỉnh Trong hình dưới, ABCD biểu diễn đường từ A tới D 3.1.17 Các thao tác cấu trúc liệu đồ thị Thêm đỉnh: Thêm đỉnh vào đồ thị Thêm cạnh: Thêm cạnh vào hai đỉnh đồ thị Hiển thị đỉnh: Hiển thị đỉnh đồ thị 3.1.18 Biểu diễn kết nối đồ thị Có nhiều cách để biểu diễn đồ thị máy tính, tùy thuộc vào tính chất đồ thị thuật tốn áp dụng với đồ thị… Ta lưu kèm theo thông tin trọng số, giá trị phù hợp với cạnh Ma trận kề: Tạo ma trận A kích thước n*n n số đỉnh đồ thị Ta gán a[u][v] = có cạnh cạnh nối hai đỉnh u, v Nếu đồ thị đa đồ thị, ta gán a[u][v] = số cạnh nối u v Định nghĩa gán tùy theo lập trình viên hiểu vơ hướng hay có hướng, đơn đồ thị hay đa đồ thị + Ưu điểm: Để kiểm tra hai đỉnh u, v có kề khơng, ta cần kiểm tra độ phức tạp O(1) + Nhược điểm: Dù đồ thị có nhiều cạnh hay cạnh phải n*n ô nhớ để lưu Để duyệt tất đỉnh kề với u, ta phải duyệt tất đỉnh v ∊ V cho dù đỉnh u kề với khơng kề với đỉnh khác ⇨ Biểu diễn ma trận kề thường dùng đồ thị có đỉnh, đồ thị dày, nhiều cạnh, thuật toán để thao tác đồ thị yêu cầu Danh sách cạnh: Với đồ thị G=(V,E)G=(V,E) có n đỉnh, m cạnh, ta liệt kê tất cạnh đồ thị danh sách tương ứng, phần tử mảng tương ứng cặp (u,v) cạnh thuộc E, tùy theo người lập trình định nghĩa có hướng hay vô hướng + Ưu điểm: Với đồ thị thưa, ta cần m (số lượng cạnh) ô nhớ để lưu đồ thị + Nhược điểm: Khi cần kiểm tra hai đỉnh u,v có kề hay khơng, ta kiểm tra nhanh //( O(1) //) cách lưu ma trận kề, tùy theo cách lưu danh sách cạnh mà ta kiểm tra //( O(logn) //) Danh sách kề: Với đỉnh đồ thị, ta lưu danh sách đỉnh kề với đỉnh + Ưu điểm: Với phương pháp này, việc duyệt tất đỉnh kề với đỉnh u vô dễ dàng + Nhược điểm: Khi cần kiểm tra hai đỉnh u,v có kề hay không, ta kiểm tra nhanh O(1)O(1) cách lưu ma trận kề, tùy theo cách lưu danh sách cạnh mà ta kiểm tra O(logn)O(logn) 3.1.19 Đồ thị vơ hướng đồ thị có hướng Đồ thị vô hướng đồ thị mà cạnh khơng có hướng Mỗi cạnh ln mối quan hệ hai chiều, cạnh duyệt qua theo hai hướng Đồ thị có hướng trường hợp ngược lại đồ thị vô hướng, với cạnh có hướng, xuất phát từ kết thúc đỉnh, thông thường ký hiệu dấu mũi tên Đồ thị vô hướng Đồ thị vô hướng đồ thị G cặp khơng có thứ tự (unordered pair) G:=(V, E), + V, tập đỉnh nút + E, tập cặp không thứ tự chứa đỉnh phân biệt, gọi cạnh Hai đỉnh thuộc cạnh gọi đỉnh đầu cuối cạnh Đồ thị có hướng Đồ thị có hướng G cặp có thứ tự G = (V, A), + V, tập đỉnh nút + A, tập cặp có thứ tự chứa đỉnh, gọi cạnh có hướng cung Một cạnh e = (x, y) coi có hướng từ x tới y; x gọi điểm đầu/gốc y gọi điểm cuối/ngọn cạnh Đồ thị liên thông Một đồ thị gọi liên thơng (connected) có đường cặp đỉnh phân biệt đồ thị Ngược lại, đồ thị gọi không liên thơng (disconnected) Tham khảo: https://www.tutorialspoint.com/python_data_structure/python_graphs.htm Thuật tốn kinh điển 1.13 Bài tốn tuyến đường chặng 4.1.1 Giải thuật tìm kiếm theo chiều rộng (BFS) Giải thuật tìm kiếm theo chiều rộng (Breadth First Search – viết tắt BFS) duyệt qua đồ thị theo chiều rộng sử dụng hàng đợi (queue) để ghi nhớ đỉnh liền kề để bắt đầu việc tìm kiếm khơng gặp đỉnh liền kề vòng lặp Qui tắc 1: Duyệt tiếp tới đỉnh liền kề mà chưa duyệt Đánh dấu đỉnh mà duyệt Hiển thị đỉnh đẩy vào hàng đợi (queue)… Qui tắc 2: Nếu khơng tìm thấy đỉnh liền kề, xóa đỉnh hàng đợi Qui tắc 3: Lặp lại Qui tắc hàng đợi trống Ví dụ duyệt BFS: Bướ Duyệt Miêu tả c Khởi tạo hàng đợi (queue) Chúng ta bắt đầu duyệt đỉnh S (đỉnh bắt đầu) đánh dấu đỉnh duyệt Sau tìm đỉnh liền kề với Smà chưa duyệt Trong ví dụ có đỉnh, theo thứ tự chữ chọn đỉnh A đánh dấu duyệt xếp A vào hàng đợi Tiếp tục duyệt đỉnh liền kề với S B Đánh dấu duyệt xếp đỉnh vào hàng đợi Tiếp tục duyệt đỉnh liền kề với S C Đánh dấu duyệt xếp đỉnh vào hàng đợi Bây đỉnh S không đỉnh liền kề mà chưa duyệt Bây rút A từ hàng đợi Từ đỉnh A có đỉnh liền kề D đỉnh chưa duyệt Đánh dấu đỉnh D duyệt xếp vào hàng đợi 4.1.2 Giải thuật tìm kiếm theo chiều sâu (DFS) Giải thuật tìm kiếm theo chiều sâu (Depth First Search – viết tắt DFS), cịn gọi giải thuật tìm kiếm ưu tiên chiều sâu, giải thuật duyệt tìm kiếm một đồ thị sử dụng stack (ngăn xếp) để ghi nhớ đỉnh liền kề để bắt đầu việc tìm kiếm khơng gặp đỉnh liền kề vòng lặp Giải thuật tiếp tục gặp đỉnh cần tìm tới nút khơng có Khi giải thuật quay lui đỉnh vừa tìm kiếm bước trước Qui tắc 1: Duyệt tiếp tới đỉnh liền kề mà chưa duyệt Đánh dấu đỉnh mà duyệt Hiển thị đỉnh đẩy vào ngăn xếp (stack) Qui tắc 2: Nếu không tìm thấy đỉnh liền kề, lấy đỉnh từ ngăn xếp (thao tác pop up) (Giải thuật lấy tất đỉnh từ ngăn xếp mà khơng có đỉnh liền kề nào) Qui tắc 3: Lặp lại qui tắc qui tắc ngăn xếp trống Ví dụ duyệt BFS: Bước Duyệt Miêu tả Khởi tạo ngăn xếp (stack) Đánh dấu đỉnh S duyệt đặt đỉnh vào ngăn xếp Tìm kiếm đỉnh liền kề mà chưa duyệt từ đỉnh S Chúng ta có đỉnh lấy đỉnh số chúng Ví dụ, lấy đỉnh A theo thứ tự chữ Đánh dấu đỉnh A duyệt đặt vào ngăn xếp Tìm kiếm đỉnh liền kề với đỉnh A Cả S D hai đỉnh liền kề A quan tâm đỉnh chưa duyệt Duyệt đỉnh D, đánh dấu đỉnh duyệt đặt vào ngăn xếp Ở đây, có B C hai đỉnh kề với D hai chưa duyệt Chúng ta chọn theo thứ tự chữ lần Chọn B, đánh dấu duyệt đặt vào ngăn xếp Ở B khơng có đỉnh liền kề mà chưa duyệt Vì lấy B khỏi ngăn xếp Kiểm tra phần tử ngăn xếp để trở nút duyệt trước kiểm tra xem đỉnh có đỉnh liền kề mà chưa duyệt hay khơng Ở đây, tìm thấy đỉnh D nằm ngăn xếp Chỉ có đỉnh liền kề với D mà chưa duyệt, đỉnh C Chúng ta duyệt C, đánh dấu duyệt đặt vào ngăn xếp 4.1.3 So sánh BFS DFS BFS tốn nhớ lưu lại tất cấp Tuy nhiên , tùy vào toán cụ thể mà BFS hay DFS “chạy” nhanh Ví dụ: Ta có gia phả qua nhiều hệ gia tộc lớn Nếu người gia phả muốn tìm kiếm người cịn sống ta thấy DFS thường hoạt động nhanh hơn.Tuy nhiên, người muốn tìm người cách lâu BFS thường nhanh DFS ⇨ Cái tốt cịn tùy thuộc vào liệu bạn tìm kiếm 1.14 Bài toán tuyến đường ngắn 4.1.4 Tổng quan tốn tìm đường ngắn Trong lý thuyết đồ thị, toán đường ngắn nguồn đơn tốn tìm đường hai đỉnh cho tổng trọng số cạnh tạo nên đường nhỏ Định nghĩa cách hình thức, cho trước đồ thị có trọng số (nghĩa tập đỉnh V, tập cạnh E, hàm số có giá trị thực f : E → R), cho trước đỉnh v thuộc V, tìm đường P từ v tới đỉnh v' thuộc V cho nhỏ tất đường nối từ v tới v' Bài toán đường ngắn cặp đỉnh tốn tương tự, ta phải tìm đường ngắn cho cặp đỉnh v v' 4.1.5 Thuật toán Dijkstra Thuật toán Dijkstra, thuật toán giải toán đường ngắn nguồn đơn đồ thị có hướng khơng có cạnh mang trọng số khơng âm Thuật tốn thường sử dụng định tuyến với chương trình thuật tốn đồ thị hay cơng nghệ Hệ thống định vị toàn cầu (GPS) Cách hoạt động Thuật toán Dijkstra Bước 1: Chọn S = {} tập soure_node bao gồm current_node passed_node Với current_node node xét đến, passed_node node xét current_node node đích tốn tìm đường ngắn Bước 2: Khởi tạo giải thuật với current_node node đích cost(N) giá trị đường ngắn từ N đến node đích Bước 3: Xét node kề N với current_node Gọi d(current_node,N) khoảng cách node kề N current_node Với p = d(current_node,N) + cost (current_node) Nếu p < cost(N) cost(N) = p Nếu khơng cost(N) giữ nguyên giá trị Bước 4: Sau xét hết node kề N, đánh dấu current_node thành passed_node Bước 5: Tìm current_node với điều kiện: khơng phải passed_node cost(current_node) nhỏ Bước 6: Nếu tập S = {} chứa đủ node đồ thị dừng thuật tốn Nếu khơng quay trở lại Bước 4.1.6 Thuật toán Bellman – Ford Thuật toán Bellman-Ford thuật tốn tính đường ngắn nguồn đơn đồ thị có hướng có trọng số (trong số cung có trọng số âm) Thuật toán Dijkstra giải toán nhiên Dijkstra có thời gian chạy nhanh hơn, đơn giản đòi hỏi trọng số cung phải có giá trị khơng âm Bước 1: Bắt đầu với đồ thị có trọng số Bước 2: Chọn đỉnh bắt đầu nhập trọng số inf cho cạnh đồ thị Bước 3: Thăm cạnh bỏ qua cạnh khơng xác Bước 4: Ta phải lặp lại V lần (số đỉnh) trường hợp xấu nhất, đường đỉnh cần điều chỉnh lại V lần Bước 5: Để ý đường qua đỉnh điều chỉnh độ dài Bước 6: Sauk hi cạnh có số đo, ta kiểm tra có chu kỳ âm 4.1.7 So sánh Bellman Ford với Dijkstra Dijkstra nhìn vào điểm hàng xóm trực tiếp đỉnh xét, Bellman qua cạnh qua lần lặp lại 1.15 Thuật toán KMP (Knuth – Morris – Pratt Algorithm) 4.1.8 Rabin – Karp Tư tưởng phương pháp sử dụng phương pháp băm (hashing) Tức xâu gán với giá trị hàm băm (hash function), ví dụ xâu “hello” gán với giá trị chẳng hạn, hai xâu gọi giá trị băm Như thay việc phải đối sánh xâu y với mẫu x, ta cần so sánh giá trị hàm băm chúng đưa kết luận 4.1.9 Knuth – Morris – Pratt Thuật toán KMP xây dựng dựa vào quan sát xâu chung S T đưa thông tin S có khớp với vị trí sau T hay khơng Bởi xâu chung đồng nghĩa với phần T khớp với phần S, nên việc khởi tạo trước số thông tin với xâu S, ta thu kết luận T (nhờ xâu chung) mà không cần quay ngược so sánh lại ký tự khớp.Cụ thể hơn, ta muốn tính tốn trước cách xâu S tự khớp với Nhờ thuật tốn khơng quay nhìn lại duyệt qua T lần Cùng với trình tiền xử lí tuyến tính O(|T|) (với |T| độ dài xâu T), thuật tốn có thời gian chạy tuyến tính 4.1.10 So sánh Robin Karp KMP Sự khác biệt quan trọng độ tin cậy thuật toán KMP đảm bảo độ tin cậy 100% với kết đưa ra, Rabin Karp không đảm bảo điều xảy xung đột q trình tra cứu bảng băm Ngày nay, có nhiều hàm băm tốt Rabin Karp đem đến độ tin cậy tiệm cận 100% Về mặt triển khai, Rabin Karp dễ thực thi tốn nhớ chút