C#,数值计算——一维数据的黄金分割(Golden Section Search in One Dimension)的计算方法与源程序

1 The Golden Section Search method

We derived the golden section search method today, see also the class notes

Derivation of the method of the golden section search to find the minimum of a function f(x) over the interval [a,b].

We assume

  • f(x) is continuous over [a,b] and
  • f(x) is "unimodal" over [a,b], meaning that f(x) has only one minimum in [a,b].

Note that the method applies as well to finding the maximum.

The conditions above remind us to the bisection method and we will apply a similar idea: narrow the interval that contains the minimum comparing function values.
In designing the method we seek to satisfy two goals:

  1. optimal reduction factor for the search interval;
  2. minimal number of function calls.

With these goals in mind we are going to determine the location to evaluate the function.

One choice inspired by the bisection method would be to compute the midpoint m = (a+b)/2 and to evaluate at x1 and x2, defined by x1 = m - eps/2 and x2 = m + eps/2, for some small value eps for which f(x1) /= f(x2). If f(x1) < f(x2), then we are left with [a,x1], otherwise [x2,b] is our new search interval. While this halves the search interval in each step, we must take two new function evaluation in each step. This is not optimal.

So we only want to perform one new function evaluation in each step. Furthermore, we want a constant reduction factor, say c, for the size of the interval.

我们今天推导出了黄金分割搜索方法,另请参阅课堂笔记

推导黄金分割搜索方法,以找到区间[a,b]上函数f(x)的最小值。

我们假设

f(x)在[a,b]上是连续的,并且

f(x)在[a,b]上是“单峰”的,这意味着f(x)在[a,b]中只有一个极小值。

请注意,该方法也适用于查找最大值。

上述条件提醒我们使用平分方法,我们将应用类似的想法:缩小包含最小比较函数值的区间。

在设计方法时,我们寻求满足两个目标:

搜索间隔的最佳缩减因子;

函数调用的最小数量。

考虑到这些目标,我们将确定评估功能的位置。

受平分法启发的一种选择是计算中点m=(a+b)/2,并在由x1=m-eps/2和x2=m+eps/2定义的x1和x2处对f(x1)/=f(x2)的一些小值eps进行评估。如果f(x1)<f(x2),那么我们剩下[a,x1],否则[x2,b]是我们的新搜索区间。虽然这将每一步的搜索间隔减半,但我们必须在每一步中进行两次新的函数评估。这不是最优的。

因此,我们只想在每个步骤中执行一个新的功能评估。此外,对于区间的大小,我们需要一个常数的折减因子,比如说c。

2 C#源代码

using System;

namespace Legalsoft.Truffer
{
    /// <summary>
    /// Golden Section Search in One Dimension
    /// </summary>
    public class Golden : Bracketmethod
    {
        //public delegateFunc func { get; set; } = null;

        public double xmin { get; set; }
        public double fmin { get; set; }
        public double tol { get; set; }

        public Golden(double toll = 3.0e-8)
        {
            this.tol = toll;
        }

        public double minimize(UniVarRealValueFun func)
        {
            const double R = 0.61803399;
            double C = 1.0 - R;
            double x1;
            double x2;
            double x0 = ax;
            double x3 = cx;
            if (Math.Abs(cx - bx) > Math.Abs(bx - ax))
            {
                x1 = bx;
                x2 = bx + C * (cx - bx);
            }
            else
            {
                x2 = bx;
                x1 = bx - C * (bx - ax);
            }
            double f1 = func.funk(x1);
            double f2 = func.funk(x2);
            while (Math.Abs(x3 - x0) > tol * (Math.Abs(x1) + Math.Abs(x2)))
            {
                if (f2 < f1)
                {
                    shft3(ref x0, ref x1, ref x2, R * x2 + C * x3);
                    shft2(ref f1, ref f2, func.funk(x2));
                }
                else
                {
                    shft3(ref x3, ref x2, ref x1, R * x1 + C * x0);
                    shft2(ref f2, ref f1, func.funk(x1));
                }
            }
            if (f1 < f2)
            {
                xmin = x1;
                fmin = f1;
            }
            else
            {
                xmin = x2;
                fmin = f2;
            }
            return xmin;
        }
    }
}
 

猜你喜欢

转载自blog.csdn.net/beijinghorn/article/details/132286385