栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

《最优化方法》 算法代码 python实现

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

《最优化方法》 算法代码 python实现

文章目录

一维搜索算法

成功-失败法 求搜索区间黄金分割法 求最小值点二次插值法 求最小值点一维搜索函数 多维直接搜索算法

坐标轮换法 基础运算

多元函数任意一点求导

此文章为《机器学习》西瓜书 算法代码 python实现 的基础

一维搜索算法

一维搜索算法传入一个凸函数,返回其最小值点
一维搜索算法需要由两部分组成

确定搜索区间在搜索区间内寻找最小值点

以下代码均经过本人在 python3.7 下测试成功,测试代码就不放了

成功-失败法 求搜索区间

此处代码有一个不完善的地方,就是当传入的函数定义域不为R时,需自行调整 x0
实际上我们可以重新设计该算法,传入函数的左范围点或右范围点,不传入默认为无穷
h 的调整需加入参数 xl 和 xr 以防止越界
但本人较为懒惰,有需要请评论或私聊讨论

def success_failure_method(f,x0=0,h=5,maxiters=1000):
    '''
    成功-失败法求搜索区间
    必须传入有最小值的严格凸函数
    有可能搜索区间长度为0 代表输入的x0即为最优解
    '''
    y0 = f(x0)
    y1 = f(x0+h)
    while maxiters:
        if y0 > y1:
            y2 = f(x0+3*h)
            if y1 > y2:
                x0 = x0 + h
                y0 = y1
                y1 = y2
                h = 2*h
                maxiters -= 1
                continue
            else:
                if h > 0:
                    return x0,x0+3*h
                else:
                    return x0+3*h,x0
        elif y0 == y1:
            if h > 0:
                return x0,x0+h
            else:
                return x0+h,x0
        else:
            h = -h/4
            y1 = f(x0+h)
            maxiters -= 1
            continue
    print('成功失败法传入了非凸函数')
    return 0,0
黄金分割法 求最小值点
def golden_section_method(f,a,b,acy=0.001,maxiters=1000):
    '''
    黄金分割法求最小值点
    传入函数f 搜索区间[a, b]
    '''
    alpha = 0.381966
    beta = 1 - alpha
    x1 = a + alpha*(b-a)
    x2 = a + b - x1
    y1 = f(x1)
    y2 = f(x2)
    while maxiters:
        if y1 > y2:
            a = x1
            if b - a < acy:
                break
            else:
                x1 = x2
                y1 = y2
                x2 = alpha*a + beta*b
                y2 = f(x2)
                maxiters -= 1
                continue
        else:
            b = x2
            if b - a < acy:
                break
            else:
                x2 = x1
                y2 = y1
                x1 = beta*a + alpha*b
                y1 = f(x1)
                maxiters -= 1
                continue
    else:
        print('黄金分割法未收敛到精度')
    return (a+b)/2
二次插值法 求最小值点
def quadratic_interpolation_method(f,x1,x3,acy=0.001,maxiters=1000,simplify=False):
    '''
    二次插值法求最小值点
    传入函数f 搜索区间[x1, x3]
    simplify 传入True时 使用化简后的二次插值法 但迭代次数更多
    '''
    x2 = (x1+x3)/2
    if abs(x1-x3) < acy:
        return x2
    if not simplify:
        while maxiters:
            y1 = f(x1);y2 = f(x2);y3 = f(x3)
            k1 = (y1-y3)/(x1-x3)
            k2 = ((y2-y1)/(x2-x1)-k1)/(x2-x3)
            xt = (x1+x3-k1/k2)/2
            # 这个地方绝对不能抄书上的 有误
            if abs(xt-x2) < acy:
                break
            elif xt < x2:
                if f(xt) < y2:
                    x3 = x2
                    x2 = xt
                else:
                    x1 = xt
                maxiters -= 1
                continue
            else:
                if f(xt) < y2:
                    x1 = x2
                    x2 = xt
                else:
                    x3 = xt
                maxiters -= 1
                continue
        else:
            print('二次插值法未收敛到精度')
        return xt
    else:
        while maxiters:
            y1 = f(x1);y2 = f(x2);y3 = f(x3)
            delta = (x3-x1)/2
            xt = x2 + (y1-y3)*delta/2/(y1-2*y2+y3)
            if abs(xt-x2) < acy:
                break
            elif xt < x2:
                if f(xt) < y2:
                    x3 = x2
                else:
                    x1 = xt
                x2 = (x1+x3)/2
                maxiters -= 1
                continue
            else:
                if f(xt) < y2:
                    x1 = x2
                else:
                    x3 = xt
                x2 = (x1+x3)/2
                maxiters -= 1
                continue
        else:
            print('二次插值法未收敛到精度')
        return xt
一维搜索函数
def one_dimensional_search(f,x0=0,method='golden_section',acy=0.001,maxiters=1000,h=5):
    '''
    一维搜素算法
    method可选择如下:
    golden_section
    quadratic_interpolation
    simplified_quadratic_interpolation
    '''
    a,b = success_failure_method(f,x0=x0,h=h,maxiters=maxiters)
    if method == 'golden_section':
        ans = golden_section_method(f,a,b,acy=acy,maxiters=maxiters)
    elif method == 'quadratic_interpolation':
        ans = quadratic_interpolation_method(f,a,b,acy=acy,maxiters=maxiters)
    elif method == 'simplified_quadratic_interpolation':
        ans = quadratic_interpolation_method(f,a,b,acy=acy,maxiters=maxiters,simplify=True)
    else:
        print('Input method does not exist!')
        return None
    return ans
多维直接搜索算法 坐标轮换法
def univarite_search_technique(f,d,ini_point=None,acy=0.01,maxiters=1000):
    '''
    坐标轮换法
    传入函数 维度 初始点
    '''
    if ini_point is None:
        point = [0 for i in range(d)]
    else:
        point = list(ini_point)
    difference = 1000
    old = f(*point)
    while abs(difference) > acy and maxiters:
        for i in range(d):
            part1 = point[:i]
            part2 = point[i+1:]
            fun = lambda x:f(*part1,x,*part2)
            t = one_dimensional_search(fun,point[i])
            point[i] = t
        new = f(*point)
        difference = new - old
        old = new
        maxiters -= 1
    return point
基础运算 多元函数任意一点求导
def diff(f,x,acy=0.01,maxiters=1000):
    ans = []
    y0 = f(*x)
    for i in range(len(x)):
        delta = 1
        part1 = x[:i]
        part2 = x[i+1:]
        old = f(*part1,x[i]+delta,*part2) - y0
        oldd = old/delta
        while maxiters:
            delta /= 10
            new = f(*part1,x[i]+delta,*part2) - y0
            newd = new/delta
            if abs(new-old) < acy and abs(newd-oldd) < acy:
                break
            else:
                old = new
                oldd = newd
                maxiters -= 1
        ans.append(newd)
    return ans
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/738127.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号