コード例 #1
0
        /// <summary>
        /// Запуск на исполнение метода
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        override public Result Run(Params p)
        {
            if (MethodsUsed == null)
            {
                throw new System.Exception("Ошибка метода " + Name + ": не определены методы, которые будет использованны");
            }
            Params cP     = (Params)p.Clone();
            Result result = cP.ToResult();

            result.ListP.Clear();
            // устанавливаем функцию
            f = p.Y;

            // параметры для поиска минимума на k-ом шаге
            Params pSerch = (Params)p.Clone();

            while (result.K <= Lim.K)
            {
                pSerch.X0 = result.ListX[result.ListX.Count - 1];
                pSerch.H  = cP.H;
                // получаю направление
                pSerch.P = -Functions.Math.GF(cP.Y, pSerch.X0);
                if (NormalizationDirections && pSerch.P.Norma > 1.0)
                {
                    pSerch.P = pSerch.P.Rationing();
                }
                result.ListP.Add(pSerch.P);
                // получаю шаг до минимума
                Result resultMethods = MethodsUsed?.Run(pSerch);
                result.Alfas.Push(resultMethods.AlfaMin);
                // получаю следующий вектор
                result.ListX.Add(pSerch.X0 + result.Alfas.Last * pSerch.P);
                // проверяю коп
                if (Lim.CheckMinEps(result.ListX[result.ListX.Count - 1], result.ListX[result.ListX.Count - 2]) &&
                    Lim.CheckNorma(pSerch.P) &&
                    Lim.CheckMinEps(f.Parse(result.ListX[result.ListX.Count - 1]), f.Parse(result.ListX[result.ListX.Count - 2])))
                {
                    break;
                }
                result.K++;
            }

            result.XMin = result.ListX[result.ListX.Count - 1];

            return(result);
        }
コード例 #2
0
        public override Result Run(Params p)
        {
            Params cP     = (Params)p.Clone();
            Result result = cP.ToResult();

            result.ListP.Clear();
            // устанавливаем функцию
            f = p.Y;

            Vector gfk = Functions.Math.GF(f, result.GetLastX());

            do
            {
                // Шаг 1
                Matrix hessian = Functions.Math.GetMatrixHessianInPoint(f, result.GetLastX());
                Vector P       = Functions.Math.GetTheSolutionOfTheSystem(hessian, -gfk);
                if (NormalizationDirections && P.Norma > 1.0)
                {
                    P = P.Rationing();
                }
                result.ListP.Add(P);
                //Шаг 2
                result.ListX.Add(X(result.GetLastX(), alfa, result.GetLastP()));
                // Шаг 3
                gfk = Functions.Math.GF(f, result.GetLastX());
                if (Lim.CheckNorma(result.GetLastP()) || Lim.CheckNorma(gfk))
                {
                    break;
                }
                result.K++;
            } while (result.K < Lim.K);

            result.XMin = result.GetLastX();

            return(result);
        }
コード例 #3
0
        public override Result Run(Params p)
        {
            if (MethodsUsed == null)
            {
                throw new System.Exception("Ошибка метода " + Name + ": не определены методы, которые будет использованны");
            }
            Params cP     = (Params)p.Clone();
            Result result = cP.ToResult();

            result.ListP.Clear();
            // устанавливаем функцию
            f = p.Y;

            int n = p.Y.Vars.Count;

            Vector mu = new Vector();

            // множество направлений пи и мю
            for (int i = 0; i < n; i++)
            {
                result.ListP.Add(Vector.GetZeroBeside(n, i));
                mu.Push(0);
                result.Alfas.Push(0);
                result.ListX.Add(null);
            }

            Params usesParam = (Params)cP.Clone();

            while (result.K <= Lim.K)
            {
                // формируем массив альфа, мю, иксов
                for (int i = 0; i < n; i++)
                {
                    usesParam.P         = result.ListP[i];
                    usesParam.X0        = result.ListX[i];
                    usesParam.H         = cP.H;
                    result.Alfas[i]     = (MethodsUsed.Run(usesParam).AlfaMin);
                    result.ListX[i + 1] = X(usesParam.X0, result.Alfas[i], usesParam.P);
                    mu[i] = f.Parse(result.ListX[i]) - f.Parse(result.ListX[i + 1]);
                }
                // получаем направляющий вектор
                Vector dk = result.ListX[n] - result.ListX[0];
                // нормируем
                dk = dk.Rationing();

                usesParam.P  = dk;
                usesParam.X0 = result.ListX[n];
                usesParam.H  = cP.H;
                // вычисляю следующую точку
                double alfa = MethodsUsed.Run(usesParam).AlfaMin;
                Vector xnpp = result.GetLastX() + alfa * dk;

                double y1 = f.Parse(result.ListX[0]), ynp = f.Parse(result.ListX[n]), ynpp = f.Parse(xnpp);
                if (Lim.CheckNorma(dk) || Lim.CheckMinEps(alfa) || Lim.CheckNorma(Functions.Math.GF(f, xnpp)) || Lim.CheckMinEps((ynp - ynpp) / ynp))
                {
                    result.ListX.Add(xnpp);
                    break;
                }
                // получаем индекс максимального мю
                int indexMax = mu.GetIndexMaxElem();
                // Меняем систему направлений
                if (4 * mu[indexMax] * (ynp - ynpp) >= (y1 - ynp - mu[indexMax]) * (y1 - ynp - mu[indexMax]))
                {
                    // если условие перспективности выполнелось, то сдвигаем начиная с i-ого
                    for (int i = indexMax; i < n - 1; i++)
                    {
                        result.ListP[i] = result.ListP[i + 1];
                    }
                    result.ListP[indexMax] = dk;
                }
                else
                {
                    for (int i = 0; i < n - 1; i++)
                    {
                        result.ListP[i] = result.ListP[i + 1];
                    }
                    result.ListP[n - 1] = dk;
                }

                result.K++;
            }

            result.XMin = result.GetLastX();

            return(result);
        }
コード例 #4
0
        public override Result Run(Params p)
        {
            // проверка переданных методов
            if (MethodsUsed == null)
            {
                throw new Exception("Ошибка метода " + Name + ": не определены методы, которые будет использованны");
            }
            // клонирование входных параметров в выходные
            Params cP     = (Params)p.Clone();
            Result result = cP.ToResult();

            result.ListP.Clear();
            // устанавливаем функцию
            f = p.Y;
            int    n      = cP.Y.Vars.Count; // количество переменных
            Params parMet = (Params)cP.Clone();

            do
            {
                for (int i = 1; i <= n; i++)
                {
                    if (result.ListX.Count != n + 1)
                    {
                        result.ListP.Add(-Functions.Math.GF(f, result.ListX[i - 1])[i - 1] * Vector.GetZeroBeside(n, i - 1));
                    }
                    else
                    {
                        result.ListP[i - 1] = -Functions.Math.GF(f, result.ListX[i - 1])[i - 1] * Vector.GetZeroBeside(n, i - 1);
                    }
                    if (NormalizationDirections && result.ListP[i - 1].Norma > 1.0)
                    {
                        result.ListP[i - 1] = result.ListP[i - 1].Rationing();
                    }
                    parMet.X0 = result.ListX[i - 1];
                    parMet.P  = result.ListP[i - 1];
                    parMet.H  = cP.H;
                    Result resultMethods = MethodsUsed?.Run(parMet);
                    result.Alfas.Push(resultMethods.AlfaMin);
                    if (result.ListX.Count != n + 1)
                    {
                        result.ListX.Add(parMet.X0 + resultMethods.AlfaMin * parMet.P);
                    }
                    else
                    {
                        result.ListX[i] = parMet.X0 + resultMethods.AlfaMin * parMet.P;
                    }
                }
                Vector d = result.ListX[n] - result.ListX[0];
                if (Lim.CheckMinEps(f.Parse(result.ListX[0]), f.Parse(result.ListX[n])) ||
                    Lim.CheckMinEps(result.ListX[0], result.ListX[n]) ||
                    Lim.CheckNorma(d))
                {
                    break;
                }
                result.ListX[0] = result.ListX[n];
                result.K++;
            } while (result.K < Lim.K);

            result.XMin = result.ListX[result.ListX.Count - 1];

            return(result);
        }
コード例 #5
0
        public override Result Run(Params p)
        {
            if (p.Alfa.Size != 2)
            {
                throw new Exception(Name + " вектор альф не имеет 2 элемента");
            }
            // Скопирвоать входные параметры для изменения
            Params cP = (Params)p.Clone();

            if (NormalizationDirections && cP.P.Norma > 1.0)
            {
                cP.P = cP.P.Rationing();
            }
            Result result = cP.ToResult();
            Vector x = result.ListX[0], P = result.ListP[0];

            // утановить функцию
            f = p.Y;
            // основной этап
            do
            {
                // шаг 1 вычислить gamma
                double alfa_;
                Vector xalfa1  = X(x, result.Alfas[0], P);
                Vector xalfa2  = X(x, result.Alfas[1], P);
                double dfalfa1 = Functions.Math.GF(f, xalfa1, P);
                double dfalfa2 = Functions.Math.GF(f, xalfa2, P);
                double z       = dfalfa1 + dfalfa2 + 3.0 * (f.Parse(xalfa1) - f.Parse(xalfa2)) / (result.Alfas[1] - result.Alfas[0]);
                double omega   = System.Math.Sqrt(z * z - dfalfa1 * dfalfa2);
                double gamma   = (z + omega - dfalfa1) / (dfalfa2 - dfalfa1 + 2.0 * omega);
                if (gamma < 0.0)
                {
                    alfa_ = result.Alfas[0];
                }
                else if (gamma > 1.0)
                {
                    alfa_ = result.Alfas[1];
                }
                else
                {
                    alfa_ = result.Alfas[0] + gamma * (result.Alfas[1] - result.Alfas[0]);
                }
                // шаг 2 проверить коп
                Vector gfalfa_V = Functions.Math.GF(f, X(x, alfa_, P));
                if (Lim.CheckMinEps(Functions.Math.GF(f, X(x, alfa_, P), P)) ||
                    Lim.CheckNorma(gfalfa_V) ||
                    alfa_ == result.Alfas[0] ||
                    alfa_ == result.Alfas[1])
                {
                    result.AlfaMin = alfa_;
                    break;
                }
                double gfalfa_ = Functions.Math.GF(f, X(x, alfa_, P), P);
                if (gfalfa_ > 0.0)
                {
                    result.Alfas[1] = alfa_;
                }
                else
                {
                    result.Alfas[0] = alfa_;
                }
                result.K++;
            } while (result.K < Lim.K);

            if (!double.IsNaN(result.AlfaMin))
            {
                result.XMin = X(x, result.AlfaMin, P);
            }

            return(result);
        }
コード例 #6
0
        public override Result Run(Params p)
        {
            if (MethodsUsed == null)
            {
                throw new System.Exception("Ошибка метода " + Name + ": не определены методы, которые будет использованны");
            }
            Params cP     = (Params)p.Clone();
            Result result = cP.ToResult();

            result.ListP.Clear();
            // устанавливаем функцию
            f = p.Y;

            Params usesParams = (Params)cP.Clone();

            Matrix A = null;
            int    n = f.Vars.Count;
            Vector gk = null, gkm = null;

            do
            {
                // Шаг 1 найти матрицу переменной метрики
                gk = Functions.Math.GF(f, result.GetLastX());
                if (result.K % n == 1)
                {
                    // единичная матрица
                    A = Matrix.GetIdentity(n);
                }
                else
                {
                    Vector gammak   = gk - gkm;
                    Vector skm      = A * gammak;
                    Vector deltaxkm = result.GetLastX() - result.ListX[result.ListX.Count - 2];
                    A = Metrics.RunMetric?.Invoke(A, gammak, skm, deltaxkm);
                }
                // Шаг 2 поиск направления поиска
                Vector P = -A * gk;
                if (NormalizationDirections && P.Norma > 1.0)
                {
                    P = P.Rationing();
                }
                result.ListP.Add(P);

                usesParams.X0 = result.GetLastX();
                usesParams.P  = result.GetLastP();
                usesParams.H  = cP.H;
                //Шаг 3 получение альфа
                result.Alfas.Push(MethodsUsed.Run(usesParams).AlfaMin);
                // Шаг 4 получение новой точки
                result.ListX.Add(X(result.GetLastX(), result.Alfas.Last, result.GetLastP()));
                // Шаг 3
                Vector gkmprev = gkm;
                gkm = Functions.Math.GF(f, result.GetLastX());
                if (Lim.CheckNorma(result.GetLastP()) ||
                    Lim.CheckNorma(gkm) ||
                    Lim.CheckNorma(gkm) ||
                    Lim.CheckMinEps(result.GetLastX(), result.ListX[result.ListX.Count - 2]) ||
                    Lim.CheckMinEps(result.GetLastX(), result.ListX[0]))
                {
                    break;
                }
                gkm = gk;
                result.K++;
            } while (result.K < Lim.K);

            result.XMin = result.GetLastX();

            return(result);
        }