/// <summary> /// 开始优化 /// </summary> /// <param name="ConfigFile">算法参数配置文件路径</param> /// <param name="X_Init">优化变量初值</param> /// <param name="X_MaxStep">优化变量最大步长</param> /// <param name="X_Lb">优化变量下限</param> /// <param name="X_Ub">优化变量上限</param> /// <returns>使适应度函数最小的变量值</returns> /// <returns>最优目标函数</returns> public double[] StartOpt(string ConfigFile, double[] X_Init, double[] X_MaxStep, double[] X_Lb, double[] X_Ub, out double Fun, out double Delta) { if (X_Init.Length != X_MaxStep.Length || X_Init.Length != X_Lb.Length || X_Init.Length != X_Ub.Length) { throw new Exception("Variable number are not set correctly!"); } this.G = new General(); List <string[]> Config = new List <string[]>(); try { Config = G.ReadCSV(ConfigFile); this.Max_FEs = int.Parse(Config[0][1]); // 最大评价次数 this.Min_TolFun = double.Parse(Config[1][1]); // 结束条件 this.Step_Ratio = double.Parse(Config[2][1]); // 初始步长比 this.Epsilon = double.Parse(Config[3][1]); // 结束条件 this.Alpha = double.Parse(Config[4][1]); // 反射因子 this.Beta = double.Parse(Config[5][1]); // 收缩因子 this.Gamma = double.Parse(Config[6][1]); // 扩大因子 } catch (System.Exception ex) { throw new Exception("ConfigFile are not existed!"); } this.X_Dim = X_Init.Length; this.X = new double[X_Dim + 1, X_Dim]; // 变量 this.Delta = new double[X_Dim + 1]; // 约束违反度 this.X_Lb = new double[X_Dim]; this.X_Ub = new double[X_Dim]; this.X_Center = new double[X_Dim]; // 重心点 this.X_R = new double[X_Dim]; // 反射点 this.X_E = new double[X_Dim]; // 扩大点 this.X_C = new double[X_Dim]; // 收缩点 this.X_Opt = new double[X_Dim]; // 最优解 this.Step = new double[X_Dim]; // 步长 this.Fun = new double[X_Dim + 1]; // 目标值 for (int i = 0; i < X_Dim; i++) { this.X_Lb[i] = Math.Max(X_Init[i] - X_MaxStep[i], X_Lb[i]); this.X_Ub[i] = Math.Min(X_Init[i] + X_MaxStep[i], X_Ub[i]); this.Step[i] = (this.X_Ub[i] - this.X_Lb[i]) / this.Step_Ratio; this.X[0, i] = X_Init[i]; for (int j = 0; j < X_Dim; j++) { if (i == j) { this.X[j + 1, i] = X_Init[i] + Step[i]; this.X[j + 1, i] = G.BoundConstraint(this.X[j + 1, i], this.X_Lb[i], this.X_Ub[i]); } else { this.X[j + 1, i] = X_Init[i]; } } } Opt(); // 优化 Fun = Best_Fun; Delta = Best_Delta; return(X_Opt); }
/// <summary>this</summary> private void Opt() { double[] X_tmp = new double[X_Dim]; int FEs = 0; // 当前评价次数 // 上下限内初始化种群 Initial(); // 开始寻优 // 种群停止进化,结束优化流程 while (FEs < Max_FEs) { W = Wmax - FEs / Max_FEs * (Wmax - Wmin); // 选择个体 for (int i = 0; i < N_Pop; i++) { // 粒子i速度与位置更新 for (int k = 0; k < X_Dim; k++) { V[i, k] = W * V[i, k] + C1 * (pBest[i, k] - X[i, k]) + C2 * (gBest[k] - X[i, k]); V[i, k] = G.BoundConstraint(V[i, k], Vmin[k], Vmax[k]); X[i, k] = X[i, k] + V[i, k]; X[i, k] = G.BoundConstraint(X[i, k], X_Lb[k], X_Ub[k]); X_tmp[k] = X[i, k]; } Fun[i] = ObjectFunction(X_tmp, out Delta[i]); // 更新pBest if ((Delta[i] == gBest_Delta && Fun[i] < pBest_Fun[i]) || Delta[i] < pBest_Delta[i]) { for (int k = 0; k < X_Dim; k++) { pBest[i, k] = X[i, k]; } pBest_Fun[i] = Fun[i]; pBest_Delta[i] = Delta[i]; } // 更新gBest if ((Delta[i] == gBest_Delta && Fun[i] < gBest_Fun) || Delta[i] < gBest_Delta) { for (int k = 0; k < X_Dim; k++) { gBest[k] = X[i, k]; } gBest_Fun = Fun[i]; gBest_Delta = Delta[i]; } } if (FEs > 0) { TolFun = Math.Abs((Last_gBest_Fun - gBest_Fun) / Last_gBest_Fun); // 最优适应度变化 } Last_gBest_Fun = gBest_Fun; FEs = FEs + N_Pop; //if (TolFun < Min_TolFun) //{ // break; //} Console.WriteLine("PSO " + FEs + " " + gBest_Fun.ToString("f2") + " " + gBest_Delta.ToString("f2")); } // 得到最优解 for (int i = 0; i < X_Dim; i++) { X_Opt[i] = gBest[i]; } }
/// <summary> /// Nelder_Mead单纯形法 /// </summary> private void Opt() { var M = Matrix <double> .Build; Matrix <double> X_Matrix; // 解矩阵 int X_Rank = X_Dim; // 解矩阵的秩 double[] X_tmp = new double[X_Dim]; double SumEpsilon = 0.0; int FEs = 0; int iter = 0; Initial(); Out_Flag = false; X_Matrix = M.DenseOfArray(X).Transpose(); // 解矩阵 X_Rank = X_Matrix.Rank(); // 解矩阵的秩 while (FEs < Max_FEs && !Out_Flag) { // 计算最小点 Fun_Min = Fun[0]; Delta_Min = Delta[0]; Index_Min = 0; for (int i = 0; i < X_Dim + 1; i++) { if ((Delta[i] == Delta_Min && Fun[i] < Fun_Min) || Delta[i] < Delta_Min) { Fun_Min = Fun[i]; Delta_Min = Delta[i]; Index_Min = i; } } // 计算最大点 Fun_Max = Fun[0]; Delta_Max = Delta[0]; Index_Max = 0; for (int i = 0; i < X_Dim + 1; i++) { if ((Delta[i] == Delta_Max && Fun[i] > Fun_Max) || Delta[i] < Delta_Max) { Fun_Max = Fun[i]; Delta_Max = Delta[i]; Index_Max = i; } } // 计算次最大点 for (int i = 0; i < X_Dim + 1; i++) { if (i != Index_Max) { Index_SecMax = i; break; } } Fun_SecMax = Fun[Index_SecMax]; Delta_SecMax = Delta[Index_SecMax]; for (int i = 0; i < X_Dim + 1; i++) { if (i != Index_Max) { if ((Delta[i] == Delta_SecMax && Fun[i] > Fun_SecMax) || Delta[i] < Delta_SecMax) { Fun_SecMax = Fun[i]; Delta_SecMax = Delta[i]; Index_SecMax = i; } } } // 计算重心点 for (int i = 0; i < X_Dim; i++) { X_Center[i] = 0.0; for (int j = 0; j < X_Dim + 1; j++) { if (j != Index_Max) { X_Center[i] = X_Center[i] + X[j, i]; } } X_Center[i] = X_Center[i] / X_Dim; X_Center[i] = G.BoundConstraint(X_Center[i], this.X_Lb[i], this.X_Ub[i]); } Fun_Center = ObjectFunction(X_Center, out Delta_Center); FEs = FEs + 1; // 判断跳出 SumEpsilon = 0.0; for (int i = 0; i < X_Dim + 1; i++) { SumEpsilon = SumEpsilon + Math.Pow(Math.Pow(Fun[i] - Fun_Center, 2.0) / (X_Dim + 1), 0.5); } if (SumEpsilon < Epsilon) { Out_Flag = true; } if (!Out_Flag) { // 计算反射点 for (int i = 0; i < X_Dim; i++) { X_R[i] = X_Center[i] + Alpha * (X_Center[i] - X[Index_Max, i]); X_R[i] = G.BoundConstraint(X_R[i], this.X_Lb[i], this.X_Ub[i]); } Fun_R = ObjectFunction(X_R, out Delta_R); FEs = FEs + 1; if ((Delta_R == Delta_Min && Fun_R < Fun_Min) || Delta_R < Delta_Min) { // 计算扩大点 for (int i = 0; i < X_Dim; i++) { X_E[i] = X_Center[i] + Gamma * (X_R[i] - X_Center[i]); X_E[i] = G.BoundConstraint(X_E[i], this.X_Lb[i], this.X_Ub[i]); } Fun_E = ObjectFunction(X_E, out Delta_E); FEs = FEs + 1; if ((Delta_E == Delta_R && Fun_E < Fun_R) || Delta_E < Delta_R) { // 扩大点替换最大点 Fun[Index_Max] = Fun_E; Delta[Index_Max] = Delta_E; Fun_Max = Fun_E; Delta_Max = Delta_E; for (int i = 0; i < X_Dim; i++) { X[Index_Max, i] = X_E[i]; } } else { // 反射点替换最大点 Fun[Index_Max] = Fun_R; Delta[Index_Max] = Delta_R; Fun_Max = Fun_R; Delta_Max = Delta_R; for (int i = 0; i < X_Dim; i++) { X[Index_Max, i] = X_R[i]; } } } else if ((Delta_R == Delta_SecMax && Fun_R < Fun_SecMax) || Delta_R < Delta_SecMax) { // 反射点替换最大点 Fun[Index_Max] = Fun_R; Delta[Index_Max] = Delta_R; Fun_Max = Fun_R; Delta_Max = Delta_R; for (int i = 0; i < X_Dim; i++) { X[Index_Max, i] = X_R[i]; } } else if ((Delta_R == Delta_Max && Fun_R < Fun_Max) || Delta_R < Delta_Max) { // 反射点替换最大点 Fun[Index_Max] = Fun_R; Delta[Index_Max] = Delta_R; Fun_Max = Fun_R; Delta_Max = Delta_R; for (int i = 0; i < X_Dim; i++) { X[Index_Max, i] = X_R[i]; } // 计算收缩点 for (int i = 0; i < X_Dim; i++) { X_C[i] = X_Center[i] + Beta * (X[Index_Max, i] - X_Center[i]); X_C[i] = G.BoundConstraint(X_C[i], this.X_Lb[i], this.X_Ub[i]); } Fun_C = ObjectFunction(X_C, out Delta_C); FEs = FEs + 1; if ((Delta_C == Delta_Max && Fun_C < Fun_Max) || Delta_C < Delta_Max) { // 收缩点替换最大点 Fun[Index_Max] = Fun_C; Delta[Index_Max] = Delta_C; Fun_Max = Fun_C; Delta_Max = Delta_C; for (int i = 0; i < X_Dim; i++) { X[Index_Max, i] = X_C[i]; } } else { // 缩边 for (int i = 0; i < X_Dim + 1; i++) { if (i != Index_Min) { for (int j = 0; j < X_Dim; j++) { X[i, j] = X[Index_Min, j] + 0.5 * (X[i, j] - X[Index_Min, j]); X[i, j] = G.BoundConstraint(X[i, j], this.X_Lb[j], this.X_Ub[j]); X_tmp[j] = X[i, j]; } Fun[i] = ObjectFunction(X_tmp, out Delta[i]); FEs = FEs + 1; } } } } else { // 计算收缩点 for (int i = 0; i < X_Dim; i++) { X_C[i] = X_Center[i] + Beta * (X[Index_Max, i] - X_Center[i]); X_C[i] = G.BoundConstraint(X_C[i], this.X_Lb[i], this.X_Ub[i]); } Fun_C = ObjectFunction(X_C, out Delta_C); FEs = FEs + 1; if ((Delta_C == Delta_Max && Fun_C < Fun_Max) || Delta_C < Delta_Max) { // 收缩点替换最大点 Fun[Index_Max] = Fun_C; Delta[Index_Max] = Delta_C; Fun_Max = Fun_C; Delta_Max = Delta_C; for (int i = 0; i < X_Dim; i++) { X[Index_Max, i] = X_C[i]; } } else { // 缩边 for (int i = 0; i < X_Dim + 1; i++) { if (i != Index_Min) { for (int j = 0; j < X_Dim; j++) { X[i, j] = X[Index_Min, j] + 0.5 * (X[i, j] - X[Index_Min, j]); X[i, j] = G.BoundConstraint(X[i, j], this.X_Lb[j], this.X_Ub[j]); X_tmp[j] = X[i, j]; } Fun[i] = ObjectFunction(X_tmp, out Delta[i]); FEs = FEs + 1; } } } } } // 得到最优适应度 for (int i = 0; i < X_Dim + 1; i++) { if ((Delta[i] == Best_Delta && Fun[i] < Best_Fun) || Delta[i] < Best_Delta) { Best_Fun = Fun[i]; Best_Delta = Delta[i]; Best_Index = i; } } // 得到最优解 for (int i = 0; i < X_Dim; i++) { X_Opt[i] = X[Best_Index, i]; } if (iter > 0) { TolFun = Math.Abs((Last_Best_Fun - Best_Fun) / Last_Best_Fun); // 最优适应度相对变化 } iter = iter + 1; Last_Best_Fun = Best_Fun; // 上一步目标值 //if (TolFun < Min_TolFun) //{ // break; //} X_Matrix = M.DenseOfArray(X).Transpose(); // 解矩阵 X_Rank = X_Matrix.Rank(); // 解矩阵的秩 Console.WriteLine("Nelder_Mead " + FEs + " " + Best_Fun.ToString("f2") + " " + Best_Delta.ToString("f2") + " " + X_Rank.ToString()); } }
/// <summary> /// SBX与多项式变异 /// </summary> /// <param name="Index_Parent">父代个体编号</param> private void Variation(int[] Index_Parent) { object tmp; double x = 0.0; tmp = x; double beta; double mu; double k; double[] X_tmp = new double[X_Dim]; double[] Fun_tmp = new double[Obj_Dim]; double[,] X_Offspring_tmp = new double[Index_Parent.Length, X_Dim]; // SBX crossover for (int i = 0; i < Index_Parent.Length / 2; i++) { for (int j = 0; j < X_Dim; j++) { mu = G.rnd_uni(rd); if (mu <= 0.5) { beta = Math.Pow(2.0 * mu, (1.0 / (DisC + 1.0))); } else { beta = Math.Pow(2.0 - 2.0 * mu, (-1.0 / (DisC + 1.0))); } beta = beta * Math.Pow(-1, G.rndInt_uni(0, 1, rd)); if (G.rnd_uni(rd) > ProC) { beta = 1.0; } X_Offspring_tmp[i, j] = (X[Index_Parent[i], j] + X[Index_Parent[i + N_Pop / 2], j]) / 2 + beta * (X[Index_Parent[i], j] - X[Index_Parent[i + N_Pop / 2], j]) / 2; X_Offspring_tmp[i + Index_Parent.Length / 2, j] = (X[Index_Parent[i], j] + X[Index_Parent[i + N_Pop / 2], j]) / 2 - beta * (X[Index_Parent[i], j] - X[Index_Parent[i + N_Pop / 2], j]) / 2; } } // 多项式变异 for (int i = 0; i < X_Offspring.GetLength(0); i++) { for (int j = 0; j < X_Dim; j++) { k = G.rnd_uni(rd); mu = G.rnd_uni(rd); if (k <= ProM && mu < 0.5) { X_Offspring_tmp[i, j] = X_Offspring_tmp[i, j] + (X_Ub[j] - X_Lb[j]) * (Math.Pow(2.0 * mu + (1.0 - 2.0 * mu) * Math.Pow(1 - (X_Offspring_tmp[i, j] - X_Lb[j]) / (X_Ub[j] - X_Lb[j]), DisM + 1.0), 1.0 / (DisM + 1.0)) - 1.0); X_Offspring[i, j] = G.BoundConstraint(X_Offspring_tmp[i, j], X_Lb[j], X_Ub[j]); } else if (k <= ProM && mu >= 0.5) { X_Offspring_tmp[i, j] = X_Offspring_tmp[i, j] + (X_Ub[j] - X_Lb[j]) * (1 - Math.Pow(2.0 * (1.0 - mu) + 2.0 * (mu - 0.5) * Math.Pow(1 - (X_Ub[j] - X_Offspring_tmp[i, j]) / (X_Ub[j] - X_Lb[j]), DisM + 1.0), 1.0 / (DisM + 1.0))); X_Offspring[i, j] = G.BoundConstraint(X_Offspring_tmp[i, j], X_Lb[j], X_Ub[j]); } else { X_Offspring[i, j] = G.BoundConstraint(X_Offspring_tmp[i, j], X_Lb[j], X_Ub[j]); } X_tmp[j] = X_Offspring[i, j]; } Fun_tmp = ObjectFunction(X_tmp, out Delta_Offspring[i]); // 得到种群适应度和约束违反度 for (int j = 0; j < Obj_Dim; j++) { Fun_Offspring[i, j] = Fun_tmp[j]; } } }