二分法
函數(shù)詳見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
收獲:
這是我第一個實現(xiàn)的代碼额各。學習完該算法以后国觉,邏輯框架基本上就有了,剩下需要明確的就是對應的python的語言虾啦。于是我就開始了查找“如何定義函數(shù)”(詳見mofan的優(yōu)酷)麻诀,“循環(huán)體”和“if條件語句”的格式(https://blog.csdn.net/qq_39407518/article/details/79822498)“數(shù)學符號”(詳見mofan的優(yōu)酷),以及print的使用
1.def是python中指定義傲醉,一般用來定義函數(shù)蝇闭,如果需要深度學習搭建網(wǎng)絡可用來定義網(wǎng)絡。值得注意的一點是
return必須要加在函數(shù)后面另起一行硬毕。
我不清楚為什么呻引,但是如果沒有加的話,那個函數(shù)公式就是一個花瓶吐咳,就像一個結果輸不出去逻悠。
2.最坑的就是邏輯元践。一開始邏輯沒理清楚,或者說在代碼上有疏漏童谒,導致我將left和right放在了循環(huán)體里单旁,結果可想而知。不過也是因為這個錯誤饥伊,我知道pycharm中的debug怎么用象浑,挺簡單的,百度一下就出來了琅豆。
3.不知道什么原因愉豺,看的莫煩視頻中的print多個變量一起輸出是沒有辦法在我的pycharm中使用的,出來的結果很奇怪茫因◎嚼梗可能是因為我是win10不是ios吧。print如果多個變量一起輸出必須是print("名字:%s,名字2:%s"%(a,b))結果輸出就是名字:a ,名字2:b
問題:1.為什么要加return节腐?
return的意思是輸出這個def里面任意一個變量值作為結果顯示外盯。一般情況而言摘盆,是輸出函數(shù)的關系式的命名翼雀,這樣當你調(diào)用這個函數(shù)的時候,變量對應的函數(shù)值才能顯示出來孩擂,否則只運行沒有結果狼渊,不會有效果。
格點法——三點等分法
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("函數(shù)值=%s"%a)
最小值=1.609375
函數(shù)值=-3.047189552275773
關于python中數(shù)據(jù)變量类垦。第一遍運行結果出現(xiàn)很明顯不對狈邑,于是我采用了debug。結果發(fā)現(xiàn)蚤认,mid1處一直為1而不是1.5米苹,于是就開始了解數(shù)據(jù)變量。起初我猜測python默認所有變量為整型砰琢,但是根據(jù)二分法的結果我意識到此猜測不對蘸嘶,所以要改整個file的變量格式?jīng)]有必要。所以我就在mid1式子前面加了一個float陪汽,結果就顯示為1.5了训唱。但是如果我將整個式子用()括起來,前面加float挚冤,結果還是1况增。我不太理解為什么。不過我知道了python的數(shù)據(jù)格式是根據(jù)輸入量決定的训挡,也就是說你的輸入量如果是整型澳骤,那么與其直接相關的計算輸出結果一定是整型歧强,而且還是不采用進位的整型。在我沒有采用+float/+.0這兩種方法之前为肮,mid1~3全部是整型誊锭。
left = 1.0
right = 2.0
mid1 =(left+right) / 2
或者不再mid1前面加float,直接將輸入量后面點個點就行
真的很想吐槽一下print,好麻煩啊啊啊啊每次都得弄個%s,而且有時候還不能放一起!C殖Iッ摇!
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)
不要問我掌握了什么籽暇,要問我現(xiàn)在寫完這個代碼后有多么的愛python的精度表示 :-)我決定以后只要再編寫數(shù)學公式的代碼都將輸入量的小數(shù)學點后面補很多0
fibonacci函數(shù)定義温治,每次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("次數(shù):%s,所得的值x:%s"%(i,x1))
i = i + 1
else:#fd0<0.001
print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
print("Bingo!順利通關蓝牲!祝您開學愉快趟脂!")
print("Boss X=%s"%x0)
break
一開始while里面<寫成了>,導致run不出來。繼而例衍,debug也沒法用昔期。在網(wǎng)上一查才知道 “沒聯(lián)網(wǎng)”+“沒選斷點”。最后想嘗試將else里面的內(nèi)容輸出來肄渗,結果發(fā)現(xiàn)run以后被刷屏了镇眷。于是改成i<7以后還是不行,于是想著加一個break跳出循環(huán)翎嫡,結果成效了欠动。
然后剛剛由debug了一下,才知道原來是i+1在if里面,因為沒有辦法+1具伍,所以i=6一直存在翅雏,就不斷循環(huán)。因為加break也好人芽,i+1也好望几,都可以。
就在一個半小時前萤厅,我成功搞完了最優(yōu)化六大代碼橄抹,純手打,無外力惕味。開心!
這是我第一組自己實現(xiàn)的python代碼楼誓,就是數(shù)學公式用python語言組裝起來。剛開始的時候知道大概需要在語言中體現(xiàn)什么名挥,但不太清楚疟羹。于是我就在網(wǎng)上找了幾個二分法的,他們都各有不同禀倔,但框架都差不多榄融,不過如果要用到我們的那個公式里還需要改變很多。然后我就開始分析我們的題救湖,我發(fā)現(xiàn)大體需要兩部分愧杯,一部分函數(shù)定義,一部分循環(huán)體捎谨。但我不知道如何定義函數(shù)民效,如何寫數(shù)學公式憔维,如何弄變量涛救,也就是說一些小點不太會,所以我選擇直接百度业扒。因為我知道自己閱讀的能力不錯检吆,相比于從視頻中提取要素,我更擅長通過閱讀獲得要點程储。有目的性地找知識點蹭沛,掌握地更牢固。
于是我就開始了第一個——二分法的編寫章鲤。我發(fā)現(xiàn)摊灭,自己出現(xiàn)了很多錯誤而且有很多地方都很基礎。但我依然沒選擇視頻败徊,而是將這些問題直接在百度上找帚呼,因為視頻講完或許你也沒找到點。當然,這是一步一步走的煤杀,不是直接就將程序擺上去眷蜈,一點一點改。
隨著前兩個的成功沈自,我發(fā)現(xiàn)自己對于這些代碼有了自信酌儒,似乎看透了他們的偽裝,抓住了本質(zhì)枯途。除此之外忌怎,我還意識到自己自從8月份以后,學習能力似乎提高了不少酪夷,而且有了更為有效的學習方法呆躲。各方面都有了一定的覺醒。除了第一個找了幾個牛頭不對馬嘴的代碼捶索,其他都是根據(jù)自己的邏輯寫插掂,邏輯通下來以后,對應語言中某一部分不知道如何翻譯就去百度腥例,其實這幾個套路都一樣或者說數(shù)學公式轉(zhuǎn)化的套路都一樣辅甥。
我還意識到,匯編其實是最難的語言燎竖,目前為止所學到的璃弄,因為很多都需要自己去定義,去死摳构回,需要記住大量的指令且不能靈活變通夏块。但是其他的卻只需要將一些對應的記下來就好。python真的挺簡單的纤掸。而且脐供,我發(fā)現(xiàn)自己今天似乎打開了新世界的大門,我愛上了這種充滿了靈性的東西借跪,充滿了嚴謹?shù)拿利愓海€有那未知的變化,我發(fā)現(xiàn)我似乎愛上了代碼掏愁⌒桑可能不僅僅局限于python,這些語言都充滿了挑戰(zhàn)性果港。我覺得當你疑惑的時候沦泌,就需要相信直覺,至少我發(fā)現(xiàn)它很準