Esempio n. 1
0
 public void Write(GamePacketWriter writer)
 {
     writer.Write(Type, 2);
     Min.Write(writer);
     Lim.Write(writer);
     writer.Write(Radius);
 }
Esempio n. 2
0
 /// <summary>
 /// Initializes a new instance of the class.
 /// </summary>
 public CnlTag(int index, int cnlNum, Cnl cnl, Lim lim)
 {
     Index           = index;
     CnlNum          = cnlNum;
     Cnl             = cnl ?? throw new ArgumentNullException(nameof(cnl));
     Lim             = lim;
     LimCnlIndex     = null;
     CalcEngine      = null;
     CalcCnlDataFunc = null;
 }
Esempio n. 3
0
        public override Result Run(Params p)
        {
            if (p.Alfa.Size != 2)
            {
                throw new Exception("Дэвидон ошибка: интервал минимизации состоит не из двух точек");
            }
            f = p.Y;
            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];
            double AlfaD, gf;

            do
            {
                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 sqeareOmega = z * z - dfalfa1 * dfalfa2;
                //double omega = System.Math.Sqrt(/*System.Math.Abs(*/z * z - dfalfa1 * dfalfa2/*)*/);
                double omega = sqeareOmega > 0.0 ? System.Math.Sqrt(sqeareOmega) : Lim.Eps;
                double gamma = (z + omega - dfalfa1) / (dfalfa2 - dfalfa1 + 2.0 * omega);
                AlfaD = result.Alfas[0] + gamma * (result.Alfas[1] - result.Alfas[0]);
                gf    = Functions.Math.GF(f, X(x, AlfaD, P), P);

                if (Lim.CheckMinEps(gf) || Lim.CheckMinEps(result.Alfas[0], result.Alfas[1]))
                {
                    break;
                }

                if (gf > 0)
                {
                    result.Alfas[1] = AlfaD;
                }
                else
                {
                    result.Alfas[0] = AlfaD;
                }

                result.K++;
            } while (result.K < Lim.K);

            result.AlfaMin = (result.Alfas[1] + result.Alfas[0]) / 2.0;
            result.XMin    = X(x, result.AlfaMin, P);
            return(result);
        }
Esempio n. 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 = 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);
        }
Esempio n. 5
0
        /// <summary>
        /// Запуск на исполнение метода
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public override Result Run(Params p)
        {
            if (p.Alfa.Size != 2)
            {
                throw new Exception("Ошибка метода " + Name + ": интервал локализации не состоит из двух чисел во входных данных");
            }

            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 = cP.Y;

            double lambda = GoldenNumbers.LambdaGoldenSection(result.Alfas[0], result.Alfas[1]),
                   mu     = GoldenNumbers.MuGoldenSection(result.Alfas[0], result.Alfas[1]);

            while (result.K <= Lim.K)
            {
                Vector x1 = X(x, result.Alfas[0], P);
                Vector x2 = X(x, result.Alfas[1], P);
                if (f.Parse(x1) < f.Parse(x2))
                {
                    result.Alfas[1] = mu;
                    mu     = lambda;
                    lambda = GoldenNumbers.LambdaGoldenSection(result.Alfas[0], result.Alfas[1]);
                }
                else
                {
                    result.Alfas[0] = lambda;
                    lambda          = mu;
                    mu = GoldenNumbers.MuGoldenSection(result.Alfas[0], result.Alfas[1]);
                }
                if (Lim.CheckMinEps(x1, x2) &&
                    Lim.CheckMinEps(f.Parse(x1), f.Parse(x2)) &&
                    Lim.CheckMinEps(result.Alfas[0], result.Alfas[1]))
                {
                    break;
                }
                result.K++;
            }

            result.AlfaMin = (result.Alfas[1] + result.Alfas[0]) / 2.0;
            result.XMin    = X(x, result.AlfaMin, P);

            return(result);
        }
Esempio n. 6
0
 /// <summary>
 /// Sets the entity properties according to the controls.
 /// </summary>
 private void ControlsToEntity()
 {
     LimEntity = new Lim
     {
         LimID        = Convert.ToInt32(numLimID.Value),
         Name         = txtName.Text,
         IsBoundToCnl = chkIsBoundToCnl.Checked,
         IsShared     = chkIsShared.Checked,
         LoLo         = txtLoLo.Text == "" ? null : ScadaUtils.ParseDouble(txtLoLo.Text),
         Low          = txtLow.Text == "" ? null : ScadaUtils.ParseDouble(txtLow.Text),
         High         = txtHigh.Text == "" ? null : ScadaUtils.ParseDouble(txtHigh.Text),
         HiHi         = txtHiHi.Text == "" ? null : ScadaUtils.ParseDouble(txtHiHi.Text),
         Deadband     = txtDeadband.Text == "" ? null : ScadaUtils.ParseDouble(txtDeadband.Text)
     };
 }
Esempio n. 7
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);
        }
Esempio n. 8
0
        public override Result Run(Params p)
        {
            if (p.Alfa.Size != 2)
            {
                throw new Exception("Больцано ошибка: интервал минимизации состоит не из двух точек");
            }
            f = p.Y;
            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];

            double alfaK, gf;

            while (result.K <= Lim.K)
            {
                alfaK = (result.Alfas[0] + result.Alfas[1]) / 2.0;
                gf    = Functions.Math.GF(f, X(x, alfaK, P), P);
                if (Lim.CheckMinEps(result.Alfas[0], result.Alfas[1]) ||
                    Lim.CheckMinEps(gf))
                {
                    break;
                }
                if (gf > 0.0)
                {
                    result.Alfas[1] = alfaK;
                }
                else
                {
                    result.Alfas[0] = alfaK;
                }
                result.K++;
            }
            result.AlfaMin = (result.Alfas[1] + result.Alfas[0]) / 2.0;
            result.XMin    = X(x, result.AlfaMin, P);
            return(result);
        }
Esempio n. 9
0
        public override Result Run(Params p)
        {
            if (p.Alfa.Size != 2)
            {
                throw new Exception("Дихотомия ошибка: интервал минимизации состоит не из двух точек");
            }
            f = p.Y;
            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];

            double lambda_k, mu_k;
            double delta = 0.1 * Lim.Eps;

            while (result.K <= Lim.K || !Lim.CheckMinEps(result.Alfas[1], result.Alfas[0]))
            {
                lambda_k = (result.Alfas[1] + result.Alfas[0] - delta) / 2.0;
                mu_k     = (result.Alfas[1] + result.Alfas[0] + delta) / 2.0;
                if (f.Parse(X(x, lambda_k, P)) < f.Parse(X(x, mu_k, P)))
                {
                    result.Alfas[1] = mu_k;
                }
                else
                {
                    result.Alfas[0] = lambda_k;
                }
                result.K++;
            }

            result.AlfaMin = (result.Alfas[1] + result.Alfas[0]) / 2.0;
            result.XMin    = X(x, result.AlfaMin, P);
            return(result);
        }
Esempio n. 10
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);
        }
Esempio n. 11
0
        /// <summary>
        /// Запуск на исполнение метода
        /// </summary>
        /// <param name="parametrs"></param>
        /// <returns></returns>
        override public Result Run(Params p)
        {
            // Копирую входные данные
            Params cP = (Params)p.Clone();

            if (NormalizationDirections && cP.P.Norma > 1.0)
            {
                cP.P = cP.P.Rationing();
            }
            Result result = cP.ToResult();

            // устанавливаем функцию
            f = cP.Y;

            // производные по направлению
            double fd_k, fd_kp, fk, fkp;
            Vector x1 = result.ListX[0], x2, P = result.ListP[0];

            // вычисляем производную в начальной точке
            fd_k = Math.GF(f, x1, P);

            // Устанавливаем две точки интервала в ноль
            result.Alfas = new Vector();
            //double q = 2 * f.Parse(x1) / Math.GF(f, x1, P);
            result.Alfas.Push(/*(System.Math.Abs(q) < 1.0) ? q : */ 1.0);
            result.Alfas.Push(0.0);

            // меняем направление если функция возрастает
            if (fd_k > 0)
            {
                cP.H = -cP.H;
            }

            // Постепенно приближаемся к минимуму с заданной точностью
            while (result.K <= Lim.K)
            {
                // вычисляем новые данные
                result.Alfas[1] = result.Alfas[0] + cP.H;
                x2 = X(x1, result.Alfas[1], P);

                // находим производные в текущей и следующей точке
                fd_k  = Math.GF(f, x1, P);
                fd_kp = Math.GF(f, x2, P);
                fk    = f.Parse(x1);
                fkp   = f.Parse(x2);
                // проверяем критерий окончания поиска
                if (fd_kp * fd_k < 0.0 ||
                    fkp > fk ||
                    Lim.CheckMinEps(result.Alfas[0], result.Alfas[1]))
                {
                    // Если знаки разные, остановка
                    break;
                }
                // иначе ведем поиск дальше
                cP.H           *= 2;
                result.Alfas[0] = result.Alfas[1];
                x1 = x2;
                result.K++;
            }
            // Если нужно поменять направление интервала
            if (result.Alfas[0] >= result.Alfas[1])
            {
                // то меняем
                double t = result.Alfas[0];
                result.Alfas[0] = result.Alfas[1];
                result.Alfas[1] = t;
            }
            return(result);
        }
Esempio n. 12
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);
        }
Esempio n. 13
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);
        }
Esempio n. 14
0
        /// <summary>
        /// Запуск на исполнение метода
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public override Result Run(Params p)
        {
            if (p.Alfa.Size != 2)
            {
                throw new System.Exception("Error run method Powell: size alfa != 2");
            }

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

            if (NormalizationDirections && cP.P.Norma > 1.0)
            {
                cP.P = cP.P.Rationing();
            }
            Result result = cP.ToResult();

            // устанавливаем функцию
            f = cP.Y;

            double t = result.Alfas[1];

            result.Alfas[1] = (result.Alfas[0] + result.Alfas[1]) / 2.0;
            result.Alfas.Push(t);
            Vector x = result.ListX[0], P = result.ListP[0];

            double d = CalculatedRatios.First(f, x, P, result.Alfas);

            if (double.IsNaN(d) || double.IsInfinity(d))
            {
                return(result);
            }
            double fb = F(x, result.Alfas[1], P),
                   fd = F(x, d, P);

            while (result.K <= Lim.K)
            {
                if (result.Alfas[1] < d && fb < fd)
                {
                    result.Alfas[2] = d;
                }
                else if (result.Alfas[1] < d && fb > fd)
                {
                    result.Alfas[0] = result.Alfas[1];
                    result.Alfas[1] = d;
                }
                else if (result.Alfas[1] > d && fb < fd)
                {
                    result.Alfas[0] = d;
                }
                else if (result.Alfas[1] > d && fb > fd)
                {
                    result.Alfas[2] = result.Alfas[1];
                    result.Alfas[1] = d;
                }
                d = CalculatedRatios.Second(f, x, P, result.Alfas);
                Vector x1 = X(x, result.Alfas[1], P), x2 = X(x, d, P);
                fb = f.Parse(x1);
                fd = f.Parse(x2);
                if (Lim.CheckMinEps(result.Alfas[0], result.Alfas[1]) ||
                    Lim.CheckMinEps(x1, x2) ||
                    Lim.CheckMinEps(fb, fd))

                /*if (System.Math.Abs(1 - d / result.Alfas[1]) > Lim.Eps ||
                 *  System.Math.Abs(1 - fd / fb) > Lim.Eps)*/
                {
                    break;
                }
                result.K++;
            }
            if (result.Alfas[1] < d)
            {
                result.Alfas[0] = result.Alfas[1];
                result.Alfas[1] = d;
            }
            else
            {
                result.Alfas[0] = d;
            }
            result.Alfas.Remove(2);

            result.AlfaMin = (result.Alfas[1] + result.Alfas[0]) / 2.0;
            result.XMin    = X(x, result.AlfaMin, P);

            return(result);
        }
Esempio n. 15
0
        public override Result Run(Params p)
        {
            Params cP     = (Params)p.Clone();
            Result result = cP.ToResult();

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

            double H          = cP.H;
            bool   searchBest = false;
            Vector xkp;

            do
            {
                do
                {
                    // выполняем исследующий поиск
                    xkp = IP(result.GetLastX(), cP.H);
                    // если не улучшили
                    if (xkp.Equals(result.GetLastX()))
                    {
                        // то проверяем коп
                        if (Lim.CheckMinEps(cP.H))
                        {
                            break;
                        }
                        // иначе уменьшаем шаг
                        cP.H /= B;
                    }
                    else
                    {
                        // иначе говорим что нашли
                        searchBest = true;
                        result.ListX.Add(xkp);
                    }
                } while (!searchBest);

                // Если коп выполнился, то стоп
                if (!searchBest)
                {
                    break;
                }

                do
                {
                    // получаем образец
                    Vector xkpO = 2 * result.GetLastX() - result.ListX[result.ListX.Count - 2];
                    xkp = IP(xkpO, cP.H);

                    // Если нашли лучше
                    if (f.Parse(xkp) < f.Parse(result.GetLastX()))
                    {
                        // добавляем
                        result.ListX.Add(xkp);
                    }
                    else
                    {
                        break;
                    }
                } while (true);

                searchBest = false;
                result.K++;
            } while (result.K < Lim.K);

            result.XMin = result.GetLastX();

            return(result);
        }
Esempio n. 16
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);
        }
Esempio n. 17
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);
        }
Esempio n. 18
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);
        }