//对该列重排序,第一放最后,其他依次上升 private void ReSortColumn(sim_node[] column, int m) { sim_node temp = column[0]; for (int i = 0; i < m - 1; i++) { column[i] = column[i + 1]; } column[m - 1] = temp; }
//对一列matrix_point排序(冒泡):最大的排最前 private void SortColumn(sim_node[] column, int m) { for (int i = 0; i < m - 1; i++) { bool isSorted = true; //假设剩下的元素已经排序好了 for (int j = 0; j < m - 1 - i; j++) { if (column[j].value < column[j + 1].value) { sim_node temp = column[j]; column[j] = column[j + 1]; column[j + 1] = temp; isSorted = false; //一旦需要交换数组元素,就说明剩下的元素没有排序好 } } if (isSorted) { break; //如果没有发生交换,说明剩下的元素已经排序好了 } } }
//路径匹配算法 //计算整个obj路径集合与待匹配的集合的相似性 private double QueueSetSimOur(String file1_name, String file2_name, double w_visual) { //组装2个界面代码文件对应序列的完整路径 String list1_path = path + @"UI_LIST\list_" + file1_name + ".csv"; String list2_path = path + @"UI_LIST\list_" + file2_name + ".csv"; //组装2个界面代码文件对应元素属性的完整路径 String tree1_path = path + @"UI_TREE\" + file1_name + ".csv"; String tree2_path = path + @"UI_TREE\" + file2_name + ".csv"; List <String[]> list_queue1 = new List <String[]>(); List <String[]> list_queue2 = new List <String[]>(); //获取文件的序列 list_queue1 = CSVtoStingList(list1_path); list_queue2 = CSVtoStingList(list2_path); int n = list_queue1.Count; int m = list_queue2.Count; var column = new List <sim_node[]>(); if (n > m)//始终把路径少的集合作为列 { //交换list_queue1,2 List <String[]> list_temp = new List <string[]>(); list_temp = list_queue1; list_queue1 = list_queue2; list_queue2 = list_temp; //交换文件属性的路径 String str_temp = tree1_path; tree1_path = tree2_path; tree2_path = str_temp; //交换m,n int num_temp; num_temp = n; n = m; m = num_temp; } for (int i = 0; i < n; i++)//矩阵列 { String[] list_obj = list_queue1[i]; //计算obj中的一条路径与待匹配的集合中的所有路径中最相似路径的相似度 sim_node[] row = new sim_node[m]; for (int j = 0; j < m; j++)//矩阵行 { String[] list_sub = list_queue2[j]; //计算结构相似性//////////////////////////// double med = SinglePathDistance(list_obj, list_sub, tree1_path, tree2_path);//使用med计算两路径的结构差异 //int lcs = LongestCommonSubsequence(list_obj, list_sub, tree1_path, tree2_path);//使用LCS计算两路径的相同结构 double structure_sim = 1 - med / Math.Max(list_obj.Length, list_sub.Length); //double structure_sim = (double)lcs / (double)(med + lcs); //求相对位置的差异作为位置影响因子 double loc_dif_fact = 1 - Math.Abs((double)(i + 1) / n - (double)(j + 1) / m); structure_sim = structure_sim * loc_dif_fact; //计算叶节点相似性////////////////////////// double visual_sim = 0; String obj = GetNodeType(tree1_path, list_obj[0])[0]; //[0]返回type String sub = GetNodeType(tree2_path, list_sub[0])[0]; if (obj.Equals(sub)) //判断两条路径的叶节点的类型是否相等 { visual_sim = 1; } //计算结构与叶节点共同的影响//////////////// row[j].value = structure_sim * (1 - w_visual) + visual_sim * w_visual; row[j].postion = j; } SortColumn(row, m);//对该列排序 column.Add(row); } //调试,排序前输出 //PrintOut(column, m, n, label1); //找到整个集合每列不重叠的最大值,保证每列的第一个元素是最后的最大值 for (int i = 1; i < n; i++) { for (int j = 0; j < i; j++) { //判断该列的最大值[i][0]是否与前列[j][0]最大值的行号重叠 if (column[j][0].postion == column[i][0].postion) { //如果重叠则比较其值的大小,小的则重排序列 if (column[j][0].value > column[i][0].value) { ReSortColumn(column[i], m); i = 1;//一旦发生重排序,就重新开始循环 } else { ReSortColumn(column[j], m); i = 1; } } } } //调试,排序后输出 //PrintOut(column, m, n, label4); //计算整体路径集合的相似度 double sim = 0; for (int i = 1; i < n; i++) { sim = sim + column[i][0].value / n;//每条路径的相似度占总体相似度的1/n,n为路径条数 } //label5.Text += sim; return(sim); }
//Lin算法计算的相似度 private double QueueSetSimLin(String file1_name, String file2_name) { //double sim_lcs = 0; double sim_acs = 0; //组装2个界面代码文件对应序列的完整路径 String list1_path = path + @"UI_LIST\list_" + file1_name + ".csv"; String list2_path = path + @"UI_LIST\list_" + file2_name + ".csv"; //组装2个界面代码文件对应元素属性的完整路径 String tree1_path = path + @"UI_TREE\" + file1_name + ".csv"; String tree2_path = path + @"UI_TREE\" + file2_name + ".csv"; List <String[]> list_queue1 = new List <String[]>(); List <String[]> list_queue2 = new List <String[]>(); //获取文件的序列 list_queue1 = CSVtoStingList(list1_path); list_queue2 = CSVtoStingList(list2_path); int n = list_queue1.Count; int m = list_queue2.Count; //////////////////// var column = new List <sim_node[]>(); if (n > m)//始终把路径少的集合作为列 { //交换list_queue1,2 List <String[]> list_temp = new List <string[]>(); list_temp = list_queue1; list_queue1 = list_queue2; list_queue2 = list_temp; //交换文件属性的路径 String str_temp = tree1_path; tree1_path = tree2_path; tree2_path = str_temp; //交换m,n int num_temp; num_temp = n; n = m; m = num_temp; } for (int i = 0; i < n; i++)//矩阵列 { String[] list_obj = list_queue1[i]; //计算obj中的一条路径与待匹配的集合中的所有路径中最相似路径的相似度 sim_node[] row = new sim_node[m]; for (int j = 0; j < m; j++)//矩阵行 { String[] list_sub = list_queue2[j]; //计算结构相似性//////////////////////////// int acs = AllCommonSubsequence(list_obj, list_sub, tree1_path, tree2_path); int acs_1 = AllCommonSubsequence(list_obj, list_obj, tree1_path, tree1_path); int acs_2 = AllCommonSubsequence(list_sub, list_sub, tree2_path, tree2_path); sim_acs = acs / Math.Sqrt(acs_1 * acs_2); //int lcs = LongestCommonSubsequence(list_obj, list_sub, tree1_path, tree2_path); //sim_lcs = lcs / Math.Sqrt(n * m); row[j].value = sim_acs; row[j].postion = j; } SortColumn(row, m);//对该列排序 column.Add(row); } //调试,排序前输出 //PrintOut(column, m, n, label1); //找到整个集合每列不重叠的最大值,保证每列的第一个元素是最后的最大值 for (int i = 1; i < n; i++) { for (int j = 0; j < i; j++) { //判断该列的最大值[i][0]是否与前列[j][0]最大值的行号重叠 if (column[j][0].postion == column[i][0].postion) { //如果重叠则比较其值的大小,小的则重排序列 if (column[j][0].value > column[i][0].value) { ReSortColumn(column[i], m); i = 1;//一旦发生重排序,就重新开始循环 } else { ReSortColumn(column[j], m); i = 1; } } } } //调试,排序后输出 //PrintOut(column, m, n, label4); //计算整体路径集合的相似度 double sim = 0; for (int i = 1; i < n; i++) { sim = sim + column[i][0].value / n;//每条路径的相似度占总体相似度的1/n,n为路径条数 } //label5.Text += sim; return(sim); }