Chương trình Vertical Fragment được thiết kế mô phỏng giải thuật phân mảnh dọc cơ sở dữ liệu phân bố đã được học từ chương trình, bao gồm các phần như sau:
- Nhập ma trận use bao gồm việc nhập số thuộc tính, số site và số query thực tế trong việc thiết kế, sau đó sinh ra ma trận
- Tính toán việc phân mảnh bao gồm tính ma trận ái lực, ma trận gôm nhóm, sau đó kết luận những thuộc tính nào nằm nên nằm trong 2 mảnh
- Chương trình cho phép người dùng chọn 2 cột thuộc tính mặc định ban đầu trong việc gom nhóm (việc này giúp mở rộng cách chọn, không chỉ luôn chọn cột 1 và 2)
- Diễn giải tiến trình hoạt động rất cụ thể và thân thiện.
- Một số chức năng cho chương trình như tạo mới, sinh ra tập dữ liệu demo để test chương trình.
Chương trình này hiện thực bằng cách sử dụng công cụ mới nhất như sau: - Ngôn ngữ lập trình: Visual C# 2010 (Microsoft .NET framework 4.0)
1. Ngôn ngữ lập trình
Sau đây là cấu trúc chương trình mô tả ngắn gọn trong Solution của Project Vertical Fragment như sau:
Chi tiết các class như sau:
- Form1.cs, Form1.Design.cs, Form1.resx: Form giao diện chính chương trình tương tác với người dùng.
- About.cs, About.Designer,cs, About.resx: Form giao diện giới thiệu về chương trình.
- DialogSelectDefaultColumns.cs, DialogSelectDefaultColumns.Designer.cs, DialogSelectDefaultColumns.resx: Form giúp người dùng chọn lựa 2 cột đầu tiên mặc định trong quá trình gôm nhóm, thay vì luôn luôn chọn cột 1 và cột 2.
- Program.cs: class mặc định của C# là điểm vào chính của chương trình để gọi Form1 và vẽ các thành phần đồ họa form.
- Utility.cs: class lưu trữ các hàm tiện ích mà sử dụng trong chương trình như: xử lý chuỗi, hàm xuất ra màn hình của cấu trúc dữ liệu
chuỗi/Arraylist, xử lý hội, giao, hiệu 2 tập hợp, và các hàm xử lý output chuỗi ra progress bar thân thiện.
- VerticalFragment.cs: class lưu trữ thông tin thuộc tính và hàm cho giải thuật phân mảnh dọc như tạo ma trận AA, tính ma trận ái lực CA, tính ma trận gôm nhóm, tính contribution, tính Bond và một số hàm phụ hỗ trợ. - Matrix.cs: class lưu trữ thông tin thuộc tính và hàm cho giải thuật cho cấu
trúc dữ liệu ma trận như tạo contructor ma trân, copy 2 ma trận, đảo cột hay đổi dòng ma trận, tính tổng giá trị các dòng.
- #1: Menu chương trình bao gồm: tạo mới, thêm dữ liệu demo, giới thiệu chương trình và thoát
- #2: Panel cho phép chọn thuộc tính, số query và site sau đó sinh động ra số dòng và số cột để nhập liệu
- #3: Panel nhập ma trận used bao gồm số dòng là các số query q và cột là các thuộc tính A
- #4: Panel nhập ma trận tần số các site mà query truy cập bao gồn số dòng là số query q (cùng số lượng query như ma trận used), và số cột là các site S - #5: Chương trình sẽ tính toán và xuất ra ma trận ái lực AA vào panel này - #6: Chương trình sẽ tính toán và xuất ra ma trận gôm nhóm CA vào panel
này
- #7: kết quả phân mảnh các thuộc tính của TA - #8: kết quả phân mảnh các thuộc tính của BA
- #9: Diễn giải tất cả tiến trình hoạt động cho chương trình bao từ lúc nhập ma trận use cho đến lúc chọn được 2 mảnh
Một số điểm chính chương trình và hàm Vertical Fragment (Phân mảnh ngang) Sau đây là những diễn giải chính cho class VerticalFragment, đó là 1 class chính chức năng để run chương trình và cần được phân tích
Hàm CreateAffMatrix():
hàm tính ma trận ái lực AA
private static long CalAffAiAj(int col1,int col2, Matrix Matrix1, Matrix Matrix2,
RichTextBox richtxtProgress) {
long result=0; int i;
string formula = "Aff[" + (col1+1) + "," + (col2+1) + "]="; if (col1 == col2) //same row same column
{
for (i = 0; i < Matrix1.RowCount; i++) {
if (Matrix1[i, col1] != 0) {
result += (Matrix.SumRow(i, Matrix2, ref formula)); formula += "+";
} } }
else //different row different column
{
for (i = 0; i < Matrix1.RowCount; i++) {
if (Matrix1[i, col1] != 0 && Matrix1[i, col2] != 0) {
result += (Matrix.SumRow(i, Matrix2, ref formula)); formula += "+";
} } }
// cut "+" in the last
formula = formula.Substring(0, formula.Length - 1);
formula += "=" + result;
richtxtProgress.AppendText(formula + Environment.NewLine); return result;
}
Chi tiết các hàm phụ trợ để tính ma trận ái lực chính là hàm SumRow(), hàm này cũng khá đon giản tính tổng các row ma có 2 thuộc tính cùng là 1
public static long SumRow(int row, Matrix matrix, ref string formula) {
long result = 0; formula += "(";
for (int i = 0; i < matrix.ColumnCount; i++) { result += matrix[row, i] * 1; if (i!= matrix.ColumnCount -1) formula += matrix[row, i] +"*1" + "+"; else formula += matrix[row, i] +"*1"; } formula += ")"; return result; }
Hàm CreateCAMatrix():
hàm tính ma trận ái lực CA và bao gồm cả việc hoán vị dòng sau khi chèn các thuộc tính theo một trật tự:
public static Matrix CreateCAMatrix(Matrix MatrixAA, ref ArrayList
OrderColumnsInMatrixChanged, RichTextBox richtxtProgress) {
string outString = "";
ArrayList allArrayAtrribute = new ArrayList(); ArrayList currentArrayAtrribute = new ArrayList(); ArrayList remainingArrayAtrribute = new ArrayList(); //display message to select default 2 columns
DialogSelectDefaultColumns childDlg = new
DialogSelectDefaultColumns(MatrixAA);
childDlg.ShowDialog();
string value1 = childDlg.txt1value; string value2 = childDlg.txt2value;
ArrayList newSelectedOrder = new ArrayList(); //childDlg.Close();
//add all values for matrix attribute
for (int i = 1; i <= MatrixAA.RowCount; i++) allArrayAtrribute.Add(i);
//Add new order to array list
newSelectedOrder.Add(Int32.Parse(value1)); newSelectedOrder.Add(Int32.Parse(value2)); currentArrayAtrribute.Add(Int32.Parse(value1)); currentArrayAtrribute.Add(Int32.Parse(value2)); //Add remaining atrribute
remainingArrayAtrribute = Utility.CalculateOQ(allArrayAtrribute, new
ArrayList(), currentArrayAtrribute);
for (int i=1; i <=MatrixAA.RowCount; i++) {
if (!newSelectedOrder.Contains(i)) newSelectedOrder.Add(i); }
// Transfer col 1 and 2 from matix AA to CA
richtxtProgress.AppendText("- Bước 1: Chuyển cột " + value1 +" và " +value2+ " từ ma trận AA--> CA\n");
//Change matrix AA order
ChangeMatrixByCols(ref MatrixAA, newSelectedOrder); //Process insert
OrderColumnsInMatrixChanged.Add(1); OrderColumnsInMatrixChanged.Add(2); //Output matrix col 1 and 2 to screen
for (int i = 0; i < MatrixAA.RowCount; i++) {
{ richtxtProgress.AppendText(MatrixAA[i,j].ToString() + "\t"); } richtxtProgress.AppendText("\n"); } richtxtProgress.AppendText("\n");
richtxtProgress.AppendText(Utility.OutputArrayListAtrribute(currentArrayAtrribute) + "\n");
//dont need to calculate if matrix size <=2
if (MatrixAA.ColumnCount <= 2) return MatrixAA; Matrix result = MatrixAA.Clone();
long[] tempArr = new long[MatrixAA.ColumnCount];
richtxtProgress.AppendText("- Bước 2: Xét di chuyển các cột còn lại: " + Utility.OutputArrayListAtrribute(remainingArrayAtrribute) + "\n");
//Xu ly tren cot 3 4 .... chen vao Matrix co san
for (int i = 2; i < result.RowCount; i++) {
currentArrayAtrribute.Add(remainingArrayAtrribute[0]); richtxtProgress.AppendText("Xét di chuyển cột : A" + remainingArrayAtrribute[0] + "\n");
remainingArrayAtrribute.RemoveAt(0);
InsertAndChangePosition(ref result, i, ref outString, ref
OrderColumnsInMatrixChanged, currentArrayAtrribute, remainingArrayAtrribute, richtxtProgress);
//richtxtProgress.AppendText("\n" +
Utility.OutputArrayListAtrribute(Utility.UpdateCurrentArray(ref currentArrayAtrribute, OrderColumnsInMatrixChanged) + "\n");
Utility.UpdateCurrentArray(ref currentArrayAtrribute, OrderColumnsInMatrixChanged, i, result.RowCount);
richtxtProgress.AppendText("\n" +
Utility.OutputArrayListAtrribute(currentArrayAtrribute) + "\n"); }
//Buoc 3: sap xep cac hang theo cot
richtxtProgress.AppendText("- Bước 3: Sắp xếp lại hàng tương ứng cột theo thứ tự: " + Utility.OutputArrayListAtrribute(currentArrayAtrribute));
//array CA matrix again by rows
OrderColumnsInMatrixChanged = currentArrayAtrribute;
ChangeMatrixByRows(ref result, OrderColumnsInMatrixChanged);
return result; }
Sau khi người dùng chọn hai cột để làm cột 1 và 2, chương trình có sử dụng một số hàm quan trọng để tính ma trận gộm nhóm là:
InsertAndChangePosition()
private static void InsertAndChangePosition(ref Matrix MatrixAA, int colProccess,
ref string outString, ref ArrayList OrderColumnsInMatrixChanged, ArrayList
currentArrayAtrribute, ArrayList remainingArrayAtrribute, RichTextBox
richtxtProgress) {
Matrix orgMatrix = MatrixAA.Clone(); int numberOfCase = colProccess; int lastParam;
long[] ArrayForInsertedValues = new long[numberOfCase+1]; ArrayList[] ArrayContItems = new ArrayList[numberOfCase+1];
long max;
int maxPosition;
for (int i = 0; i <= numberOfCase; i++) {
if (i + 1 <= numberOfCase) lastParam = i+1; else
lastParam = 0;
ArrayContItems[i] = new ArrayList(); if (i==0) ArrayContItems[i].Add("_"); else ArrayContItems[i].Add(i); ArrayContItems[i].Add(numberOfCase+1); if (lastParam==0) ArrayContItems[i].Add("_"); else ArrayContItems[i].Add(lastParam); //Calculate Contribution
ArrayForInsertedValues[i] = Contribution(i, numberOfCase+1, lastParam, MatrixAA, currentArrayAtrribute, remainingArrayAtrribute, ref
outString);
richtxtProgress.AppendText(outString);
}
//add max place holder
richtxtProgress.AppendText("\t====> MAX = {0} (Cột {1} chèn giữa phần tử thứ {2} và phần tử thứ {3})\n");
//find max
max = ArrayForInsertedValues[0]; maxPosition = 0;
for (int i = 1; i <= numberOfCase; i++) { if (ArrayForInsertedValues[i] > max) { max = ArrayForInsertedValues[i]; maxPosition = i; } }
//Replace MAX value
string pr1, pr2, pr3;
pr1 = ArrayContItems[maxPosition][1].ToString(); pr2 = ArrayContItems[maxPosition][0].ToString(); pr3 = ArrayContItems[maxPosition][2].ToString();
richtxtProgress.Text = string.Format(richtxtProgress.Text, max.ToString(), pr1, pr2, pr3);
//Insert and Change all columns of Matrix
OrderColumnsInMatrixChanged.Insert(maxPosition,colProccess+1); ChangeMatrix(ref MatrixAA, colProccess, maxPosition);
//Output matrix after inserted and changed
for (int i = 0; i < MatrixAA.RowCount; i++) {
for (int j = 0; j < colProccess+1; j++) { richtxtProgress.AppendText(MatrixAA[i, j].ToString() + "\t"); } richtxtProgress.AppendText("\n"); } }
Hàm được sử dụng trong hàm InsertAndChangePosition() là Contribution() để tính mức độ đóng góp những thuộc tính trong các site và query:
private static long Contribution(int first, int mid, int last, Matrix MatrixAA,
ArrayList currentArrayAtrribute, ArrayList remainingArrayAtrribute, ref string
outString) {
string tempString = "";
string firstString, midString, lastString; long value1, value2, value3;
outString = "";
//firstString = (first == 0 ? "_" : "A" + first.ToString());
firstString = (first == 0 ? "_" : "A" + currentArrayAtrribute[first- 1].ToString());
//midString = (mid == 0 ? "_" : "A" + mid.ToString());
midString = (mid == 0 ? "_" : "A" +
currentArrayAtrribute[currentArrayAtrribute.Count-1].ToString()); //lastString = (last == 0 ? "_" : "A" + last.ToString());
lastString = (last == 0 ? "_" : "A" + currentArrayAtrribute[last- 1].ToString());
//bond 1 calculate
value1= 2 * Bond(first, mid, MatrixAA, ref outString);
tempString+="cont(" + firstString +"," + midString + "," + lastString +")";
tempString+="\t =2*bond(" + firstString + "," + midString + ") + 2*bond(" + midString + "," + lastString + ") - 2*bond(" + firstString +","+ lastString +")\n";
tempString += "\t\t =2*[" + outString + "]"; //bond 2 calculate
outString = "";
value2 = 2 * Bond(mid, last, MatrixAA,ref outString); tempString += " + 2*[" + outString + "]";
//bond 3 calculate
outString = "";
value3 = - 2 * Bond(first, last, MatrixAA,ref outString); tempString += " - 2*[" + outString + "]\n";
//Summary total value
tempString += "\t\t =" + value1 + " + " + value2 + " + " + value3 + " = " + (value1+value2+value3) + "\n";
outString = tempString; return value1+value2+value3; }
Hàm Bond() phụ trợ tính như sau:
private static long Bond(int param1, int param2, Matrix MatrixAA, ref string
outString) { outString = ""; long result=0; if (param1 == 0 | param2 == 0) { outString = "0"; result = 0; } else {
for (int i = 0; i < MatrixAA.RowCount; i++) {
result += MatrixAA[i, param1-1] * MatrixAA[i, param2-1];
//paramx-1 for match array index from 0
outString += MatrixAA[i, param1-1] + "*" + MatrixAA[i, param2- 1] + " + ";
}
outString = outString.Substring(0, outString.Length - 3); outString += " = " + result;
}
return result; }
Hàm CalculateFragments():
hàm tính toán các công thức AQ(qi), TQ, BQ, OQ, CTQ, CBQ, CTQ và Z tổng cuối cùng:
public static void CalculateFragments(ref ArrayList part1, ref ArrayList part2,
Matrix MatrixCA, Matrix Matrix1, Matrix Matrix2, ArrayList
OrderColumnsInMatrixChanged, RichTextBox richtxtProgress) {
int i,rowOfCA,j,k;
int numberOfCase = MatrixCA.RowCount; ArrayList Q = new ArrayList();
ArrayList[] TAArr = new ArrayList[numberOfCase]; ArrayList[] BAArr = new ArrayList[numberOfCase]; ArrayList[] AQArr = new ArrayList[Matrix1.RowCount];
ArrayList[] BQArr = new ArrayList[Matrix1.ColumnCount]; ArrayList[] OQArr = new ArrayList[Matrix1.ColumnCount]; long[] CTQ = new long[Matrix1.ColumnCount];
long[] CBQ = new long[Matrix1.ColumnCount]; long[] COQ = new long[Matrix1.ColumnCount]; long[] Total = new long[Matrix1.ColumnCount-1]; //Add value for Q array List (all queries
for (i = 1; i <= Matrix1.RowCount; i++) Q.Add("q" + i);
//Process for each case
for (i = 1; i < numberOfCase; i++) {
richtxtProgress.AppendText("\n\n- Ở vị trí " + i + ":"); //calculate and output TA
richtxtProgress.AppendText("\nTA = "); TAArr[i - 1] = new ArrayList();
for (rowOfCA=0; rowOfCA<i;rowOfCA++) {
TAArr[i-1].Add("A" + OrderColumnsInMatrixChanged[rowOfCA]);
}
richtxtProgress.AppendText(Utility.OutputArrayList(TAArr[i - 1])); //calculate and output BA
richtxtProgress.AppendText("\nBA = "); BAArr[i - 1] = new ArrayList();
for (rowOfCA = i; rowOfCA < numberOfCase; rowOfCA++) {
BAArr[i - 1].Add("A" + OrderColumnsInMatrixChanged[rowOfCA]); }
richtxtProgress.AppendText(Utility.OutputArrayList(BAArr[i - 1])); //calculate and output AQ(qi)
for (j = 0; j < Matrix1.RowCount; j++) {
AQArr[j] = new ArrayList();
for (k = 0; k < Matrix1.ColumnCount; k++) { if (Matrix1[j,k]==1) { AQArr[j].Add("A" + (k+1)); } } richtxtProgress.AppendText("\nAQ(q" + (j+1) + ") = " + Utility.OutputArrayList(AQArr[j])); }
//calculate and output TQ
richtxtProgress.AppendText("\nTQ = "); TQArr[i-1] = new ArrayList();
for (j = 0; j < Matrix1.RowCount; j++) {
TQArr[i-1].Add("q" + (j + 1)); }
richtxtProgress.AppendText(Utility.OutputArrayList(TQArr[i-1])); //calculate and output BQ
richtxtProgress.AppendText("\nBQ = "); BQArr[i-1] = new ArrayList();
for (j = 0; j < Matrix1.RowCount; j++) {
if (Utility.IsChildSet(AQArr[j], BAArr[i - 1])) BQArr[i-1].Add("q" + (j + 1));
}
richtxtProgress.AppendText(Utility.OutputArrayList(BQArr[i-1])); //calculate and output OQ
richtxtProgress.AppendText("\nOQ = ");
OQArr[i - 1] = Utility.CalculateOQ(Q, TQArr[i - 1], BQArr[i - 1]);
richtxtProgress.AppendText(Utility.OutputArrayList(OQArr[i - 1])); //calculate CTQ
CTQ[i-1] = 0;
richtxtProgress.AppendText("\nCTQ = "); for (j = 0; j < TQArr[i - 1].Count; j++) {
string tempstring = ""; int rownumber = Utility.CutFirstChar(TQArr[i-1] [j].ToString());
richtxtProgress.AppendText("Sum(tần số truy cập của query q" + rownumber + ")\n("); for (k = 0; k < Matrix2.ColumnCount; k++) { CTQ[i - 1] += Matrix2[rownumber - 1, k]; tempstring += Matrix2[rownumber - 1, k] + "+"; }
tempstring = tempstring.Substring(0, tempstring.Length - 1);
richtxtProgress.AppendText(tempstring + ")\n"); }
if (TQArr[i - 1].Count > 0)
richtxtProgress.AppendText(" = " + CTQ[i - 1].ToString()); else
richtxtProgress.AppendText("0"); //calculate CBQ
CBQ[i - 1] = 0;
richtxtProgress.AppendText("\nCBQ = "); for (j = 0; j < BQArr[i - 1].Count; j++) {
string tempstring = "";
int rownumber = Utility.CutFirstChar(BQArr[i - 1] [j].ToString());
richtxtProgress.AppendText("Sum(tần số truy cập của query q" + rownumber + ")\n(");
for (k = 0; k < Matrix2.ColumnCount; k++) {
tempstring += Matrix2[rownumber - 1, k] + "+"; }
tempstring = tempstring.Substring(0, tempstring.Length - 1); richtxtProgress.AppendText(tempstring + ")\n");
}
if (BQArr[i - 1].Count > 0)
richtxtProgress.AppendText(" = " + CBQ[i - 1].ToString()); else
richtxtProgress.AppendText("0"); //calculate COQ
COQ[i - 1] = 0;
richtxtProgress.AppendText("\nCOQ = "); for (j = 0; j < OQArr[i - 1].Count; j++) {
string tempstring = "";
int rownumber = Utility.CutFirstChar(OQArr[i - 1] [j].ToString());
richtxtProgress.AppendText("Sum(tần số truy cập của query q" + rownumber + ")\n("); for (k = 0; k < Matrix2.ColumnCount; k++) { COQ[i - 1] += Matrix2[rownumber - 1, k]; tempstring += Matrix2[rownumber - 1, k] + "+"; }
tempstring = tempstring.Substring(0, tempstring.Length - 1); richtxtProgress.AppendText(tempstring + ")\n");
}
if (OQArr[i - 1].Count > 0)
richtxtProgress.AppendText(" = " + COQ[i - 1].ToString()); else
richtxtProgress.AppendText(" 0"); //Cong thuc Z
Total[i-1]=(CTQ[i-1] * CBQ[i-1]) - (COQ[i-1]*(COQ[i-1])); richtxtProgress.AppendText("\nTổng kết quả: (CTQ * CBQ - bình phương(COQ) = (" + CTQ[i - 1] + " * " + CBQ[i - 1] + " - bình phương(" + COQ[i - 1] + ")) = " + Total[i - 1]);
}
//Find total in arraylist
long max = Total[0]; int maxposition = 0;
for (i = 1; i < Total.Length; i++) { if (max < Total[i]) { max = Total[i]; maxposition = i; } }
//Display chon phan tach o vi tri nao
part1 = TAArr[maxposition]; part2 = BAArr[maxposition];
richtxtProgress.AppendText("\n======> Chọn ở vị trí: " + (maxposition+1) + " có Max = " + Total[maxposition]);
richtxtProgress.AppendText("\n======> CHỌN PHÂN MẢNH TÁCH 2 NHÓM LÀ: "); richtxtProgress.AppendText("\n TA = " + Utility.OutputArrayList(TAArr[maxposition])); richtxtProgress.AppendText("\n BA = " + Utility.OutputArrayList(BAArr[maxposition])); } }
Hai thông số part1, part2 sẽ trả ra các tập thuộc tính được chọn sau khi phân mảnh dọc, ví dụ như dữ liệu phía trên, sẽ có 2 tập được chọn như sau {A3, A2, A4, A5} và {A1}:
2. Demo chương trình phân mảnh dọc
Ví dụ khi nhấn vào Data/Demo3, sẽ hiển thị 1 dữ liệu mẫu cho các ma trận:
Menu Help/About để giới thiệu về chương trình như tên môn học, tên đề tài, giáo viên hướng dẫn, môi trường chạy…
Và sau đây là log chương trình sau khi chạy (được xuất ra từ panel “Tiến trình hoạt động”) sẽ có kết quả như sau:
********** Ma Trận Giá Trị Thuộc Tính (Used) **********
1 1 1 0 0
0 0 1 1 0
0 1 0 1 1
0 0 1 0 1
********** Ma Trận Tần Số Truy Cập (Query Access) **********
20 1 0 10 5 9 80 1 9 2 5 4 ********** Ma Trận Ái Lực AA (Aff) ********** Aff[1,1]=(20*1+1*1+0*1)=21 Aff[1,2]=(20*1+1*1+0*1)=21 Aff[1,3]=(20*1+1*1+0*1)=21 Aff[1,4]=0 Aff[1,5]=0 Aff[2,1]=(20*1+1*1+0*1)=21 Aff[2,2]=(20*1+1*1+0*1)+(80*1+1*1+9*1)=111 Aff[2,3]=(20*1+1*1+0*1)=21 Aff[2,4]=(80*1+1*1+9*1)=90 Aff[2,5]=(80*1+1*1+9*1)=90 Aff[3,1]=(20*1+1*1+0*1)=21 Aff[3,2]=(20*1+1*1+0*1)=21 Aff[3,3]=(20*1+1*1+0*1)+(10*1+5*1+9*1)+(2*1+5*1+4*1)=56 Aff[3,4]=(10*1+5*1+9*1)=24 Aff[3,5]=(2*1+5*1+4*1)=11 Aff[4,1]=0 Aff[4,2]=(80*1+1*1+9*1)=90 Aff[4,3]=(10*1+5*1+9*1)=24 Aff[4,4]=(10*1+5*1+9*1)+(80*1+1*1+9*1)=114 Aff[4,5]=(80*1+1*1+9*1)=90 Aff[5,1]=0 Aff[5,2]=(80*1+1*1+9*1)=90 Aff[5,3]=(2*1+5*1+4*1)=11 Aff[5,4]=(80*1+1*1+9*1)=90 Aff[5,5]=(80*1+1*1+9*1)+(2*1+5*1+4*1)=101 21 21 21 0 0 21 111 21 90 90 21 21 56 24 11 0 90 24 114 90 0 90 11 90 101 Bond(1,2)= (21*21)+(21*111)+(21*21)+(0*90)+(0*90) = 3213 Bond(1,3)= (21*21)+(21*21)+(21*56)+(0*24)+(0*11) = 2058 Bond(1,4)= (21*0)+(21*90)+(21*24)+(0*114)+(0*90) = 2394 Bond(1,5)= (21*0)+(21*90)+(21*11)+(0*90)+(0*101) = 2121 Bond(2,3)= (21*21)+(111*21)+(21*56)+(90*24)+(90*11) = 7098 Bond(2,4)= (21*0)+(111*90)+(21*24)+(90*114)+(90*90) = 28854 Bond(2,5)= (21*0)+(111*90)+(21*11)+(90*90)+(90*101) = 27411 Bond(3,4)= (21*0)+(21*90)+(56*24)+(24*114)+(11*90) = 6960 Bond(3,5)= (21*0)+(21*90)+(56*11)+(24*90)+(11*101) = 5777 Bond(4,5)= (0*0)+(90*90)+(24*11)+(114*90)+(90*101) = 27714 ********** Ma Trận CA **********
- Bước 1: Chuyển cột 3 và 5 từ ma trận AA--> CA
21 0
21 90
56 11
24 90
A3 A5
- Bước 2: Xét di chuyển các cột còn lại: A1 A2 A4 Xét di chuyển cột : A1
cont(_,A1,A3) =2*bond(_,A1) + 2*bond(A1,A3) - 2*bond(_,A3)
=2*[0] + 2*[21*21 + 21*21 + 21*56 + 0*24 + 0*11 = 2058] - 2*[0] =0 + 4116 + 0 = 4116
cont(A3,A1,A5) =2*bond(A3,A1) + 2*bond(A1,A5) - 2*bond(A3,A5)
=2*[21*21 + 21*21 + 56*21 + 24*0 + 11*0 = 2058] + 2*[21*0 + 21*90 + 21*11 + 0*90 + 0*101 = 2121] - 2*[21*0 + 21*90 + 56*11 + 24*90 + 11*101 = 5777]
=4116 + 4242 + -11554 = -3196
cont(A5,A1,_) =2*bond(A5,A1) + 2*bond(A1,_) - 2*bond(A5,_)
=2*[0*21 + 90*21 + 11*21 + 90*0 + 101*0 = 2121] + 2*[0] - 2*[0] =4242 + 0 + 0 = 4242 ====> MAX = 4242 (Cột 3 chèn giữa phần tử thứ 2 và phần tử thứ _) 21 0 21 21 90 21 56 11 21 24 90 0 11 101 0 A3 A5 A1 Xét di chuyển cột : A2
cont(_,A2,A3) =2*bond(_,A2) + 2*bond(A2,A3) - 2*bond(_,A3)
=2*[0] + 2*[21*21 + 111*21 + 21*56 + 90*24 + 90*11 = 7098] - 2*[0] =0 + 14196 + 0 = 14196
cont(A3,A2,A5) =2*bond(A3,A2) + 2*bond(A2,A5) - 2*bond(A3,A5)
=2*[21*21 + 21*111 + 56*21 + 24*90 + 11*90 = 7098] + 2*[21*0 + 111*90 + 21*11 + 90*90 + 90*101 = 27411] - 2*[21*0 + 21*90 + 56*11 + 24*90 + 11*101 = 5777]
=14196 + 54822 + -11554 = 57464
cont(A5,A2,A1) =2*bond(A5,A2) + 2*bond(A2,A1) - 2*bond(A5,A1)
=2*[0*21 + 90*111 + 11*21 + 90*90 + 101*90 = 27411] + 2*[21*21 + 111*21 + 21*21 + 90*0 + 90*0 = 3213] - 2*[0*21 + 90*21 + 11*21 + 90*0 + 101*0 = 2121]
=54822 + 6426 + -4242 = 57006
cont(A1,A2,_) =2*bond(A1,A2) + 2*bond(A2,_) - 2*bond(A1,_)
=2*[21*21 + 21*111 + 21*21 + 0*90 + 0*90 = 3213] + 2*[0] - 2*[0] =6426 + 0 + 0 = 6426 ====> MAX = 57464 (Cột 4 chèn giữa phần tử thứ 1 và phần tử thứ 2) 21 21 0 21 21 111 90 21 56 21 11 21 24 90 90 0 11 90 101 0 A3 A2 A5 A1 Xét di chuyển cột : A4
cont(_,A4,A3) =2*bond(_,A4) + 2*bond(A4,A3) - 2*bond(_,A3)
=2*[0] + 2*[0*21 + 90*21 + 24*56 + 114*24 + 90*11 = 6960] - 2*[0] =0 + 13920 + 0 = 13920
cont(A3,A4,A2) =2*bond(A3,A4) + 2*bond(A4,A2) - 2*bond(A3,A2)
=2*[21*0 + 21*90 + 56*24 + 24*114 + 11*90 = 6960] + 2*[0*21 + 90*111 + 24*21 + 114*90 + 90*90 = 28854] - 2*[21*21 + 21*111 + 56*21 + 24*90 + 11*90 = 7098]
=13920 + 57708 + -14196 = 57432
cont(A2,A4,A5) =2*bond(A2,A4) + 2*bond(A4,A5) - 2*bond(A2,A5)
=2*[21*0 + 111*90 + 21*24 + 90*114 + 90*90 = 28854] + 2*[0*0 + 90*90 + 24*11 + 114*90 + 90*101 = 27714] - 2*[21*0 + 111*90 + 21*11 + 90*90 + 90*101 = 27411]
=57708 + 55428 + -54822 = 58314
cont(A5,A4,A1) =2*bond(A5,A4) + 2*bond(A4,A1) - 2*bond(A5,A1)
=2*[0*0 + 90*90 + 11*24 + 90*114 + 101*90 = 27714] + 2*[0*21 + 90*21 + 24*21 + 114*0 + 90*0 = 2394] - 2*[0*21 + 90*21 + 11*21 + 90*0 + 101*0 = 2121]
=55428 + 4788 + -4242 = 55974
cont(A1,A4,_) =2*bond(A1,A4) + 2*bond(A4,_) - 2*bond(A1,_)
21 21 0 0 21 21 111 90 90 21 56 21 24 11 21 24 90 114 90 0 11 90 90 101 0 A3 A2 A4 A5 A1
- Bước 3: Sắp xếp lại hàng tương ứng cột theo thứ tự: A3 A2 A4 A5 A1
56 21 24 11 21
21 111 90 90 21
24 90 114 90 0
11 90 90 101 0
21 21 0 0 21
********** Phương Pháp Tách Thuộc Tính - Thuật Toán Partition VF ********** - AQ(qi): tập thuộc tính được truy cập bằng qi
AQ(qi) = {Aj | use(qi,Aj) = 1} - TQ: tập thuộc tính chỉ truy cập TA TQ = {qi | AQ(qi) ⊆ TA}
- BQ: tập thuộc tính chỉ truy cập BA BQ = {qi | AQ(qi) ⊆ BA}
- OQ: tập thuộc tính truy cập cả TQ và BQ OQ = Q - {TQ ∪ BQ}
- Ở vị trí 1: TA = {A3}
BA = {A2, A4, A5, A1} AQ(q1) = {A1, A2, A3} AQ(q2) = {A3, A4} AQ(q3) = {A2, A4, A5} AQ(q4) = {A3, A5} TQ = {}
BQ = {q3} OQ = {q1, q2, q4} CTQ = 0
CBQ = Sum(tần số truy cập của query q3) (80+1+9)
= 90
COQ = Sum(tần số truy cập của query q1) (20+1+0)
Sum(tần số truy cập của query q2) (10+5+9)
Sum(tần số truy cập của query q4) (2+5+4)
= 56
Tổng kết quả: (CTQ * CBQ - bình phương(COQ) = (0 * 90 - bình phương(56)) = -3136 - Ở vị trí 2:
TA = {A3, A2}