/// <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);
        }
Beispiel #2
0
        /// <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];
                }
            }
        }