黄金分割法与Fibonacci法

来源:互联网 发布:本地连接虚拟机数据库 编辑:程序博客网 时间:2024/06/10 01:58

最近在上一门最优化算法的课,于是就打算写一篇博客来将自己所学的知识做一个巩固,这两种方法都是用来选取函数的极值点,属于的一维搜索方法中的试探法,方式也是很简单那就是在值域[a,b]内选取两个点,通过两个值的函数值来缩小值域的取值范围

下面我们来看一下用两种方法,怎么求出函数这里写图片描述在区间[0,1]内的极大值点,容许误差为106,函数图像呢如下:
这里写图片描述
斐波那契法:

var     golbal = {        cache: {            "1" : 1,            "2" : 1        },        a: 0,        b: 1    },    e = Math.E,    sin = Math.sin,    tan = Math.tan,    pow = Math.pow,    Fibonacci = function () {        return function (n) {            if (golbal.cache.hasOwnProperty(n)) {                return golbal.cache[n];            } else {                golbal.cache[n] = Fibonacci(n - 1) + Fibonacci(n - 2);                return golbal.cache[n];            }        }    }(),    getN = function (deviation) {        var fn = Math.round(1 / deviation),         n = 1;        while (fn > Fibonacci(n)) {            n++;        }         return n;    },    N = getN(Math.pow(10, -6)),    getT1 = function (max, min, k) {        return max + golbal.cache[N - k] / golbal.cache[N - k + 1] * (min - max);      },    getT2 = function (max, min, k) {        return min + golbal.cache[N - k] / golbal.cache[N - k + 1] * (max - min);      },    fn = function (x) {        return -( pow(sin(x), 6) * tan(1- x) * pow(e, 20 * x) );    },    t1 = getT1(golbal.b, golbal.a, 1),    t2 = getT2(golbal.b, golbal.a, 1); for (var i = 2; i < N - 1; i++) {    if ( fn( t1 ) < fn( t2 ) ) {        golbal.b = t2;        t2 = t1;        t1 = getT1(golbal.b, golbal.a, i);    } else {        golbal.a = t1;        t1 = t2;        t2 = getT2(golbal.b, golbal.a, i);    }}var result = fn(t1) > fn(t2) ? t2 : t1;console.log(result);   // 0.9586523941351989

黄金分割法(0.618法):
首先我们来看一下0.618是怎么样来的:
我们将一个线段中选取两个点,使得较长的线段a,较短的先打b,满足aa+b=ba,经过计算,我们可以的出,512,这也就是我们所说的0.618,这样选取的目的使得我们在迭代时,只需要计算一次值,而另一个值即为这次的0.618处的值。

var e = Math.E,    sin = Math.sin,    tan = Math.tan,    pow = Math.pow;function GoldSplit (max, min, deviation, obj1, obj2) {    if (Math.abs(max - min) < deviation) {        return (max + min) / 2;    }    var t1 = obj1.t1 || min + 0.382 * (max - min),        t2 = obj2.t2 || min + 0.618 * (max - min),        f1 = obj1.f1 || -( pow(sin(t1), 6) * tan(1- t1) * pow(e, 30 * t1) );        f2 = obj2.t2 || -( pow(sin(t2), 6) * tan(1- t2) * pow(e, 30 * t2) );    if (f1 < f2) {        return GoldSplit(t2, min, deviation, {}, {            t2: t1,            f2: f1        });    } else if (f1 > f2) {        return GoldSplit(max, t1, deviation, {            t1: t2,            f1: f2        }, {});    } else {        return GoldSplit(t2, t1, deviation, {}, {});    }}console.log(GoldSplit(1, 0, Math.pow(10, -6), {}, {})); // 0.9442574673570285
0 0
原创粉丝点击