Ejemplo n.º 1
0
        public double GoldenSection(double[] X, double eps, double left, double right, double[] p)
        {
            double a = left, b = right, t, x1, x2, F1, F2;
            int    i = 0;

            t = 0.618;

            x1 = b - (b - a) * t;
            x2 = a + (b - a) * t;

            F1 = FunctionClass.Function2(X[0] + p[0], X[1] + p[1]);
            F2 = FunctionClass.Function2(X[0] + p[0], X[1] + p[1]);

            while (true)
            {
                i++;

                if (F1 <= F2)
                {
                    b  = x2;
                    x2 = x1;
                    F2 = F1;
                    x1 = b - (b - a) * t;
                    F1 = FunctionClass.Function2(X[0] + p[0], X[1] + p[1]);
                }
                else
                {
                    a  = x1;
                    x1 = x2;
                    F1 = F2;
                    x2 = a + (b - a) * t;
                    F2 = FunctionClass.Function2(X[0] + p[0], X[1] + p[1]);
                }

                if ((b - a) < eps)
                {
                    break;
                }
            }

            x1 = (a + b) / 2;

            if (x1 == left)
            {
                GoldenSection(X, eps, x1 - right + left, x1, p);
            }
            else if (x1 == right)
            {
                GoldenSection(X, eps, x1, x1 + right - left, p);
            }

            return(x1);
        }
Ejemplo n.º 2
0
        private void HookJeevesButton_Click(object sender, EventArgs e)
        {
            OutBox.Text = string.Empty;

            double eps  = Convert.ToDouble(EpsilonBox.Text); // Точность вычислений
            double step = Convert.ToDouble(StepBox.Text);    // Начальный шаг
            // Начальное приближение
            double x  = Convert.ToDouble(x0Box.Text);
            double y  = Convert.ToDouble(y0Box.Text);
            double y0 = FunctionClass.Function2(x, y);

            int    IterCount = 0;
            double fx;

            double lenght, y1, y2, y3, x1n, x2n, x1nn, x2nn;
            int    fl = 0;

            lenght = 1;

            do
            {
                fx           = FunctionClass.Function2(x, y);
                OutBox.Text += "x = " + Math.Round(x, 6).ToString() + "   y = " + Math.Round(y, 6).ToString() + "   f(x, y) = " + Math.Round(fx, 6).ToString() + "\r\n";

                fl = 0;
                y1 = FunctionClass.Function2(x + step, y);
                if (y1 < y0)
                {
                    x1n = x + step;
                }
                else
                {
                    y1 = FunctionClass.Function2(x - step, y);
                    if (y1 < y0)
                    {
                        x1n = x - step;
                    }
                    else
                    {
                        x1n = x;
                        y1  = y0;
                    }
                }
                y2 = FunctionClass.Function2(x1n, y + step);
                if (y2 < y1)
                {
                    x2n = y + step;
                }
                else
                {
                    y2 = FunctionClass.Function2(x1n, y - step);
                    if (y2 < y1)
                    {
                        x2n = y - step;
                    }
                    else
                    {
                        x2n = y;
                        y2  = y1;
                    }
                }
                if ((x1n == x) && (x2n == y))
                {
                    if (step > eps)
                    {
                        fl   = 1;
                        step = step / 2;
                    }
                }
                else
                {
                    fl = 1;
                    do
                    {
                        x1nn   = x1n + lenght * (x1n - x);
                        x2nn   = x2n + lenght * (x2n - y);
                        y3     = FunctionClass.Function2(x1nn, x2nn);
                        x      = x1nn;
                        y      = x2nn;
                        lenght = lenght * 0.5;
                    } while (y2 < y3);

                    IterCount++;
                    y0 = y3;
                }
            } while (fl == 1);

            fx                = FunctionClass.Function2(x, y);
            MinXBox.Text      = x.ToString();
            MinYBox.Text      = y.ToString();
            MinFBox.Text      = fx.ToString();
            IterCountBox.Text = IterCount.ToString();
        }
Ejemplo n.º 3
0
        private void BuildButton_Click(object sender, EventArgs e)
        {
            // Границы вычисления функции по осям X и Y
            double minX = Convert.ToDouble(MinXBox.Text);
            double maxX = Convert.ToDouble(MaxXBox.Text);
            double minY = Convert.ToDouble(MinYBox.Text);
            double maxY = Convert.ToDouble(MaxYBox.Text);
            // Масштаб
            double intervalX  = maxX - minX;
            double intervalY  = maxY - minY;
            double zoomX      = intervalX / bitmap.Width;          // 1 пиксель : 1 ед.измерения оси X
            double zoomY      = intervalY / bitmap.Height;         // 1 пиксель : 1 ед.измерения оси Y
            double eps        = Convert.ToDouble(EpsilonBox.Text); // Точность
            int    levelCount = Convert.ToInt32(LevelBox.Text);    // Количество линий уровня
            // Уровни
            int countX = Convert.ToInt32(bitmap.Width);
            int countY = Convert.ToInt32(bitmap.Height);

            double[,] values = new double[countX, countY]; // Сетка функции
            double[] levels = new double[levelCount];      // Уровни функции
            for (int i = 0; i < bitmap.Width; i++)
            {
                for (int j = 0; j < bitmap.Height; j++)
                {
                    double x = minX + i * zoomX;
                    double y = minY + j * zoomY;
                    double z = FunctionClass.Function2(x, y);

                    values[i, j] = z;
                }
            }
            double minValue = values[0, 0];  // Локальный минимум функции
            double maxValue = values[0, 0];  // Локальный максимум функции

            for (int i = 0; i < values.GetLength(0); i++)
            {
                for (int j = 0; j < values.GetLength(1); j++)
                {
                    if (values[i, j] < minValue)
                    {
                        minValue = values[i, j];
                    }

                    if (values[i, j] > maxValue)
                    {
                        maxValue = values[i, j];
                    }
                }
            }
            int levelStepX = bitmap.Width / levelCount / 2;
            int levelStepY = bitmap.Height / levelCount / 2;

            for (int i = 0; i < levelCount; i++)
            {
                levels[i] = values[i * levelStepX, i *levelStepY];
            }
            // Рисуем линии уровней
            ProgressBar.Value   = 0;
            ProgressBar.Maximum = bitmap.Width * bitmap.Height * levels.Length;

            for (int i = 0; i < bitmap.Width; i++)
            {
                for (int j = 0; j < bitmap.Height; j++)
                {
                    for (int k = 0; k < levels.Length; k++)
                    {
                        double x = minX + i * zoomX;
                        double y = minY + j * zoomY;
                        double z = FunctionClass.Function2(x, y);

                        if (z >= levels[k] - eps && z <= levels[k] + eps)
                        {
                            int c = (int)(255 * Math.Abs(z - levels[k]) / eps);
                            DrawPoint(i, bitmap.Height - j - 1, Color.FromArgb(c, c, c));
                        }

                        ProgressBar.Value++;
                    }
                }
            }
        }
Ejemplo n.º 4
0
        private void GaussButton_Click(object sender, EventArgs e)
        {
            OutBox.Text = string.Empty;

            double eps  = Convert.ToDouble(EpsilonBox.Text); // Точность вычислений
            double step = Convert.ToDouble(StepBox.Text);    // Начальный шаг
            // Начальное приближение
            double x = Convert.ToDouble(x0Box.Text);
            double y = Convert.ToDouble(y0Box.Text);

            int    IterCount = 0;
            double fx, prevX, prevY, curX = x, curY = y;
            double leftBorder, rightBorder;
            double x1, xm, x2;
            double y1, ym, y2;
            double z1, zm, z2;

            do
            {
                IterCount++;

                prevX = curX;
                prevY = curY;

                // По 1 координате
                leftBorder  = prevX - step;
                rightBorder = prevX + step;

                x1 = leftBorder + (rightBorder - leftBorder) / 4;
                xm = (leftBorder + rightBorder) / 2;
                x2 = rightBorder - (rightBorder - leftBorder) / 4;

                z1 = FunctionClass.Function2(x1, prevY);
                zm = FunctionClass.Function2(xm, prevY);
                z2 = FunctionClass.Function2(x2, prevY);

                while (Math.Abs(rightBorder - leftBorder) > eps)
                {
                    if ((z1 > zm) && (zm < z2))
                    {
                        leftBorder  = x1;
                        rightBorder = x2;

                        x1 = leftBorder + (rightBorder - leftBorder) / 4;
                        x2 = rightBorder - (rightBorder - leftBorder) / 4;
                    }
                    else if ((z1 > zm) && (zm > z2))
                    {
                        leftBorder = xm;

                        x1 = leftBorder + (rightBorder - leftBorder) / 4;
                        x2 = rightBorder - (rightBorder - leftBorder) / 4;
                        xm = (leftBorder + rightBorder) / 2;

                        zm = FunctionClass.Function2(xm, prevY);
                    }
                    else if ((z1 < zm) && (zm < z2))
                    {
                        rightBorder = xm;

                        x1 = leftBorder + (rightBorder - leftBorder) / 4;
                        x2 = rightBorder - (rightBorder - leftBorder) / 4;
                        xm = (leftBorder + rightBorder) / 2;

                        zm = FunctionClass.Function2(xm, prevY);
                    }

                    z1 = FunctionClass.Function2(x1, prevY);
                    z2 = FunctionClass.Function2(x2, prevY);
                }

                curX = (leftBorder + rightBorder) / 2;

                // По 2 координате
                leftBorder  = prevY - step;
                rightBorder = prevY + step;

                y1 = leftBorder + (rightBorder - leftBorder) / 4;
                ym = (leftBorder + rightBorder) / 2;
                y2 = rightBorder - (rightBorder - leftBorder) / 4;

                z1 = FunctionClass.Function2(curX, y1);
                zm = FunctionClass.Function2(curX, ym);
                z2 = FunctionClass.Function2(curX, y2);

                while (Math.Abs(rightBorder - leftBorder) > eps)
                {
                    if ((z1 > zm) && (zm < z2))
                    {
                        leftBorder  = y1;
                        rightBorder = y2;

                        y1 = leftBorder + (rightBorder - leftBorder) / 4;
                        y2 = rightBorder - (rightBorder - leftBorder) / 4;
                    }
                    else if ((z1 > zm) && (zm > z2))
                    {
                        leftBorder = ym;

                        y1 = leftBorder + (rightBorder - leftBorder) / 4;
                        y2 = rightBorder - (rightBorder - leftBorder) / 4;
                        ym = (leftBorder + rightBorder) / 2;

                        zm = FunctionClass.Function2(curX, ym);
                    }
                    else if ((z1 < zm) && (zm < z2))
                    {
                        rightBorder = ym;

                        y1 = leftBorder + (rightBorder - leftBorder) / 4;
                        y2 = rightBorder - (rightBorder - leftBorder) / 4;
                        ym = (leftBorder + rightBorder) / 2;

                        zm = FunctionClass.Function2(curX, ym);
                    }

                    z1 = FunctionClass.Function2(curX, y1);
                    z2 = FunctionClass.Function2(curX, y2);
                }

                curY = (leftBorder + rightBorder) / 2;
            }while (Math.Abs(FunctionClass.Function2(curX, curY) - FunctionClass.Function2(prevX, prevY)) > eps);

            fx                = FunctionClass.Function2(curX, curY);
            MinXBox.Text      = curX.ToString();
            MinYBox.Text      = curY.ToString();
            MinFBox.Text      = fx.ToString();
            IterCountBox.Text = IterCount.ToString();
        }
Ejemplo n.º 5
0
        private void NewtonButton_Click(object sender, EventArgs e)
        {
            OutBox.Text = string.Empty;

            // Шаг 1
            int    k = 0;  // Счетчик итераций
            double x0, y0; // Начальное приближение
            double a = 1;  // Шаг для модифицированного метода

            x0  = Convert.ToDouble(x0Box.Text);
            y0  = Convert.ToDouble(y0Box.Text);
            eps = Convert.ToDouble(EpsilonBox.Text);
            //a = Convert.ToDouble(StepBox.Text);

            double x = x0, y = y0;                     // Текущая точка

            double[] grad = new double[2];             // Градиент
            double [,] matrix      = new double[2, 2]; // Матрица Гессе
            double[,] invertMatrix = new double[2, 2]; // Обратная матрица Гессе
            double[] p         = new double[2];        // Направление спуска
            double[] curPoint  = new double[2];        // Текущая точка
            double[] nextPoint = new double[2];        // Следущая точка

calculate:

            OutBox.Text += "Итерация № " + k.ToString() + "\r\n" +
                           "Текущая точка (" + x + ", " + y + ")\r\n" +
                           "Значение функции в точке " + FunctionClass.Function2(x, y) + "\r\n";

            // Вычисляем градиент
            grad         = GetGrad(x, y);
            OutBox.Text += "Градиент\r\n (" + grad[0] + ", " + grad[1] + ")\r\n";

            // Вычисляем матрицу Гессе
            matrix       = GetHesse(x, y);
            OutBox.Text += "Матрица Гессе\r\n" +
                           "| " + matrix[0, 0] + " | " + matrix[0, 1] + " |\r\n" +
                           "| " + matrix[1, 0] + " | " + matrix[1, 1] + " |\r\n";
            // Шаг 2
            // Определяем обратную матрицу
            invertMatrix = InvertMatrix(matrix);
            if (invertMatrix == null)
            {
                return;
            }
            OutBox.Text += "Обратная матрица Гессе\r\n" +
                           "| " + invertMatrix[0, 0] + " | " + invertMatrix[0, 1] + " |\r\n" +
                           "| " + invertMatrix[1, 0] + " | " + invertMatrix[1, 1] + " |\r\n";

            // Шаг 3
            // Определяем направление спуска
            p            = GetDirect(grad, invertMatrix);
            OutBox.Text += "Направление спуска\r\n (" + p[0] + ", " + p[1] + ")\r\n";

            // Шаг 4
            // Определяем следующую точку
            curPoint[0] = x;
            curPoint[1] = y;
            //a = GoldenSection(curPoint, eps, -10, 10, p);
            nextPoint    = GetNextPoint(curPoint, a, p);
            OutBox.Text += "Новая точка (" + nextPoint[0] + ", " + nextPoint[1] + ")\r\n";

            // Шаг 5
            // Вычисление в новой точке градиента
            grad = GetGrad(nextPoint[0], nextPoint[1]);

            // Шаг 6
            // Если точность не достигнута, то продолжаем итерации
            x = nextPoint[0];
            y = nextPoint[1];

            if ((Math.Sqrt(grad[0] * grad[0] + grad[1] * grad[1]) > eps && Math.Abs(FunctionClass.Function2(curPoint[0], curPoint[1]) - FunctionClass.Function2(nextPoint[0], nextPoint[1])) > eps))
            {
                k++;
                OutBox.Text += "________________________________\r\n";
                goto calculate;
            }

            double f = FunctionClass.Function2(x, y);

            OutBox.Text += "*************************************\r\n" +
                           "Минимум функции равен " + f + "\r\n" +
                           "в точке (" + x + ", " + y + ")\r\n";

            MinXBox.Text      = x.ToString();
            MinYBox.Text      = y.ToString();
            MinFBox.Text      = f.ToString();
            IterCountBox.Text = (k + 1).ToString();
        }
Ejemplo n.º 6
0
 public double GetDfDy(double _x, double _y)
 {
     return((FunctionClass.Function2(_x, _y + Math.Pow(eps, 2)) - FunctionClass.Function2(_x, _y)) / Math.Pow(eps, 2));
 }