public void local_search_alg(Tasks tsk, string local_Search_Method_Name, int max_Genens, Random rnd, ref Chromosome ind, ref int func_call) { func_call = 1; switch (local_Search_Method_Name) { case "PRIM_2nd_TASK": #region áp dụng giải thuật PRIM tìm cây khung nhỏ nhất cho cluster int idx_Max_Clus = 0; int num_Vertex_In_Cluster = 0; Evaluate eva = new Evaluate(); eva.find_Largest_Cluster(tsk, ref idx_Max_Clus, ref num_Vertex_In_Cluster); double[,] cluster_Weight = init_Chrome.create_Weight_Matrix_for_Cluster(max_Genens, num_Vertex_In_Cluster, tsk.Weight_Matrix, tsk.Vertex_In_Cluster[idx_Max_Clus]); double[,] spanning_Tree_of_Cluster = graph_Method_Class.prim(cluster_Weight, num_Vertex_In_Cluster, rnd); //Chuyen ra cay khung cua do thi G for (int k = 0; k < num_Vertex_In_Cluster; k++) { for (int j = 0; j < num_Vertex_In_Cluster; j++) { if (spanning_Tree_of_Cluster[k, j] > 0) { ind.Edges_Matrix[tsk.Vertex_In_Cluster[idx_Max_Clus][k], tsk.Vertex_In_Cluster[idx_Max_Clus][j]] = spanning_Tree_of_Cluster[k, j]; } } } //int[,] aaa = new int[max_Genens, max_Genens]; //for (int i = 0; i < max_Genens; i++) //{ // for (int j = 0; j < max_Genens; j++) // { // aaa[i, j] = (int)ind.Edges_Matrix[i, j]; // } //} //ioFile.draw_Plot_in_Matlab("Local_Search_GA" + @".m", max_Genens, aaa); //Evaluate??? #endregion break; case "1": #region 1 //11111; #endregion break; } }
public double[,] edge_Clustered_Tree_Mutation(double[,] par, int num_Vertex, double mutation_Rate, int num_Cluster, int[][] vertex_In_Cluster, Random rnd) { Initialize_Chromosome init_Chrome = new Initialize_Chromosome(); double[,] child = new double[num_Vertex, num_Vertex]; for (int i = 0; i < num_Vertex; i++) { for (int j = 0; j < num_Vertex; j++) { child[i, j] = par[i, j]; } } for (int ii = 0; ii < num_Vertex; ii++) { int idx_Cluster = rnd.Next(num_Cluster); while (vertex_In_Cluster[idx_Cluster].Length < 3) { idx_Cluster = rnd.Next(num_Cluster); } //01. Chuyển ma trận của cluster thành ma trận cây để áp dụng đột biến double[,] weight_Cluster_Matrix; double[,] spanning_Tree_of_Cluster; int num_Vertex_in_Cluster = vertex_In_Cluster[idx_Cluster].Length; weight_Cluster_Matrix = init_Chrome.create_Weight_Matrix_for_Cluster(num_Vertex, num_Vertex_in_Cluster, par, vertex_In_Cluster[idx_Cluster]); spanning_Tree_of_Cluster = edge_Mutation(weight_Cluster_Matrix, num_Vertex_in_Cluster, mutation_Rate, rnd); //Chuyen ra cay khung cua do thi G int[] cluster = new int[num_Vertex_in_Cluster]; for (int i = 0; i < num_Vertex_in_Cluster; i++) { cluster[i] = vertex_In_Cluster[idx_Cluster][i]; } for (int k = 0; k < num_Vertex_in_Cluster; k++) { for (int j = 0; j < num_Vertex_in_Cluster; j++) { //child[cluster[k], cluster[j]] = 0; child[cluster[k], cluster[j]] = spanning_Tree_of_Cluster[k, j]; } } } return(child); }
//Ghi ket qua toi uu ra file public void write_Results(string file_Name, int seed, Tasks tsk, int idx_task, Chromosome best_Ind, string running_Time) { Evaluate eval_class = new Evaluate(); int[] tour_Decode; int[,] tree_Solution; int[] prufer_Tour_Decode; int[,] opt_tree; switch (tsk.Function_Cost_Name) { case "Sphere": case "Rosenbrok": case "Ackley": case "Rastrigin": case "Griewank": case "Weierstrass": case "Schwefel": write_Solution_to_File(file_Name, seed, best_Ind.Rnvec, tsk.Dims, best_Ind.Obj_value[idx_task]); break; case "TSP": #region TSP tour_Decode = eval_class.decoding_TSP(best_Ind.Invec, tsk.MaxDims, tsk.Dims); write_TSP_Solution_to_File(file_Name, seed, tour_Decode, tsk.Dims, best_Ind.Obj_value[idx_task]); #endregion break; case "PRUFER_CODE": #region PRUFER_CODE tour_Decode = eval_class.decoding_MFO_Prufer_Simple(best_Ind.Invec, tsk.MaxDims, tsk.Dims); int[,] edge_Weight = eval_class.convert_Prufer_to_Tree(tour_Decode, tsk.Dims + 2); write_Opt_Solution_File(file_Name, seed, edge_Weight, tsk.Dims + 2, best_Ind.Obj_value[idx_task], running_Time, false); draw_Plot_in_Matlab(Path.GetDirectoryName(file_Name) + @"\" + Path.GetFileNameWithoutExtension(file_Name) + @".m", tsk.Dims + 2, edge_Weight); #endregion break; case "BLOB_CODE": #region BLOB_CODE int[,] tree_temp = new int[(tsk.Dims + 2) + 1, (tsk.Dims + 2) + 1]; int[] blod_arr = new int[(tsk.Dims + 2) + 1]; blod_arr[0] = -1; //A Blob string B = (b2, b3, . . . , bn−1) ∈ Cn. blod_arr[1] = -1; //Blod code: 1 -> n blod_arr[tsk.Dims + 2] = -1; prufer_Tour_Decode = eval_class.decoding_MFO_Prufer_Simple(best_Ind.Invec, tsk.MaxDims, tsk.Dims); for (int i = 2; i <= (tsk.Dims + 2) - 1; i++) { blod_arr[i] = prufer_Tour_Decode[i - 2] + 1; } tree_temp = eval_class.convert_Blod_to_Tree(blod_arr, (tsk.Dims + 2)); tree_Solution = new int[tsk.Dims + 2, tsk.Dims + 2]; for (int i = 0; i < (tsk.Dims + 2); i++) { for (int j = 0; j < (tsk.Dims + 2); j++) { tree_Solution[i, j] = tree_temp[i + 1, j + 1]; } } write_Opt_Solution_File(file_Name, seed, tree_Solution, tsk.Dims + 2, best_Ind.Obj_value[idx_task], running_Time, false); draw_Plot_in_Matlab(Path.GetDirectoryName(file_Name) + @"\" + Path.GetFileNameWithoutExtension(file_Name) + @".m", tsk.Dims + 2, tree_Solution); #endregion break; case "EDGES_SET": case "EDGES_SET_VERTEX_IN_SUBGRAPH": #region EDGES_SET //tree_Solution = new int[tsk.MaxDims, tsk.MaxDims]; //for (int i = 0; i < tsk.MaxDims; i++) //{ // for (int j = 0; j < tsk.MaxDims; j++) // { // tree_Solution[i, j] = (int)best_Ind.Edges_Matrix[i, j]; // } //} //draw_Plot_in_Matlab(Path.GetDirectoryName(file_Name) + @"\" + "AAAA" + tsk.Dims.ToString() + @".m", tsk.MaxDims, tree_Solution); tree_Solution = eval_class.decoding_MFO_Edge_Set_1(best_Ind.Edges_Matrix, tsk.MaxDims, tsk.Dims); write_Opt_Solution_File(file_Name, seed, tree_Solution, tsk.Dims, best_Ind.Obj_value[idx_task], running_Time, false); draw_Plot_in_Matlab(Path.GetDirectoryName(file_Name) + @"\" + Path.GetFileNameWithoutExtension(file_Name) + @".m", tsk.Dims, tree_Solution); #endregion break; case "CLUSTERED_TREE": #region CLUSTERED_TREE tree_Solution = new int[tsk.MaxDims, tsk.MaxDims]; for (int i = 0; i < tsk.MaxDims; i++) { for (int j = 0; j < tsk.MaxDims; j++) { tree_Solution[i, j] = (int)best_Ind.Edges_Matrix[i, j]; } } //draw_Plot_in_Matlab(Path.GetDirectoryName(file_Name) + @"\" + "AAAA" + tsk.Dims.ToString() + @".m", tsk.MaxDims, tree_Solution); //?????????????????Decoding //tree_Solution = eval_class.decoding_MFO_Edge_Set_1(best_Ind.Edges_Matrix, tsk.MaxDims, tsk.Dims); write_Opt_Solution_File(file_Name, seed, tree_Solution, tsk.Dims, best_Ind.Obj_value[idx_task], running_Time, false); draw_Plot_in_Matlab(Path.GetDirectoryName(file_Name) + @"\" + Path.GetFileNameWithoutExtension(file_Name) + @".m", tsk.Dims, tree_Solution); #endregion break; case "MAX_GROUP_IN_CLUSTERED_TREE": #region MAX_GROUP_IN_CLUSTERED_TREE int idx_Max_Clus = 0; int num_Vertex_In_Cluster = tsk.Vertex_In_Cluster[0].Length; for (int i = 1; i < tsk.Num_Cluster; i++) { if (tsk.Vertex_In_Cluster[i].Length > num_Vertex_In_Cluster) { num_Vertex_In_Cluster = tsk.Vertex_In_Cluster[i].Length; idx_Max_Clus = i; } } double[,] weight_Cluster_Matrix = init_Chromo.create_Weight_Matrix_for_Cluster(tsk.MaxDims, num_Vertex_In_Cluster, best_Ind.Edges_Matrix, tsk.Vertex_In_Cluster[idx_Max_Clus]); tree_Solution = new int[num_Vertex_In_Cluster, num_Vertex_In_Cluster]; for (int i = 0; i < num_Vertex_In_Cluster; i++) { for (int j = 0; j < num_Vertex_In_Cluster; j++) { tree_Solution[i, j] = (int)weight_Cluster_Matrix[i, j]; } } write_Opt_Solution_File(file_Name, seed, tree_Solution, num_Vertex_In_Cluster, best_Ind.Obj_value[idx_task], running_Time, false); draw_Plot_in_Matlab(Path.GetDirectoryName(file_Name) + @"\" + Path.GetFileNameWithoutExtension(file_Name) + @".m", num_Vertex_In_Cluster, tree_Solution); #endregion break; } }
/********************************************************************************************************************************************* * Tìm ma trận liên kết các cluster từ cây khung * + Hướng 1: Chỉ tìm liên kết không quan tâm tới trọng số * + Hướng 2: Tìm liên kết có lưu trọng số, và các cạnh nối giữa các cluster để thực hiện lai ghép về sau <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< **********************************************************************************************************************************************/ private double[,] primRST_Cluster_Crossover(double[,] par_1, double[,] par_2, int num_Vertex, int num_Cluster, int[][] vertex_In_Cluster, Random rnd) { double[,] G_cr = new double[num_Vertex, num_Vertex]; double[,] T = new double[num_Vertex, num_Vertex]; Initialize_Chromosome init_Chrome = new Initialize_Chromosome(); //Khoi tao for (int i = 0; i < num_Vertex; i++) { for (int j = i; j < num_Vertex; j++) { T[i, j] = 0; T[j, i] = 0; } } //Ap dung PrimRST crossover cho tung cluster double[,] weight_Cluster_Matrix_Par_1, weight_Cluster_Matrix_Par_2; double[,] spanning_Tree_of_Cluster; int num_Vertex_in_Cluster = 0; for (int i = 0; i < num_Cluster; i++) { num_Vertex_in_Cluster = vertex_In_Cluster[i].Length; weight_Cluster_Matrix_Par_1 = init_Chrome.create_Weight_Matrix_for_Cluster(num_Vertex, num_Vertex_in_Cluster, par_1, vertex_In_Cluster[i]); weight_Cluster_Matrix_Par_2 = init_Chrome.create_Weight_Matrix_for_Cluster(num_Vertex, num_Vertex_in_Cluster, par_2, vertex_In_Cluster[i]); spanning_Tree_of_Cluster = primRST_Crossover(weight_Cluster_Matrix_Par_1, weight_Cluster_Matrix_Par_2, num_Vertex_in_Cluster, rnd); //Chuyen ra cay khung cua do thi G for (int k = 0; k < num_Vertex_in_Cluster; k++) { for (int j = 0; j < num_Vertex_in_Cluster; j++) { if (spanning_Tree_of_Cluster[k, j] > 0) { T[vertex_In_Cluster[i][k], vertex_In_Cluster[i][j]] = spanning_Tree_of_Cluster[k, j]; } } } } //Tạo cây khung cho đại diện các nhóm //01. Tim cạnh liên kết các nhóm của cha mẹ => các cạnh của cha mẹ có thể liên kết tới các đỉnh khác nhau của cùng 1 nhóm => weight_Cluster_Matrix_Par_1 = find_Spanning_Tree_Between_Clusters(par_1, num_Vertex, num_Cluster, vertex_In_Cluster); weight_Cluster_Matrix_Par_2 = find_Spanning_Tree_Between_Clusters(par_2, num_Vertex, num_Cluster, vertex_In_Cluster); //02. Tạo các thể con cho các cạnh nay spanning_Tree_of_Cluster = primRST_Crossover(weight_Cluster_Matrix_Par_1, weight_Cluster_Matrix_Par_2, num_Cluster, rnd); //Chuyen ra cay khung cua do thi G int[] idx_Cluster = new int[num_Cluster]; for (int i = 0; i < num_Cluster; i++) { int vt = rnd.Next(vertex_In_Cluster[i].Length); idx_Cluster[i] = vertex_In_Cluster[i][vt]; } for (int k = 0; k < num_Cluster; k++) { for (int j = 0; j < num_Cluster; j++) { if (spanning_Tree_of_Cluster[k, j] > 0) { T[idx_Cluster[k], idx_Cluster[j]] = spanning_Tree_of_Cluster[k, j]; } } } return(T); }
/********************************************************************************************************************************************* * Thủ tục gần đúng tìm lời giải bài toán: Clustered Shortest-Path Tree Problem * Thuật toán áp dụng DFS cho cây khung với mỗi nút là 1 cluster; sau đó áp dụng Dijstra cho các đỉnh trong cluster * Output: ma tran trong so bieu dien cay khung: edge_Matrix ********************************************************************************************************************************************/ private void BFS_Dijstra_Clustered_Tree(double[,] weigh_Matrix, int num_Vertex, int num_Cluster, int[][] vertex_In_Cluster, int start_Vertex, out double[,] edge_Matrix) { int[,] connect_Cluster; //Lưu các đỉnh thuộc các cluster nào được sử dụng để nối tới đỉnh khác. double[,] cluster_Weight; int[] pre; List <int> path_1; edge_Matrix = new double[num_Vertex, num_Vertex]; for (int i = 0; i < num_Vertex; i++) { for (int j = i; j < num_Vertex; j++) { edge_Matrix[i, j] = 0; } } //01. Chuyển đồ thị thành độ thị với mỗi cluster là một đỉnh find_Spanning_Tree_Between_Clusters_Determine_Vertex(weigh_Matrix, num_Vertex, num_Cluster, vertex_In_Cluster, out cluster_Weight, out connect_Cluster); //02. Áp dụng BFS cho đồ thị được tạo từ cluster //+ Kiểm tra xem start_Vertex thuộc cluster nào, để áp dụng BFS từ cluster đó. int idx_Cluster = -1; for (int i = 0; i < num_Cluster; i++) { if (vertex_In_Cluster[i].Contains(start_Vertex)) { idx_Cluster = i; break; } } int[] preBFS = graph_Method_Class.BFS(cluster_Weight, num_Cluster, idx_Cluster); //+ Tạo đồ thị theo duyệt cây BFS //double[,] aaa = new double[num_Cluster, num_Cluster]; for (int i = 0; i < num_Cluster; i++) { path_1 = graph_Method_Class.print_Path(idx_Cluster, i, preBFS); for (int j = path_1.Count - 1; j > 0; j--) { //aaa[path_1[j], path_1[j - 1]] = cluster_Weight[path_1[j], path_1[j - 1]]; //aaa[path_1[j - 1], path_1[j]] = aaa[path_1[j], path_1[j - 1]]; edge_Matrix[connect_Cluster[path_1[j], path_1[j - 1]], connect_Cluster[path_1[j - 1], path_1[j]]] = cluster_Weight[path_1[j], path_1[j - 1]]; edge_Matrix[connect_Cluster[path_1[j - 1], path_1[j]], connect_Cluster[path_1[j], path_1[j - 1]]] = cluster_Weight[path_1[j], path_1[j - 1]]; } } //int[,] map = new int[num_Cluster, num_Cluster]; //for (int i = 0; i < num_Cluster; i++) //{ // for (int j = 0; j < num_Cluster; j++) // { // map[i, j] = (int)aaa[i, j]; // } //} //ioFile.draw_Plot_in_Matlab("DFS_cluster_Tree.m", num_Cluster, map); //02. Du dung Dijstra cho cac Cluster double[,] weight_Cluster_Matrix; double[,] spanning_Tree_of_Cluster; int num_Vertex_in_Cluster = 0; int start_Vertex_In_Cluster = -1; //Đỉnh kết nối với cluster ngoài sau khi chuyển về ma trận clustert int vertex_Connect_Other_Cluster = -1; //Đỉnh kết nối với ma trận ngoài for (int i = 0; i < num_Cluster; i++) { start_Vertex_In_Cluster = -1; num_Vertex_in_Cluster = vertex_In_Cluster[i].Length; weight_Cluster_Matrix = init_Chrome.create_Weight_Matrix_for_Cluster(num_Vertex, num_Vertex_in_Cluster, weigh_Matrix, vertex_In_Cluster[i]); if (vertex_In_Cluster[i].Contains(start_Vertex))//cluster nao chua dinh: start_Vertex thi se duyet distra tu dinh do { vertex_Connect_Other_Cluster = start_Vertex; //Tìm xem: start_Vertex là đỉnh thứ bao nhiều trong đồ thị sau khi chuyển cluster for (int j = 0; j < num_Vertex_in_Cluster; j++) { if (vertex_In_Cluster[i][j] == start_Vertex) { start_Vertex_In_Cluster = j; break; } } pre = graph_Method_Class.dijkstra(weight_Cluster_Matrix, num_Vertex_in_Cluster, start_Vertex_In_Cluster); } else { //Xác định đỉnh trong cluster liên kết với đỉnh ở cluster khác path_1 = graph_Method_Class.print_Path(idx_Cluster, i, preBFS); //++ Xác cluster cha trong đường đi tới cluster chứa đỉnh nguồn int idx_Cluster_Parent = path_1[1];//path_1[0] la dinh i //Xác định xem đỉnh trên là đỉnh nào trong ma trận chuyển la dinh se bat dau ap dung dijstra vertex_Connect_Other_Cluster = connect_Cluster[i, path_1[1]]; //Tu dinh do xac dinh xem la dinh nao trong ma tran chuyen cluster for (int j = 0; j < num_Vertex_in_Cluster; j++) { if (vertex_In_Cluster[i][j] == vertex_Connect_Other_Cluster) { start_Vertex_In_Cluster = j; break; } } //+ Ap dung Dijstra cho cluster pre = graph_Method_Class.dijkstra(weight_Cluster_Matrix, num_Vertex_in_Cluster, start_Vertex_In_Cluster); } //Tao cay khung cho Dijstra spanning_Tree_of_Cluster = new double[num_Vertex_in_Cluster, num_Vertex_in_Cluster]; for (int ii = 0; ii < num_Vertex_in_Cluster; ii++) { path_1 = graph_Method_Class.print_Path(start_Vertex_In_Cluster, ii, pre); for (int l = path_1.Count - 1; l > 0; l--) { spanning_Tree_of_Cluster[path_1[l], path_1[l - 1]] = weight_Cluster_Matrix[path_1[l], path_1[l - 1]]; spanning_Tree_of_Cluster[path_1[l - 1], path_1[l]] = weight_Cluster_Matrix[path_1[l - 1], path_1[l]]; } } //map = new int[num_Vertex_in_Cluster, num_Vertex_in_Cluster]; //for (int iii = 0; iii < num_Vertex_in_Cluster; iii++) //{ // for (int jjj = 0; jjj < num_Vertex_in_Cluster; jjj++) // { // map[iii, jjj] = (int)spanning_Tree_of_Cluster[iii, jjj]; // } //} //ioFile.draw_Plot_in_Matlab("Dijstra_for_cluster_Weight_" + i.ToString() + ".m", num_Vertex_in_Cluster, map); //Chuyen ra cay khung cua do thi G for (int k = 0; k < num_Vertex_in_Cluster; k++) { for (int j = 0; j < num_Vertex_in_Cluster; j++) { if (spanning_Tree_of_Cluster[k, j] > 0) { edge_Matrix[vertex_In_Cluster[i][k], vertex_In_Cluster[i][j]] = spanning_Tree_of_Cluster[k, j]; } } } }//for }