コード例 #1
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 g;

            do
            {
                g = Functions.Math.GF(f, cP.X0);
                if (NormalizationDirections && g.Norma > 1.0)
                {
                    g = g.Rationing();
                }
                if (result.K % n == 1)
                {
                    cP.P = -g;
                }
                else
                {
                    /// получаем сопряженный коэф направления
                    result.Betas.Push(ConjugateDirection.MethodPolakRibiere(g, -cP.P));
                    cP.P = -g + result.Betas.Last * cP.P;
                }
                result.ListP.Add(cP.P);

                Result resultMethods = MethodsUsed.Run(cP); /// поиск alfa_

                result.Alfas.Push(resultMethods.AlfaMin);   // сохранение коэф. для направления минимизации
                cP.X0 = X(cP.X0, result.Alfas.Last, cP.P);
                result.ListX.Add(cP.X0);
                result.K++;
                /// проверяем критерий Пауэлла
                if (!(g * cP.P <= 0.2 * g.Norma) || Lim.CheckMinEps(g * g) || Lim.CheckMinEps(result.ListX[result.ListX.Count - 1], result.ListX[result.ListX.Count - 2]))
                {
                    break;
                }
            } while (result.K < Lim.K);

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

            return(result);
        }
コード例 #2
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);
        }
コード例 #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 System.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();

            result.ListX = new System.Collections.Generic.List <Vector>()
            {
                null, null, null, null
            };
            result.ListP = new System.Collections.Generic.List <Vector>()
            {
                null, null, null, null
            };
            result.Alfas = new Vector(new double[4]);

            // получаем x1
            result.ListX[0] = cP.X0;
            do
            {
                int i = 0;
                //Шаг 1 получаем x2
                parMet.X0 = result.ListX[0];

                result.ListP[0] = -Math.GF(f, result.ListX[0]);
                if (NormalizationDirections && result.ListP[0].Norma > 1.0)
                {
                    result.ListP[0] = result.ListP[0].Rationing();
                }
                parMet.P = result.ListP[0];
                parMet.H = p.H;

                Result resultMethods = MethodsUsed.Run(parMet);
                result.Alfas[0] = resultMethods.AlfaMin;

                result.ListX[1] = X(result.ListX[0], result.Alfas[0], parMet.P);
                //Шаг 2 получаем x3, x4
                do
                {
                    // x3
                    parMet.X0 = result.ListX[1];

                    result.ListP[1] = -Math.GF(f, result.ListX[1]);
                    if (NormalizationDirections && result.ListP[1].Norma > 1.0)
                    {
                        result.ListP[1] = result.ListP[1].Rationing();
                    }
                    parMet.P = result.ListP[1];
                    parMet.H = p.H;

                    resultMethods   = MethodsUsed.Run(parMet);
                    result.Alfas[1] = resultMethods.AlfaMin;

                    result.ListX[2] = X(result.ListX[1], result.Alfas[1], parMet.P);
                    // x4
                    Vector d1 = result.ListX[2] - result.ListX[0];
                    result.Betas.Push(ConjugateDirection.MethodPolakRibiere(Math.GF(f, result.ListX[1]), Math.GF(f, result.ListX[0])));
                    result.ListX[3] = result.ListX[2] + result.Betas.Last * d1;
                    i++;
                    // Шаг 3
                    if (i < n - 1)
                    {
                        result.ListX[0] = result.ListX[1];
                        result.ListX[1] = result.ListX[3];
                    }
                } while (i < n - 1);
                if (Lim.CheckMinEps(result.ListX[3], cP.X0) || Lim.CheckMinEps(f.Parse(result.ListX[3]), f.Parse(cP.X0)))
                {
                    break;
                }
                cP.X0 = result.ListX[0] = result.ListX[3];
                result.K++;
            } while (result.K < Lim.K);

            result.XMin = cP.X0;

            //cP.X0 = xs[3];
            return(result);
        }
コード例 #5
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);
        }
コード例 #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);
        }