凸优化Python实战(1)_ 最优化问题概念与基本知识

1 最优化问题

1.1 什么是最优化问题

在这里插入图片描述

1.2 名词与符号

在这里插入图片描述

1.3 最优解条件

在这里插入图片描述

2 用计算机求解问题

2.1 迭代搜索

在这里插入图片描述
在这里插入图片描述

2.2 质量评估

在这里插入图片描述

3 最小二乘问题——无约束最优化问题实例

点列的曲线拟合是我们高中开始就接触过的问题。为了寻找一个待定系数的函数,可以以最小的误差去描述点列,我们需要用到最小二乘法。有关最小二乘法可以参阅:https://www.zhihu.com/question/37031188

最小二乘法是我们研究无约束最优化问题的一个出色的实例。它具有广泛的应用价值,而且目标函数的局部最优解就是全局最优解。我们在接下来的无约束最优化问题部分将针对一个最小二乘法例题进行研究

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

4.代码实现

本博客所有代码在https://github.com/HarmoniaLeo/optimization-in-a-nutshell开源,如果帮助到你,请点个star,谢谢这对我真的很重要!

本次代码实现内容是梯度、梯度二范数、黑森矩阵等最优化问题基本件的python数值解法,以及简化的python线性代数库

梯度、梯度二范数、黑森矩阵求法参考自博客,有修改:https://www.cnblogs.com/kisetsu/p/9145393.html

4.1制作Fuction.py

import numpy as np

class Function:
    def __init__(self, _f):
        self.fun = _f

    def value(self, val):
        return self.fun(val)

    def part(self, var_index, val):
        a = self.fun(val)
        b = a + 1
        i = 0
        e = 2 ** 10 - 1
        e1 = 2 ** 10
        while 10 ** (-6) < e < e1 or i > -6:
            e1 = e
            a = b
            val_ = list(val)
            val_[var_index] += 10 ** i
            m = self.fun(val_)
            n = self.fun(val)
            b = (m - n) / 10 ** i
            i -= 2
            e = abs(b - a)
        return a

    def part_2(self, x_index, y_index, val):
        return self.__diff_(x_index).__diff_(y_index).value(val)

    def diff(self, val):
        a = self.fun(val)
        b = a + 1
        i = 0
        e = 2 ** 10 - 1
        e1 = 2 ** 10
        while 10 ** (-6) < e < e1 or i > -6:
            e1 = e
            a = b
            val_ = val + 10 ** i
            m = self.fun(val_)
            n = self.fun(val)
            b = (m - n) / 10 ** i
            i -= 2
            e = abs(b - a)
        return a

    def grad(self, val):
        g = np.array(val).astype('float')
        for i in range(0, g.size):
            g[i] = self.part(i, val)
        return np.array(g)

    def __diff_(self, index):
        def diff_f(vals):
            vals_ = list(vals)
            vals_[index] = vals_[index] + 10 ** (-6)
            m = self.fun(vals_)
            n = self.fun(vals)
            return (m - n) / 10 ** (-6)
        return Function(diff_f)

    def hesse(self, val):
        v = np.mat(val)
        G = np.mat(np.dot(v.T, v)).astype('float')
        for i in range(0, v.size):
            for j in range(0, v.size):
                p = self.part_2(i, j, val)
                G[i, j] = p
        G=np.array(G)
        return G
    
    def norm(self, val):
        s = 0
        for x in self.grad(val):
            s += x ** 2
        return np.sqrt(s)

在之后的每个方法实现中,我们都会用到Fuction.py

from Function import Function
tar=Function(func)  #func是一个以列表为参数的多元函数
val=tar.val(para)   #传入参数获取值
diff=tar.diff(para) #一元函数求导
part=tar.part(index,para)   #对第index个参数求导
grad=tar.grad(para) #求梯度数组
hesse=tar.hesse(para)   #求hesse阵
norm=tar.norm(para) #求梯度范数

4.2 制作一个lagb.py

import numpy as np

def turn(a):    #转置
    if len(a.shape)==1:
        a=a.reshape((1,a.shape[0]))
        return a
    else:
        return np.array(np.mat(a).T)

def dot(a,b):   #点乘
    if len(a.shape)==1:
        a=a.reshape((a.shape[0],1))
    if len(b.shape)==1:
        b=b.reshape((b.shape[0],1))
    res=np.array(np.mat(a)*np.mat(b))
    if res.shape==(1,1):
        return res[0][0]
    else:
        if res.shape[1]==1:
            return res.squeeze()
        else:
            return res

def muldot(*args):  #连乘
    res=args[0]
    for i in range(1,len(args)):
        res=dot(res,args[i])
    return res

def rev(a): #求逆
    return np.array(np.mat(a).I)

在之后的每个方法实现中,我们也都会用到lagb.py

from lagb import *

#输入参数可以为向量或矩阵,即numpy创建的数组
#用numpy创建的一维数组会默认为列向量
a=turn(a)   #求转置
c=dot(a,b)  #点乘,视情况会返回向量、矩阵、数值
d=dot([a,b,c])  #连续的点乘
b=rev(a)    #求逆矩阵

引用参考:

深入浅出最优化(1) 最优化问题概念与基本知识:https://www.jianshu.com/p/c1ea0d3656ce

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值