4.4.1 Khái niệm tập mờ
Lý thuyết tập mờ (fuzzy set), do giáo sƣ L.Zadeh khởi xƣớng (1965), là sự tổng quát hóa của lý thuyết tập hợp truyền thống (đƣợc gọi là tập rõ (crisp set)). Khái niệm tập mờ cho phép đƣa ra phƣơng pháp toán học để biểu diễn những tri thức khó định lƣợng (nhƣ: cao, thấp; già, trẻ; …) hoặc những tri thức mà ngƣời diễn
86
đạt nó trong ngôn ngữ tự nhiên không có nhu cầu cung cấp độ chính xác định lƣợng cao (nhƣ “cách đây một năm” là một đặc trƣng mang sắc thái gần đúng) hay không có khả năng cung cấp độ chính xác cao hơn (chẳng hạn nhƣ: “gần đây”); hoặc những tri thức thu đƣợc từ thực nghiệm nên thực ra chỉ là gần đúng do có sai số của phép đo (nhƣ khi cân một ô tô cho kết quả: “nặng khoảng 5 tấn”). Trong lý thuyết tập mờ, không có sự chuyển đột ngột từ một lớp này sang lớp khác mà cho phép biểu diễn khả năng có những phần tử không thuộc hoàn toàn hay thuộc một phần vào một lớp nào đó. Khi một phần tử có đặc trƣng càng gần với đặc trƣng điển hình của một lớp thì sự thuộc vào lớp đó càng mạnh, điều này sẽ đƣợc thể hiện thông qua “độ thuộc” của phần tử vào lớp.
Cho đến nay, ý tƣởng về tập mờ đã đƣợc phát triển rộng rãi trong nhiều lĩnh vực khoa học, cả về lý thuyết và ứng dụng, trong đó lý thuyết ngôn ngữ hình thức và otomat.
Định nghĩa 4.1. Cho tập hợp X. Một tập con mờ (gọi tắt là tập mờ) A trên tập rõ cơ sở X (gọi là tập nền) được biểu thị bởi hàm µA: X [0, 1]. Ta gọi µA là hàm thuộc và µA(x) là độ thuộc của x vào tập mờ A, với mỗi x là một phần tử của tập nền X.
Trong thực tế, tùy từng trƣờng hợp, ngƣời ta có thể sử dụng tập mờ (mở rộng) với các giá trị mờ là số thực hoặc tổng quát hơn, là phần tử của một dàn (chẳng hạn nhƣ giá trị nhãn ngữ nghĩa: cao, rất cao, …), …
Ví dụ 4.1. Cho tập các xâu kí tự X = { s1, s2, s3} và một xâu mẫu P.
Trong lý thuyết tập hợp truyền thống, tập A biểu thị tập các xâu kí tự của X giống (hay bằng) mẫu P là một tập rõ. Nhƣng khi cần xác định tập A, biểu thị tập các xâu kí tự của X gần giống (hay tƣơng tự) với mẫu P thì cách biểu diễn dƣới dạng tập mờ là hợp lý: A có thể xem là một tập con mờ trên tập nền X với hàm thuộc µA. Chẳng hạn, A = {s1/0; s2/1; s3/0,8}, có nghĩa là µA(s1) = 0, µA(s2) = 1, µA(s3) = 0,8 cho biết mức độ gần giống của mỗi xâu trong X so với mẫu P.
87
4.4.2 Tiếp cận mờ cho bài toán tìm kiếm
Bài toán đối sánh mẫu chính xác đƣợc phát biểu nhƣ sau: Cho xâu mẫu P độ dài m (P = P1P2…Pm) và xâu đích S độ dài n (S1S2…Sn) trên cùng bảng chữ Ạ Tìm tất cả các vị trí xuất hiện của mẫu P trong xâu S.
Từ việc giải bài toán trên ta có thể dễ dàng thống kê đƣợc tần suất xuất hiện mẫu P trong một văn bản.
Bài toán đặt ra ở đây là tìm kiếm chính xác mẫu, nhiều lần lặp mẫụ Độ mờ là một giá trị nguyên thuộc [0, …, m] cho biết độ dài của khúc đầu dài nhất của mẫu P đã xuất hiện trên S. Đây cũng có thể xem nhƣ một mô hình “lỗi”, rất phù hợp với tìm kiếm xấp xỉ khúc đầu trong các từ điển lớn.
Định nghĩa 4.2. Cho xâu mẫu P độ dài m và xâu đích S độ dài n. Độ mờ xuất hiện mẫu P trên S tại vị trí j là giá trị nguyên λ ≥ 0 thỏa mãn:
+ Nếu Sj ≠ P1 thì λ = 0
+ Ngược lại, λ là số lớn nhất sao cho P1P2… = Sj-λ+1Sj-λ+2…Sj
Gọi AP là tập các kí tự có trong mẫu P, # là một kí tự đại diện cho các kí tự thuộc A nhƣng không xuất hiện trong P (thuộc A\ AP).
Độ mờ xuất hiện mẫu P đƣợc xác định thông qua hàm TFuzz nhƣ sau: TFuzz: {0, 1, …, m} × (AP #) {0, 1,…, m}
(λ, a) λ‟ = TFuzz(λ, a)
Trong đó λ gọi là giá trị độ mờ cũ, λ‟ là giá trị độ mờ mới khi gặp kí tự ạ
4.4.3 Mô hình Otomat mờ so mẫu
Do ý nghĩa của độ mờ là độ dài khúc đầu dài nhất của mẫu P đã xuất hiện trên S nên otomat sẽ có tập trạng thái là tập số nguyên {0, 1, …, m}. Hoạt động của otomat mờ so mẫu sẽ nhƣ sau:
- Khởi đầu con trỏ trên S là j = 0. Tại đó chƣa xuất hiện khúc đầu nào của mẫu nên trạng thái khởi đầu của otomat là q0 = 0.
88
- Duyệt S, mỗi lần một kí tự, bắt đầu từ S1. Giả sử trạng thái của otomat là q thì khi đọc đƣợc kí tự Sj, trạng thái mới (ứng với vị trí j trên S) sẽ là q‟ = δ(q, Sj) (δ là hàm chuyển của otomat).
- Tại vị trí j trên S, nếu trạng thái của otomat là q, có nghĩa khúc đầu dài nhất xuất hiện trên S của P có độ dài q. Nếu q = m, báo hiệu một lần xuất hiện mẫu, bắt đầu từ vị trí j – m + 1.
Mô hình otomat mờ cần đƣợc xây dựng một cách thích hợp để đáp ứng đƣợc yêu cầu sánh mẫu nhƣ trên.
Định nghĩa 4.3. Otomat mờ so mẫu là bộ ĂP) = (A, Q, q0, δ, F), trong đó: + Bảng chữ vào A = Ap {#},
+ Tập trạng thái Q = {0, 1, …, m} + Trạng thái khởi đầu q0 = 0, + Trạng thái kết thúc F = m, + Hàm chuyển δ: Q × A Q
δ(q, a) = TFuzz(q, a)
Cách xác định hàm TFuzz:
Giả sử độ mờ xuất hiện mẫu P tại vị trí j trên S là λ. Khi đó độ mờ λ’ tại vị trí j+1 được xác định bởi λ’ = TFuzz(λ, Sj+1), với TFuzz được xác định như sau:
+ TFuzz(0,x) = {
89 + TFuzz(i,x) = {
Việc xác định j dựa vào bảng next (nhƣ trong thuật toán KMP) và một vòng lặp. 4.4.4 Thuật toán KMP mờ Khi cài đặt thuật toán cần lƣu ý lựa chọn cấu trúc dữ liệu phù hợp để có thể truy cập nhanh chóng trong bảng TFuzz. Gọi A[0.. k] là mảng lƣu trữ giữ bảng chữ A của otomat, trong đó k là số kí tự phân biệt trong mẫu P. Mảng đƣợc sắp theo chiều tăng của các kí tự và A[k] = ‟#‟. Để thuận tiện khi truy nhập đến các chữ cái trong A, có thể sử dụng mảng index xác định vị trí của các chữ trong bảng. Index[c] = { [ ]
[ ] [ ] [ ]
TFuzz là mảng [0..m, 0..k], trong đó TFuzz[i,j] là độ mờ mới khi độ mờ i gặp kí tự x có index[x] = j.
Chi tiết thuật toán tạo bảng TFuzz và tìm kiếm dựa vào bảng TFuzz nhƣ sau:
Thuật toán 4.5 Tạo lập TFuzz
Procedure initTFuzz(); Begin For i := 0 to m do TFuzz[i,k] := 0; For i := 0 to k do TFuzz[0,j] := 0; TFuzz[0, index[P[1]] := 1; For i := 1 to m do
90 For t := 0 to k – 1 do
Begin
If i = m then j := next[i + 1] Else j := i + 1;
While (j > 0) and (P[j] ≠ A[t]) do j := next[j]; TFuzz[i, index[A[t]] := j;
End; End;
Thuật toán 4.6 Tìm kiếm mẫu dựa vào bảng TFuzz
Procedure FKMP(); Begin
j := 1; counter := 0; fuz[0] := 0; For j := 1 to n do
Begin
Fuz[j] := TFuzz[fuz[j – 1 ], index[S[j]]; If fuz[j] = m then Begin counter := counter + 1; Ghi nhận vị trí j – m + 1; End; End; {for} Ghi nhận counter; End;
Độ phức tạp của thuật toán
91
Ví dụ 4.2. Với mẫu P = aababaab, A = {a, b, #}, Ap= {a, b}, bảng TFuzz đƣợc tính toán dựa trên mảng next cho kết quả nhƣ sau:
Q A A b # 0 1 0 0 1 2 0 0 2 0 3 0 3 4 0 0 4 2 5 0 5 6 0 0 6 7 0 0 7 2 8 0 8 4 0 0
Cho xâu đích S = aabaababaababaabab. Gọi j là con trỏ trên xâu S, là độ mờ xuất hiện mẫu P tại vị trí j trên S. Quá trình so mẫu P trên dòng dữ liệu S diễn ra nhƣ sau: J 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 S A A B A A B A B a A b a b A A b a b 1 2 3 4 2 3 4 5 6 7 8 4 5 6 7 8 4 5 Ghi nhận ghi nhận 11-8+1=4 16-8+1=9 Nhƣ vậy, mẫu P xuất hiện trong xâu S hai lần, bắt đầu tại các vị trí 4 và 9.
92
So sánh đánh giá các thuật toán đã tìm hiểu:
Vậy so với thuật toán KMP thì thuật toán KMP mờ tốt và hiệu quả hơn vì thuật toán KMP cải tiến từ thuật toán KMP kết hợp với otomat mờ nên sau khi tính bảng next, tính toán bảng TFuzz thì không còn hình ảnh dịch chuyển mẫụ
Xét sau khi tiền xử lý mẫu thì độ phức tạp của thuật toán KMP là O(m+n) và thuật toán KMP mờ là O(n).
4.5 Ứng dụng thuật toán tìm kiếm xâu
Trong cuộc sống hiện nay, việc lƣu giữ thông tin của các mối quan hệ là rất cần thiết. Với sự phát triển lớn mạnh của công nghệ di động, mọi thông tin có thể đƣợc lƣu trữ trên các thiết bị nhƣ điện thoại, máy tính bảng cũng nhƣ máy tính.
Khi lƣợng thông tin lƣu trữ của chúng ta quá lớn, chúng ta không thể nhớ một cách chính xác thông tin khi tìm kiếm. Vì vậy, ngày nay việc tìm kiếm thông tin gần đúng là một nhu cầu không thể thiếụ
Hiện nay, đã có một số công cụ tìm kiếm rất hữu ích trong cuộc sống nhƣ : Google, Yahoo Search, Các phần mềm search danh bạ điện thoại,…
Trong nội dung của luận văn này, tôi đã xây dựng một phần mềm sử dụng thuật toán tìm kiếm KMP trong bài toán mô phỏng tìm kiếm danh bạ điện thoạị
93
4.5.1. Cài đặt ứng dụng
4.5.1.1. Giao diện sử dụng
Hình 4.5. Giao diện sử dụng của phần mềm
- Danh bạ đƣợc hiển thị khi khởi động chƣơng trình
- Tƣơng ứng với một liên lạc bao gồm các thông tin: Tên, Địa chỉ email, Số điện thoại
- Thống kê tổng số lƣợng liên lạc có trong danh bạ
- Chức năng tìm kiếm thông tin: Khi nhập nội dung tìm kiếm vào ô search.. kết quả tìm kiếm sẽ hiển thị. Ngoài ra trên vùng thông tin chi tiết có hiển thị cả kết quả tìm kiếm có bao nhiêu kết quả đƣợc tìm thấỵ
- Ở phần nội dung tìm kiếm: có thể nhập tìm kiếm theo Tên, theo địa chỉ email và tìm kiếm theo số điện thoạị
94
4.5.1.2. Cài đặt chương trình
- Ứng dụng đƣợc phát triển trên ngôn ngữ C# và sử dụng tool development Visual studio 2012
- Các lớp cơ bản đƣợc cài đặt trong chƣơng trình :
+ Cns.cs: Lớp Constant, khai báo các giá trị sử dụng trong source codẹ + User.cs: Lớp chứa thông tin về liên lạc: Tên, Email, Phone
+ KMP.cs: Lớp cài đặt thuật toán tìm kiếm Knuth Morris Pratt
+ frmMain.cs: Lớp cài đặt các thao tác trên form và gọi đến xử lý tìm kiếm ở
lớp KMP.
- Mã source code của 2 lớp xử lý chính trong chƣơng trình ứng dụng + KMP.cs:
///<summary>
/// Xử lý tìm kiếm KMP (Hàm public ra ngoài )
///</summary>
///<param name="pattern">Nội dung của chuỗi tìm kiếm</param> ///<param name="targetString">Chuỗi nguồn để tìm kiếm</param>
///<returns> Mảng trả về vị trí đầu tiên tìm thấy trong chuỗi nguồn</returns> publicstatic ArrayList Knuth_Morris_Pratt(string pattern, string targetString) {
return Knuth_Morris_Pratt_Detail(pattern, targetString); }
///<summary>
/// Xử lý tìm kiếm KMP ( Hàm private trong class )
///</summary>
///<param name="pattern">Nội dung của chuỗi tìm kiếm</param> ///<param name="targetString">Chuỗi nguồn để tìm kiếm</param>
95
privatestaticArrayList Knuth_Morris_Pratt_Detail(string pattern, string
targetString) { ArrayList result; char[] charArray; char[] patternArray; charArray = targetString.ToLower().ToCharArray(); patternArray = pattern.ToLower().ToCharArray(); result = new ArrayList();
// Gán giá trị index của ký tự đầu tiên trong chuỗi search
int k = 0;
for (int i = 0; i < charArraỵLength; i++) {
// Trƣờng hợp ký tự trong chuỗi search trùng với ký tự nguồn
if (charArray[i] == patternArray[k]) {
// Tăng giá trị cho biến index lên 1
k++; } else
{ // Reset lại giá trị cho biến k.
k = 0; }
// Kết thúc quá trình tìm kiếm. Nếu k = độ dài của chuỗi tìm kiếm
if (k == patternArraỵLength) {
96
// Ađ giá trị index vào mảng kết quả.
result.Ađ(i - (patternArraỵLength - 1)); // Set lại giá trị cho biến index.
k = 0; } } return result; } + frmMain.cs : ///<summary> /// Searching ///</summary> ///<param name="sender"></param> ///<param name="e"></param>
privatevoid textBox1_TextChanged(object sender, EventArgs e) { ExactlySearch(); searchKey = textBox1.Text; } ///<summary> /// Xử lý tìm kiếm ///</summary>
privatevoid ExactlySearch() {
ArrayList arrResult;
dtvContact = _userDataTablẹDefaultView; dtvContact.Sort = Cns.Sort_Option;
97
dgrContactInfọDataSource = dtvContact.ToTable(); label1.Text = string.Empty;
_userDataTableSearch = newDataTable();
_userDataTableSearch.Columns.Ađ(Cns.Column_Name); string strSearchkey = string.Empty;
int intCountResult = 0;
strSearchkey += textBox1.Text; try
{
if (!string.IsNullOrEmpty(strSearchkey))
{ for (int i = 1; i < dgrContactInfọRowCount; i++) {
string strTargetSearch = dgrContactInfọRows[i - 1].Cells[Cns.Column_Name].ValuẹToString(); arrResult = KMP.Knuth_Morris_Pratt(strSearchkey, strTargetSearch); if (arrResult.Count > 0) { _userDataTableSearch.Rows.Ađ(dgrContactInfọRows[i - 1].Cells[Cns.Column_Name].ValuẹToString()); intCountResult++; } } label1.Text = Cns.Message_SearchResult.Replace("{1}", intCountResult.ToString()).Replace("{2}", dgrContactInfọRows.Count.ToString());
98
dgrContactInfọDataSource = _userDataTableSearch; }
}
catch (Exception ex)
{ MessageBox.Show(Cns.Message_PopUp, ex.Message); }
}
4.5.2. Kết quả tìm kiếm
- Trƣờng hợp tìm kiếm theo tên: Nhập giá trị tìm kiếm là “Anh”. Kết quả tìm kiếm hiển thị nhƣ Hình 4.6.
99
- Trƣờng hợp tìm kiếm theo cả tên và email : “Vân”. Kết quả tìm kiếm hiển thị nhƣ Hình 4.7.
100
- Trƣờng hợp tìm kiếm theo số điện thoại : “0912”. Kết quả tìm kiếm hiển thị nhƣ Hình 4.8.
101
KẾT LUẬN
Kết quả đạt đƣợc của luận văn
Nghiên cứu các cấu trúc dữ liệu và giải thuật cho bài toán tìm kiếm và cài đặt các chƣơng trình thử nghiệm bao gồm:
Các giải thuật tìm kiếm cơ bản: tìm kiếm tuyến tính, tìm kiếm nhị phân, tìm kiếm thông tin trên bảng, tìm kiếm theo phƣơng pháp băm, tìm kiếm xâụ
Khái niệm, cấu trúc dữ liệu và giải thuật trên cây nhị phân tìm kiếm, cây cân bằng AVL, cây nhị phân tìm kiếm tối ƣụ
Khái niệm bảng băm, hàm băm, bảng băm mở, bảng băm đóng.
Kỹ thuật index trong cơ sở dữ liệu: khái niệm index, kỹ thuật index trong SQL Server, Index Lucencẹ
Các thuật toán đối sánh mẫu chính xác KMP (Knuth Morris Pratt) và BM (Boyer-Moore), thuật toán KMP mờ.
Xây dựng phần mềm phát triển trên ngôn ngữ C# và sử dụng tool
development Visual studio 2012 trong đó sử dụng thuật toán tìm kiếm KMP cho bài toán tìm kiếm danh bạ điện thoạị
Hƣớng nghiên cứu tiếp theo
Tìm hiểu và xây dựng chƣơng trình ứng dụng trong thực tế có sử dụng các thuật toán tìm kiếm hiệu quả.
Do khả năng của bản thân có hạn nên luận văn còn nhiều thiếu sót, em rất mong nhận đƣợc sự góp ý, chỉ dẫn thêm của thầy cô, bạn bè và đồng nghiệp để em có thể xây dựng đƣợc ứng dụng hoàn thiện hơn. Một lần nữa, em xin chân thành cảm ơn cô giáo Tiến sĩ Nguyễn Thị Thanh Huyền, các thầy cô giáo trong Viện đã tạo điều kiện thuận lợi giúp em có thể hoàn thành luận văn.
102
TÀI LIỆU THAM KHẢO
[1]. Nguyễn Thị Thanh Huyền, Đối sánh mẫu theo tiếp cận otomat mờ và ứng dụng, Luận án tiến sĩ, Viện Toán ứng dụng và Tin học, trƣờng Đại học Bách khoa Hà Nội, 2007.
[2]. Đỗ Xuân Lôi, Cấu trúc dữ liệu và giải thuật, NXB ĐHQGHN, 2008.
[3]. PGS.TS. Nguyễn Đức Nghĩa, Cấu trúc và giải thuật, NXB Bách Khoa Hà Nội, 2008.
[4]. Hồ Thuần, Hồ Cẩm Hà, Trần Thiên Thanh, Cấu trúc dữ liệu, Phân tích thuật toán và phát triển phần mềm, NXBGD, 2008.
[5]. Cơ bản về index trong SQL Server,
http://www.bigdatạcom.vn/2013/07/co-ban-ve-index-trong-sql-server.html
[6]. Chƣơng 12- bảng và truy xuất thông tin – Giáo trình cấu trúc dữ liệu và giải thuật
http://m.123doc.org/document/629869-bang-va-truy-xuat-thong-tin.htm. [7].LucennẹNet document,
http://incubator.apachẹorg/lucenẹnet/docs/2.1/LucenẹNet.Documents.html
[8]. LucenẹNet overview, http://incubator.apachẹorg/lucenẹnet/
[9]. Shou-chuan-Yang, A search algorithm and data structure for an efficient information system, International conference on Computational linguistics coling, 1969.