private void btnCalc_Click(object sender, EventArgs e)
        {
            Point2D x0, h;
            double  eps = 0, x0x = 0, x0y = 0, hx = 0, hy = 0;
            Point2D res;

            //Парсинг параметров
            try
            {
                x0x = double.Parse(txtX0X.Text);
                x0y = double.Parse(txtX0Y.Text);
                hx  = double.Parse(txtHX.Text);
                hy  = double.Parse(txtHY.Text);
                eps = double.Parse(txtEps.Text);
            }
            catch (FormatException exp)
            {
                MessageBox.Show("Неверный ввод - не число");
                return;
            }

            x0 = new Point2D(x0x, x0y);
            h  = new Point2D(hx, hy);

            //Определяем функцию
            Func <double, double, double> f;

            if (rbTest.Checked)
            {
                f = test;
            }
            else
            {
                f = task211;
            }

            //Вычисление
            if (rbGZ.Checked)
            {
                res = GaussZeidelMethod.FindMinimum(f, x0, h, eps);
            }
            else
            {
                res = HookJeevesMethod.FindMinimum(f, x0, h, eps);
            }

            txtOut.Text = res.ToString(OptimizationUtils.GetFormat(eps));
        }
Exemple #2
0
        /// <summary>
        /// Осуществляет оптимизацию многомерной функции методом Гаусса-Зейделя
        /// </summary>
        /// <param name="f">Минимизируемая функция</param>
        /// <param name="x0">начальной точки посика</param>
        /// <param name="interval">интервалы поиска</param>
        /// <param name="h">Векор положительных приращений координат</param>
        /// <param name="eps0">Точность</param>
        /// <returns></returns>
        public static Point2D FindMinimum(Func <double, double, double> f, Point2D x0, Point2D h, double eps0)
        {
            /*Стоило бы сделать поддержку функций многих переменных (N>2), но тут трудности в преобразовании
             * Func<double[], double> -> Func<double, double>*/

            double finder_h  = 0.05;                    //Шаг поиска отрезка минимума
            double z         = 0.1;                     //Уменьшение шага поиска
            double equal_eps = eps0;                    //Совпадение

            Point2D x = new Point2D(0, 0);
            Func <double, double> f_fixed;
            Interval interval;
            double   ak;

            Logger.Write("===> Минимизация методом Гаусса-Зейделя <==");
            Logger.WriteContinue(" |Начальная точка x0: {0}", x0);
            Logger.WriteContinue(" |Шаг h: {0} ", h);
            Logger.WriteContinue(" |Точность eps: {0} ", eps0);


            string format = OptimizationUtils.GetFormat(eps0 / 10);

            do
            {
                do
                {
                    x0.X = x.X;
                    x0.Y = x.Y;

                    Logger.Write("Минимазация по каждой координате");
                    //Поочередная минимизация по каждой координате
                    //X
                    Logger.WriteContinue("X:");
                    f_fixed  = a => f(x0.X + a * h.X, x0.Y);
                    interval = IntervalFinder.Find(x0.X, finder_h, f_fixed);
                    ak       = GoldenRatioMethod.FindMinimum(interval, f_fixed, eps0 / 5);
                    x.X      = x0.X + ak * h.X;
                    Logger.WriteContinue("  3. ak = {0:" + format + "}", ak);
                    Logger.WriteContinue("  4. x[k+1].X=x[k].X + ak*h.X = {0:" + format + "} + {1:" + format + "} * {2:" + format + "} = {3:" + format + "}", x0.X, ak, h.X, x.X);

                    //Y
                    Logger.WriteContinue("Y");
                    f_fixed  = a => f(x.X, x0.Y + a * h.Y);
                    interval = IntervalFinder.Find(x0.Y, finder_h, f_fixed);
                    ak       = GoldenRatioMethod.FindMinimum(interval, f_fixed, eps0 / 5);
                    x.Y      = x0.Y + ak * h.Y;
                    Logger.WriteContinue("  3. ak = {0:" + format + "}", ak);
                    Logger.WriteContinue("  4. x[k+1].Y=x[k].Y + ak*h.Y = {0:" + format + "} + {1:" + format + "} * {2:" + format + "} = {3:" + format + "}", x0.Y, ak, h.Y, x.Y);
                }while (!check_equal(x0, x, equal_eps));
                Logger.Write("x[k+1]==x[k]");
                var h0 = h;

                if (OptimizationUtils.EuclidNorm(h) <= eps0)
                {
                    break;
                }

                //Уменьшаем шаг
                h.X = z * h.X;
                h.Y = z * h.Y;

                Logger.WriteContinue("9. Уменьшаем шаг: h = {0:" + format + "} * {1:" + format + "} = {2:" + format + "}", z, h0, h);
                Logger.WriteContinue("Переход на шаг 3");
            } while (true);

            Logger.Write("||h|| = {0:" + format + "} < eps", OptimizationUtils.EuclidNorm(h));
            Logger.Write("Минимум найден: {0:" + format + "}", x);

            return(x);
        }