当前位置: 首页 > 后端技术 > Python

#Python干货#python实现-优化算法

时间:2023-03-26 18:28:09 Python

二分函数详见rres,这段代码让算法运行两次defasdf(x):rres=8*x**3-2*x**2-7*x+3返回rresi=2left=0right=1whilei>0:i=i-1ans=0.1mid1=(left+right+ans)/2mid2=(left+right-ans)/2a=asdf(mid1)c=asdf(mid2)ifa>c:right=mid1else:left=mid2b=(left+right)/2print("leftlimit=%s,rightlimit=%s,minimumvaluex=%s"%(left,right,b))leftlimit=0.45,rightlimit=0.775,minimumvaluex=0.6125收获:这是我第一次实现的代码。学完算法,逻辑框架基本有了,剩下需要弄清楚的就是对应的python语言。于是我开始寻找“如何定义一个函数”(详见mofan的优酷),“循环体”和“if条件语句”的格式(https://blog.csdn.net/qq\_39407518/article/details/79822498)《数学符号》(详见莫凡的优酷),以及print的使用1.def是python中中指的定义,一般用来定义函数。如果你需要深度学习来构建网络,你可以使用它来定义网络。值得注意的是,函数后面一定要加return,并另起一行。不知道为什么,不加的话,函数公式就是个花瓶,就像一个无法输出的结果。2.最糟糕的是逻辑。一开始逻辑不清晰,或者代码有遗漏,导致我把left和right放到了循环体内,结果可想而知。不过也是因为这个错误,知道怎么用pycharm中的debug,很简单,百度一下就出来了。3.不知道是什么原因,在我的pycharm中无法使用莫凡视频中的printmultiplevariables一起输出,结果很奇怪。可能是因为我是win10不是ios。print如果多个变量一起输出,一定是print("name:%s,name2:%s"%(a,b))结果输出是name:a,name2:b问题:1.为什么要加返回?return表示输出这个def中的任意一个变量值作为结果显示。一般来说就是输出函数的关系表达式的名字,这样调用这个函数的时候就可以显示变量对应的函数值,否则只会运行没有结果,没有任何作用。格点法——三点等分法importnumpyasnpdefqwer(x):third=np.exp(x)-5*xreturnthirdleft=1right=2mid1=float(left+right)/2mid2=(left+mid1)/2mid3=(mid1+right)/2a=qwer(mid1)b=qwer(mid2)c=qwer(mid3)i=5whilei>0:i=i-1如果a>b:如果c>b:#bright=mid1mid1=mid2a=bmid2=(left+mid1)/2mid3=(mid1+right)/2b=qwer(mid2)c=qwer(mid3)else:#b>c#cleft=mid1mid1=mid3a=cmid2=(left+mid1)/2mid3=(mid1+right)/2b=qwer(mid2)c=qwer(mid3)else:#b>aifa>c:#Cleft=mid1mid1=mid3a=cmid2=(left+mid1)/2mid3=(mid1+right)/2b=qwer(mid2)c=qwer(mid3)else:#b>a&c>a#aleft=mid2right=mid3mid2=(left+mid1)/2mid3=(mid1+right)/2b=qwer(mid2)c=qwer(mid3)print("最小值=%s"%mid1)print("函数值=%s"%a)最小值=1.609375函数值=-3.047189552275773python中data变量第一次运行结果明显错误,所以我用了debug。原来mid1永远是1而不是1.5,于是我开始了解数据变量。一开始我猜测python默认所有变量都是整数,但是根据二分法的结果,我意识到这个猜测是错误的,所以没有必要改变整个文件的变量格式。于是我在mid1公式前面加了一个float,结果显示为1.5。但是如果我把整个公式用()括起来,前面加上float,结果还是1,不太明白为什么。不过我知道python的数据格式是根据输入量来决定的。也就是说,如果你的输入量是整数类型,那么与其直接相关的计算输出也一定是整数类型,而它仍然没有使用整数类型。在我没有使用+float/+.0这两个方法之前,mid1~3都是整数。left=1.0right=2.0mid1=(left+right)/2或者不再在mid1前面加float,直接在输入的amount后面点一个点。我真的很想抱怨印刷品。太麻烦了。弄个%s,有时候拼不起来!!!!斐波那契方法deffibonacci(n):i=0a=0b=1foriinrange(n):i=i+1c=a+ba=bb=creturncdefbn(x):ert=x**2-6*x+2返回ertz=2p=0left=0.00000right=10.00000L1=right-leftwhilez<100:m=fibonacci(z)l=L1/mk=1.000/mifk<0.03:print("n=%s,Fn=%s"%(z,m))L2=l*fibonacci(z-1)t=left+L2r=right-L2whilep<3:p=p+1l3=t-re=bn(t)o=bn(r)ife>o:right=tt=rr=left+l3else:#o>e??left=rr=tt=right-l3breakelse:z=z+1okk=(左+右)/2okky=bn(okk)print(左)print(右)print("最小值x=",okk)print("最小值y=",okky)写完这段代码别问我掌握了什么,问我有多喜欢python的精度表示:-)我决定只把数学写在future公式的代码会在输入量的小数学点后加很多0来定义斐波那契函数,每次调试完手都在抖O(∩\_∩)O~黄金分割法defgold(x):gg=x**2-6*x+9返回ggleft=1right=7ans=0.4a=left+0.618*(right-left)b=left+0.382*(right-left)gga=gold(a)ggb=gold(b)i=0whilei<7:print("i=%s"%i)print("left=%s,right=%s"%(left,right))print("xleft=%s,xright=%s"%(a,b))print("yleft=%s,yright=%s"%(ggb,gga))c=right-left如果c>0.4:i=i+1如果gga>ggb:right=aa=bb=left+0.382*(right-left)gga=ggbggb=gold(b)else:#gga0.05000:a=abs(xp-x2)如果xp>x2:如果fp>f2:x3=xpf3=fpxp=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))打印("x2=%s,f2=%s"%(x2,f2))print("******************")else:#f2>fpx1=x2f1=f2x2=xpf2=fpxp=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:#xpf2:x1=xpf1=fpxp=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("*******************”)否则:x3=x2f3=f2x2=xpf2=fpxp=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的长河)。代码虽然很长,但主要是打印的太多了。一开始我打算打印,但是最后的结果会漏掉最后一部分。懒得想别的办法了,直接做吧间接法——牛顿法deffd(x):y=4*x**3-12*x**2-12*x-16returnydeffdd(x):ys=12*x**2-24*x-12返回ysi=1x0=3.00000ans=0.001whilei<7:fd0=fd(x0)fdd0=fdd(x0)如果abs(fd0)>ans:x1=x0-(fd0/fdd0)x0=x1print("Times:%s,obtainedvaluex:%s"%(i,x1))i=i+1else:#fd0<0.001print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")print("宾果游戏!成功通过关卡!开学愉快!")print("BossX=%s"%x0)while开头break,导致跑不出来。那么,debug也是没用的。上网一查,发现是“未联网”+“未选择断点”。最后想尝试输出else中的内容,结果发现run后刷屏了。所以改成i<7后还是不行,于是想着加个break跳出循环,果然成功了。然后刚调试完,发现if里面是i+1,因为没办法+1,所以i=6一直存在,一直循环。因为加break或者i+1都没有关系,没关系。就在一个半小时前,我成功完成了六大代码的优化,纯手工,没有借助外力。快乐的!这是我自己实现的第一套python代码,就是用python语言组装数学公式。一开始知道语言需要体现什么,但不是很清楚。于是在网上找了几个二分法。它们都是不同的,但是框架是相似的,但是如果我们要使用我们的公式,我们需要改变很多。然后开始分析我们的问题,发现一般需要两部分,一部分函数定义,一部分循环体。但是我不知道怎么定义函数,怎么写数学公式,怎么造变量,也就是说,一些小点不是很好,所以我选择直接去百度。因为我知道我是一个很好的读者,所以我比从视频中提取它要好得多。有目的地寻找知识点,掌握得更牢。于是我开始了第一个——二分法的写作。我发现自己犯了很多错误,很多事情都是非常基础的。但是我还是没有选择视频,而是直接在百度上搜索了这些问题,因为可能你看了视频之后没有找到什么。当然,这是一个循序渐进的过程,而不是把程序放上去,一点一点改。随着前两者的成功,我发现自己对这些代码有了信心,似乎看破了它们的伪装,抓住了本质。另外,我也体会到,从八月份开始,我的学习能力好像提高了很多,有了更有效的学习方法。各方面都有了一定的觉醒。除了第一个发现了几个牛头和错误的代码外,其他的都是按照自己的逻辑写的。理清逻辑后,如果不知道对应语言的某部分怎么翻译,可以去百度。其实这些套路都是一样的或者转化数学公式的套路都是一样的。我也意识到汇编实际上是最难的语言。目前学到的东西,因为很多都需要自己定义,需要记住很多指令,不能灵活变通。而其他人只需要写下一些对应的就可以了。Python真的很简单。而且,我发现,今天的自己,仿佛打开了新世界的大门。我爱上了这种充满灵性,充满严谨美感,充满未知变化的东西。我发现我好像爱上了代码。可能不仅限于python,这些语言都充满了挑战。我觉得当你有疑问的时候,你需要相信你的直觉,至少我发现它很准确最后,如果文章对你有帮助,请点赞+关注,你的支持是我最大的动力