演算法學習這部分,自從離開了數論後,程式效率可提公升的地方變少了,因此看起來,好像沒意思了……換句話說,之前那種通過嘗試不同語句、不同求解思路來極大提公升程式效率的快感沒了……這好像也間接導致了我更新部落格的速度變慢了(有推脫自己三分鐘熱度的嫌疑)……
接下來這部分的內容,程式主要依賴於數學分析,而程式的主體,按著數學分析的步驟表述清楚即可,因此,分析說明會更加簡單。(寫部落格的初衷是為了督促自己持續程式設計,而不是為了寫成很詳細的說明文件,具體專題,還是要參考書籍,請諒解~)
用二分法求方程
2 x3
−5x−
1=02x^3-5x-1=0
2x3−5x
−1=0
在區間[1,
2][1,2]
[1,2
]的根,使絕對誤差不超過10−
510^
10−5
二分法:又稱對分法,最簡單的解一元非線性方程根的演算法之一。基本思路是,將含根區間i
ii 逐次分半減小,得到乙個區間長度以 i/2
i/2i/
2 的比例減小的含根區間序列 i1,
i2..
...i_1,i_2.....
i1,i2
...
..等絕對誤差:區間長度i
ii_i
ii 小於給定的限制,如本題的 10−
510^
10−5
從給定區間[a,
b][a, b]
[a,b
] 開始,驗證區間端點,一定要滿足 f(a
)∗f(
b)<
0f(a) *f(b)<0
f(a)∗f
(b)<
0, 不滿足,一般不存在根或是區間太過寬泛
取區間[a,
b][a, b]
[a,b
]中點c=a
+b2c=\frac
c=2a+b
, 驗證 f(c
)f(c)
f(c)
是否等於0
00, 等於則 c
cc就是方程的解,退出;否則到第3步
區間縮小一半。判斷是 f(a
)∗f(
c)<
0f(a)*f(c)<0
f(a)∗f
(c)<
0 還是 f(b
)∗f(
c)<
0f(b)*f(c)<0
f(b)∗f
(c)<
0,目的是提出乘積小於0的組合,然後,把c
cc替換成a
aa 或是 b
bb; 跳到步驟2繼續執行,知道區間長度 b−a
<10
−5b-a<10^
b−a<10
−5, 跳出迴圈
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @date : 2019-05-03 20:54:28
# @author : promise ([email protected])
# @link : $
# @version : $id$
# 用二分法求方程的關鍵是,先定義返回待計算函式值的函式,然後判斷端點的取值,從而縮小區間
import math
# 定義函式
deffunc
(x):
return
2*x*x*x -
5*x -
1# 給定根的區間,通過不斷判斷區間中點的函式值是否小於誤差,還有區間端點的精度夠不夠,從而決定是不是拿中點當解
deffindanswer
(a, b)
:# 輸入解的端點
# 正常這裡要檢查端點,先忽略了
if func(a)
* func(b)
>0:
print
('所選區間有誤,請更正!'
)# 很大程度會是錯的
return
none
middle =
(a + b)/2
while
(b-a)
>1e-
5or math.fabs(func(middle)
)>1e-
5:# 一方面是區間要小於10的負五,取值的差要衡量跟0的距離
# 更新區間
if func(middle)
* func(a)
<0:
b = middle
elif func(middle)
* func(b)
<0:
a = middle
else
:print
('所選區間不止乙個根'
) middle =
(a + b)/2
# 更新區間
return middle
defmain()
: a, b =
eval
(input
('請輸入區間端點:'))
result = findanswer(a, b)
print
('解x='
上圖是只有單獨乙個判斷條件 (b−
本圖是判斷條件有兩個(b−
a)>10
−5(b-a)>10^
(b−a
)>10
−5and ∣fu
nc(m
iddl
e)∣>1e
−5|func(middle)| > 1e-5
∣func(
midd
le)∣
>1e
−5, 第二個條件用於刻畫函式值跟零的接近程度,由於捨入誤差,我們不可能得到函式值完全等於0
00的情況,於是,只能借助不等式來表達。不過,對比上圖,二者差別其實不大。
單獨定義乙個方程求值的函式fun
c(x)
func(x)
func(x
),便於值比較 ,更高階的求解,是函式可以輸入係數,這裡從簡,省略了
在求解的主函式,判斷區間是否可用,很重要,如果區間一開始不滿足端點符號相異,接下來的求解都沒有意義。
根據實驗結果的分析,只要根的精確度在給定的區間,函式值一般不會差太多,所以增加函式值判斷的條件,可有可無
注意區間端點的更新條件
本篇部落格使用求解非線性方程最簡單額二分法進行求解,難點在於區間更新和值精確度的確定,弄懂了這兩個,就能正確求解。
演算法學習 二分法
二分查詢也稱折半查詢 binary search 它是一種效率較高的查詢方法,前提是資料結構必須先排好序,可以在資料規模的對數時間複雜度內完成查詢。但是,二分查詢要求線性表具有有隨機訪問的特點 例如陣列 也要求線性表能夠根據中間元素的特點推測它兩側元素的性質,以達到縮減問題規模的效果。舉個簡單的例子...
求方程根 (二分法)
二分法求方程的根 求下面方程的乙個根 f x x3 5x2 10x 80 0 若求出的根是a,則要求 f a 10 6 解法 對f x 求導,得f x 3x2 10x 10。由一元二次方程求根公式知方呈f x 0 無解,因此f x 恆大於0。故f x 是單調遞增的。易知f 0 0且f 100 0,所...
二分法求方程根
二分法是計算機上的一種常用演算法,下面列出計算步驟 step1 計算 step2 計算 step3 若 0,則若若 如下 erfen.m 有根區間 a,b 函式 y x 2 2 呼叫了erfenhanshu a 1 b 6 e 10 cnt 0 while e 0.1 cnt cnt 1 fa er...