python实现——最优化算法(二分法、格点法、黄金分割法、牛顿法等)

Souleigh ✨ 等级 387 0 0

二分法

函数详见rres,此代码使该算法运行了两次

def asdf(x):
    rres=8*x**3-2*x**2-7*x+3
    return rres

i=2
left=0
right=1
while i>0 :
    i = i-1
    ans = 0.1
    mid1 = (left + right + ans) / 2
    mid2 = (left + right - ans) / 2
    a=asdf(mid1)
    c=asdf(mid2)
    if a > c :
        right = mid1
    else :
        left = mid2
b=(left+right) / 2
print("左极限=%s,右极限=%s,极小值x=%s"%(left,right,b)) 
左极限=0.45,右极限=0.775,极小值x=0.6125 

收获:
这是我第一个实现的代码。学习完该算法以后,逻辑框架基本上就有了,剩下需要明确的就是对应的python的语言。于是我就开始了查找“如何定义函数”(详见mofan的优酷),“循环体”和“if条件语句”的格式(https://blog.csdn.net/qq_39407518/article/details/79822498)“数学符号”(详见mofan的优酷),以及print的使用

1.def是python中指定义,一般用来定义函数,如果需要深度学习搭建网络可用来定义网络。值得注意的一点是

return必须要加在函数后面另起一行。

我不清楚为什么,但是如果没有加的话,那个函数公式就是一个花瓶,就像一个结果输不出去。

2.最坑的就是逻辑。一开始逻辑没理清楚,或者说在代码上有疏漏,导致我将left和right放在了循环体里,结果可想而知。不过也是因为这个错误,我知道pycharm中的debug怎么用,挺简单的,百度一下就出来了。

3.不知道什么原因,看的莫烦视频中的print多个变量一起输出是没有办法在我的pycharm中使用的,出来的结果很奇怪。可能是因为我是win10不是ios吧。print如果多个变量一起输出必须是print("名字:%s,名字2:%s"%(a,b))结果输出就是名字:a ,名字2:b

问题:1.为什么要加return?

return的意思是输出这个def里面任意一个变量值作为结果显示。一般情况而言,是输出函数的关系式的命名,这样当你调用这个函数的时候,变量对应的函数值才能显示出来,否则只运行没有结果,不会有效果。

格点法——三点等分法

import numpy as np
def qwer(x):
    third = np.exp(x) - 5*x
    return third

left = 1
right = 2
mid1 =float(left+right) / 2
mid2 = (left+mid1) / 2
mid3 = (mid1+right) /2
a = qwer(mid1)
b = qwer(mid2)
c = qwer(mid3)
i = 5
while i > 0:
    i=i-1
    if a > b:
        if c > b :
            #b
            right = mid1
            mid1 = mid2
            a=b
            mid2 = (left + mid1) / 2
            mid3 = (mid1 + right) / 2
            b = qwer(mid2)
            c = qwer(mid3)
        else:#b>c
            #c
            left = mid1
            mid1 = mid3
            a = c
            mid2 = (left + mid1) / 2
            mid3 = (mid1 + right) / 2
            b = qwer(mid2)
            c = qwer(mid3)
    else:#b>a
            if a > c:
                #C
                left = mid1
                mid1 = mid3
                a = c
                mid2 = (left + mid1) / 2
                mid3 = (mid1 + right) / 2
                b = qwer(mid2)
                c = qwer(mid3)
            else:#b>a&c>a
                # a
                left = mid2
                right = mid3
                mid2 = (left + mid1) / 2
                mid3 = (mid1 + right) / 2
                b = qwer(mid2)
                c = qwer(mid3)

print("最小值=%s"%mid1)
print("函数值=%s"%a) 
最小值=1.609375
函数值=-3.047189552275773 

关于python中数据变量。第一遍运行结果出现很明显不对,于是我采用了debug。结果发现,mid1处一直为1而不是1.5,于是就开始了解数据变量。起初我猜测python默认所有变量为整型,但是根据二分法的结果我意识到此猜测不对,所以要改整个file的变量格式没有必要。所以我就在mid1式子前面加了一个float,结果就显示为1.5了。但是如果我将整个式子用()括起来,前面加float,结果还是1。我不太理解为什么。不过我知道了python的数据格式是根据输入量决定的,也就是说你的输入量如果是整型,那么与其直接相关的计算输出结果一定是整型,而且还是不采用进位的整型。在我没有采用+float/+.0这两种方法之前,mid1~3全部是整型。

left = 1.0
right = 2.0
mid1 =(left+right) / 2 

或者不再mid1前面加float,直接将输入量后面点个点就行
真的很想吐槽一下print,好麻烦啊啊啊啊每次都得弄个%s,而且有时候还不能放一起!!!!

Fibonacci法

def fibonacci(n):
    i=0
    a = 0
    b = 1
    for i in range(n):
        i=i+1
        c = a+b
        a = b
        b = c
    return c
def bn(x):
    ert = x**2 - 6*x + 2
    return ert
z = 2
p = 0
left = 0.00000
right = 10.00000
L1 = right - left
while z < 100:
    m = fibonacci(z)
    l = L1/m
    k = 1.000/m
    if k < 0.03:
        print("n=%s,Fn=%s"%(z,m))
        L2 = l*fibonacci(z-1)
        t = left + L2
        r = right -L2
        while p < 3:
            p = p + 1
            l3 = t - r
            e= bn(t)
            o = bn(r)
            if e>o :
                right = t
                t = r
                r = left + l3
            else:#o>e
                left = r
                r = t
                t = right - l3
        break
    else:
        z = z + 1

okk=(left+right)/2
okky=bn(okk)
print(left)
print(right)
print("极小值x=",okk)
print("极小值y=",okky) 

不要问我掌握了什么,要问我现在写完这个代码后有多么的爱python的精度表示 :-)我决定以后只要再编写数学公式的代码都将输入量的小数学点后面补很多0
fibonacci函数定义,每次debug后我的手都是抖的O(∩_∩)O~

黄金分割法

def gold(x):
    gg= x**2 - 6*x + 9
    return gg

left = 1
right = 7
ans = 0.4
a = left + 0.618 * (right - left)
b = left + 0.382*(right - left)
gga = gold(a)
ggb = gold(b)
i = 0
while i < 7:
    print("i=%s" % i)
    print("left=%s,right=%s" % (left, right))
    print("x左=%s,x右=%s" % (a, b))
    print("y左=%s,y右=%s" % (ggb, gga))
    c = right - left
    if c > 0.4:
        i = i + 1
        if gga > ggb:
            right = a
            a = b
            b = left + 0.382*(right - left)
            gga = ggb
            ggb = gold(b)
        else:#gga<ggb
            left = b
            b = a
            a = left + 0.618 * (right - left)
            ggb = gga
            gga = gold(a)
    else:
        break 

不知道自己什么时候有的强迫症,只要是代码下面有“~”我就必须要消掉。笑哭。这个很简单,前四个除了费波纳茨,都很简单。

间接法——二次插值法

def yy(x):
    y=x**4-4*x**3-6*x**2-16*x+4
    return y

def xing(xm1,xm2,xm3,fm1,fm2,fm3):
    yxxx=0.5000*((xm2**2-xm3**2)*fm1+(xm3**2-xm1**2)*fm2+(xm1**2-xm2**2)*fm3)/((xm2-xm3)*fm1+(xm3-xm1)*fm2+(xm1-xm2)*fm3)
    return yxxx

x1 = -1.0000
f1 = yy(x1)
x3 = 6
f3 = yy(x3)
x2 = 0.50000*(x1+x3)
f2 = yy(x2)
xp = xing(x1,x2,x3,f1,f2,f3)
fp = yy(xp)
a = abs(xp-x2)
while abs(xp-x2) > 0.05000:
    a = abs(xp - x2)
    if xp > x2:
        if fp > f2:
            x3=xp
            f3=fp
            xp = xing(x1, x2, x3, f1, f2, f3)
            fp = yy(xp)
            print("ans=%s" % a)
            print("left=%s,right=%s" % (x1, x3))
            print("x*=%s,fp*=%s" % (xp, fp))
            print("x2=%s,f2=%s" % (x2, f2))
            print("******************")
        else:#f2>fp
            x1 = x2
            f1 = f2
            x2 = xp
            f2 = fp
            xp = xing(x1, x2, x3, f1, f2, f3)
            fp = yy(xp)
            print("ans=%s" % a)
            print("left=%s,right=%s" % (x1, x3))
            print("x*=%s,fp*=%s" % (xp, fp))
            print("x2=%s,f2=%s" % (x2, f2))
            print("******************")
    else:#xp<x2
        if fp > f2:
            x1 = xp
            f1 = fp
            xp = xing(x1, x2, x3, f1, f2, f3)
            fp = yy(xp)
            print("ans=%s" % a)
            print("left=%s,right=%s" % (x1, x3))
            print("x*=%s,fp*=%s" % (xp, fp))
            print("x2=%s,f2=%s" % (x2, f2))
            print("******************")
        else:
            x3 = x2
            f3 = f2
            x2 = xp
            f2 = fp
            xp = xing(x1, x2, x3, f1, f2, f3)
            fp = yy(xp)
            print("ans=%s" % a)
            print("left=%s,right=%s" % (x1, x3))
            print("x*=%s,fp*=%s" % (xp, fp))
            print("x2=%s,f2=%s" % (x2, f2))
            print("******************") 

这个公式看起来很麻烦,便写的时候更要谨慎。我上回把那个2搁在了分号下面,结果很大,所以还是换算成0.5更好(PS:勿忘那长河般的0)。
虽然代码很长,但是主要是因为print太多。本打算在开头print,最后结果会漏掉最后一部分。懒得想其他办法了,直接就这样吧

间接法——牛顿法

def fd(x):
    y = 4*x**3-12*x**2-12*x-16
    return y
def fdd(x):
    ys = 12*x**2-24*x-12
    return ys

i = 1
x0 = 3.00000
ans = 0.001
while i < 7:
    fd0 = fd(x0)
    fdd0 = fdd(x0)
    if abs(fd0) > ans:
        x1 = x0 - (fd0/fdd0)
        x0 = x1
        print("次数:%s,所得的值x:%s"%(i,x1))
        i = i + 1
    else:#fd0<0.001
        print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
        print("Bingo!顺利通关!祝您开学愉快!")
        print("Boss  X=%s"%x0)
        break 

一开始while里面<写成了>,导致run不出来。继而,debug也没法用。在网上一查才知道 “没联网”+“没选断点”。最后想尝试将else里面的内容输出来,结果发现run以后被刷屏了。于是改成i<7以后还是不行,于是想着加一个break跳出循环,结果成效了。
然后刚刚由debug了一下,才知道原来是i+1在if里面,因为没有办法+1,所以i=6一直存在,就不断循环。因为加break也好,i+1也好,都可以。

就在一个半小时前,我成功搞完了最优化六大代码,纯手打,无外力。开心!

这是我第一组自己实现的python代码,就是数学公式用python语言组装起来。刚开始的时候知道大概需要在语言中体现什么,但不太清楚。于是我就在网上找了几个二分法的,他们都各有不同,但框架都差不多,不过如果要用到我们的那个公式里还需要改变很多。然后我就开始分析我们的题,我发现大体需要两部分,一部分函数定义,一部分循环体。但我不知道如何定义函数,如何写数学公式,如何弄变量,也就是说一些小点不太会,所以我选择直接百度。因为我知道自己阅读的能力不错,相比于从视频中提取要素,我更擅长通过阅读获得要点。有目的性地找知识点,掌握地更牢固。
于是我就开始了第一个——二分法的编写。我发现,自己出现了很多错误而且有很多地方都很基础。但我依然没选择视频,而是将这些问题直接在百度上找,因为视频讲完或许你也没找到点。当然,这是一步一步走的,不是直接就将程序摆上去,一点一点改。
随着前两个的成功,我发现自己对于这些代码有了自信,似乎看透了他们的伪装,抓住了本质。除此之外,我还意识到自己自从8月份以后,学习能力似乎提高了不少,而且有了更为有效的学习方法。各方面都有了一定的觉醒。除了第一个找了几个牛头不对马嘴的代码,其他都是根据自己的逻辑写,逻辑通下来以后,对应语言中某一部分不知道如何翻译就去百度,其实这几个套路都一样或者说数学公式转化的套路都一样。
我还意识到,汇编其实是最难的语言,目前为止所学到的,因为很多都需要自己去定义,去死抠,需要记住大量的指令且不能灵活变通。但是其他的却只需要将一些对应的记下来就好。python真的挺简单的。而且,我发现自己今天似乎打开了新世界的大门,我爱上了这种充满了灵性的东西,充满了严谨的美丽,还有那未知的变化,我发现我似乎爱上了代码。可能不仅仅局限于python,这些语言都充满了挑战性。我觉得当你疑惑的时候,就需要相信直觉,至少我发现它很准

收藏
评论区

相关推荐

python实现——最优化算法(二分法、格点法、黄金分割法、牛顿法等)
二分法 函数详见rres,此代码使该算法运行了两次 python def asdf(x): rres8x32x27x3 return rres i2 left0 right1 while i0 : i i1 ans 0.1 mid1 (left right ans) / 2
python时间模块的使用 white_study
前言: 在开发中经常会与时间打交道,如:获取事件戳,时间戳的格式化等,这里简要记录一下python操作时间的方法。 python中常见的处理时间的模块: time:处理时间的模块,如获取时间戳,格式化日期等 datetime:date和time的结合体,处理日期和时间 calendar:日历相关的模块,如:处理年历/月历 tim
统计字符串中字符出现的次数(Python版)
字符串转list python s 'aabbccd' list1 list(s) 方法一: python list1 'a', 'a', 'b', 'c', 'c', 'c', 'c' dict_cnt {} for value in list1: dict_cntvalue dict_cnt.get(value,
Python中的基本list操作
List是python中的基本数据结构之一,和Java中的ArrayList有些类似,支持动态的元素的增加。list还支持不同类型的元素在一个列表中,List is an Object。 最基本的创建一个列表的方法 myList \'a','b','c'\ 在python中list也是对象,所以他也有方法和属性,在ptython解释器中 使用h
python算法
640?wx_fmtjpeg(https://imghelloworld.osscnbeijing.aliyuncs.com/c8238ed70f9664b61ce91f80786ca26f.png) 来源 | CSDN(ID:CSDNnews ) 本文是一些机器人算法(特别是自动导航算法)的Python代码合集。 其主要特点有以下
Python新式类与经典类(旧式类)的区别
Python新式类与经典类(旧式类)的区别 Python中类分两种:旧式类和新式类: ➤新式类都从object继承,经典类不需要。 ➤新式类的MRO(method resolution order 基类搜索顺序)算法采用C3算法广度优先搜索,而旧式类的MRO算法是采用
Python中JSON的基本使用_Just do it !
JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。Python3 中可以使用 json 模块来对 JSON 数据进行编解码,它主要提供了四个方法: dumps、dump、loads、load。 dump和dumps dump和dumps对python对象进行序列化。将一个Python对象
Python编程基础(快速入门必看
Python编程基础一、Python语言基本语法 Python是一
商业数据分析从入门到入职(8)Python模块、文件IO和面向对象
前言本文先介绍了Python中程序、模块和包的基本使用,并在此基础上介绍了Python标准库。然后详细介绍了Python中的文件IO操作,包括文本文件、二进制文件的读写和其他IO操作。最后介绍了面向对象,包括类的定义、继承的使用、鸭子类型和魔法方法。 一、程序、模块和包 1.自定义模块和包之前我们使用的.ipynb文件都不是纯Python文件,
python-算法训练 区间k大数查询
问题描述给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个。 输入格式第一行包含一个数n,表示序列长度。第二行包含n个正整数,表示给定的序列。第三个包含一个正整数m,表示询问个数。接下来m行,每行三个数l,r,K,表示询问序列从左往右第l个数到第r个数中,从大往小第K大的数是哪个。序列元素从1开始标号。 输出格式总共输出m行,每行一个数
Jupyter Notebook最强指南,没有之一
(文末有福利) Python语言是一种强大而简洁的编程语言。据IEEE Spectrum消息,Python在2020年继续蝉联最受欢迎的编程语言第一名。对于刚接触Python的新手来说,配置一个容易上手又适合自己的开发环境无疑是成功掌握这门编程语言的第一步。对于Python IDE的比较和推荐,各路高手也说法不同,其中被推荐频率最高的当属Pycharm、V
python的这些必备干货知识点,快来看看有没有你不了解的?
Python是当前主流的编程语言之一,其优点有:一:语法简洁,可以让使用者用少量的代码完成相对复杂的效果。二:标准库和第三库多,功能强大;三:站在了人工智能和大数据的风口上;像国内的豆瓣呀,知乎呀等等知名网站都是基于python开发的,而Youtube、Reddit、Dropbpx也是用python的框架开发的。近几年学习python的小伙伴越来越多,那么p
盘点Python加密解密模块hashlib的7种加密算法
大家好,我是黄伟。今天给大家介绍hashlib模块!前言 在程序中我们经常可以看到有很多的加密算法,比如说MD5 sha1等,今天我们就来了解下这下加密算法的吧,在了解之前我们需要知道一个模块嘛就是hashlib,他就是目前Python一个提供字符加密的模块,它加密的字符类型为二进制编码,所以直接加密字符串会报错。import hashlibstring'任
盘点一款Python二级考试模拟软件,带你轻松过关二级Python考试
大家好,我是Python进阶者。今天给大家讲的这个软件,主要是想让大家通过这个软件能将自己的Python基础进一步提高。一、前言相信有些小伙伴学习Python有一段时日,但是又不知道自己的Python基础学的如何,这个时候就需要一款神器来检测一下自己的Python基础了。要想检测自己的Python功力最直观的方法当然是做题了,至于做什么题了我们就不得而知了,
建议收藏,22个Python迷你项目(附源码)
在使用Python的过程中,我最喜欢的就是Python的各种第三方库,能够完成很多操作。 下面就给大家介绍22个通过Python构建的项目,以此来学习Python编程。 大家也可根据项目的目的及提示,自己构建解决方法,提高编程水平。 ① 骰子模拟器 目的:创建一个程序来模拟掷骰子。 提示:当用户询问时,使用random模块生成一个1到6之间