這裡引用乙個大家從小就聽過的小故事。
傳說,印度的舍罕國王打算重賞西洋棋的發明人——大臣西薩·班·達依爾。這位聰明的大臣跪在國王面敢說:「陛下,請你在這張棋盤的第乙個小格內,賞給我一粒麥子,在第二個小格內給兩粒,在第三個小格內給四粒,照這樣下去,每一小格內都比前一小格加一倍。陛下啊,把這樣擺滿棋盤上所有64格的麥粒,都賞給您的僕人吧?」國王說:「你的要求不高,會如願以償的」。說著,他下令把一袋麥子拿到寶座前,計算麥粒的工作開始了。……還沒到第二十小格,袋子已經空了,一袋又一袋的麥子被扛到國王面前來。但是,麥粒數一格接一格地增長得那樣迅速,很快看出,即使拿出來全印度的糧食,國王也兌現不了他對象棋發明人許下的語言。這個故事中的計算麥粒的方法,在數學上是有對應方法的,這也正是這篇文章要講的概念——迭代法(iterative method)。
那麼到底什麼是迭代法呢?
簡單來說,迭代法就是不斷地用舊的變數值,遞推計算新的變數值。
我們回到這個西洋棋的故事,大臣要求每一格的麥子都是前一格的兩倍,那麼前一格里麥子的數量就是舊的變數值,我們可以先記作 xn-1 ;而當前格仔裡麥子的數量就是新的變數值,我們記作 xn 。這兩個變數的遞推關係如下?
有程式設計經驗的人很容易就想到,迭代的思想可以通過計算機語言中的迴圈語句來實現。計算機本身就很適合做重複性的工作,我們可以通過迴圈語句,讓計算機重複執行迭代中的遞推步驟,然後推導出變數的最終值。
這裡我用c語言實現一下這個迭代過程。
#include
long
getnumberofwheat
(int grid)
;long
getnumberofwheat
(int grid)
return sum;
}int
main()
我用第20格作為測試,迭代到後面會超出c語言資料結構能表示的最大值了。
測試結果如下?
大體上,迭代法可以運用在以下幾個方面:
在這裡我主要說一下求數值的解和查詢匹配記錄這兩個應用。
迭代法在數學和程式設計中的應用有很多,如果只能用來計算龐大的數字,那就太暴殄天物了。
迭代還可以幫助我們進行無窮地逼近,求得方程的精確或者近似解。
比如說,我們想計算某個給定正整數 n(n > 1)的平方根,如果不用程式語言自帶的函式,要怎麼做呢?
假設有正整數 n ,這個平方根一定小於 n 本身,並且大於 1。那麼這個問題就轉化成了,在 1 到 n 之間,找乙個數字等於 n 的平方根。
這裡我採用迭代中常見的二分法。每次檢視區間內的中間值,檢驗它是否符合標準。
同樣的,我用c語言來簡單實現一下這個功能。
#include
#include
double
getsqureroot
(int number,
int maxtry,
double threshold)
;double
getsqureroot
(int number,
int maxtry,
double threshold)
for(i =
0; i < maxtry; i++
)else
else}}
return
-2.0;}
intmain()
elseif(
-2.0
== squreroot)
else
return0;
}
這裡我說幾個細節。
middle =
(max - min)/2
+ min
這裡我用的是這個式子而不是(max + min) / 2
,是因為如果max
和min
都已經接近資料的極限,兩個數相加就會溢位,所以替換成了先減,然後用兩個數的差的二分之一再加,這樣就不會溢位了。兩個式子化簡下來其實是一樣的。
int maxtry
是最多嘗試的次數,防止程式耗時太久。double threshold
是精度,也是乙個保護機制,如果找不到精確解,誤差小於規定的精度也可以退出迴圈。
delta =
fabs
(squre / number -1)
;
這個就是算的誤差佔原值的百分比,來控制迭代的結束。
這就是二分迭代法。這裡我簡單地提一下牛頓迭代法。
牛頓迭代法是牛頓在17世紀提出的一種方法,用於求方程的近似解。這種方法以微分為基礎,每次迭代的時候,它都會去找到比上乙個值 x0 更接近的方程的根,最終找到近似解。該方法及其延伸也被應用在機器學習的演算法中,在我後面的文章中,我會詳細講解。
二分法中的迭代式逼近,不僅可以幫我們求得近似解,還可以幫助我們查詢匹配的記錄。這裡我舉乙個查通訊錄的例子。
比如你有一本通訊錄,按照名字的首字母從a到z排列。
如果你要查詢乙個名字,自然要從中間開始,如果中間的字母在要找的名字的前面,那就可以不用管前半邊了,直接從後半部分再取中間,然後看字母的順序。就這樣持續地迭代式查詢,直到範圍縮小到單個的名字。如果最終仍然無法找到,則返回不存在。
這個方法的整體思路和二分法求解平方根是一致的,主要區別在兩個方面:
第一,每次判斷是否終結迭代的條件不同。求平方根的時候我們需要判斷某個數的平方是否和輸入的資料一致。而這裡,我們需要判斷通訊錄中某個單詞是否和待查的單詞相同;
第二,二分查詢需要確保被搜尋的空間是有序的。
這裡我就不寫**了,因為道理都是一樣的。
關於迭代法的內容就完了,日常的程式設計中我們要多觀察問題的現象,思考其本質,看看不斷更新變數值或者縮小搜尋的區間範圍,是否可以獲得最終的解(或近似解、區域性最優解),如果是,那就可以嘗試迭代法。
《程式設計師的數學課》模組一 無處不在的數學思維01
數制是一種計算數量大小的制度,也是計數法。用大白話來說,就是數數的方法。數制中,最重要的因素是基數。假設我們設定基數為 10 來數數,那就是在用十進位制計數法 如果設定基數為 2,就是在用二進位制計數法。經常說的進製,其實就是數制 不同的數制中,使用最廣泛的就是十進位制,這與人類有 10 個手指頭是...
程式設計師的數學基礎課 筆記4
你好,我是黃申。今天我們來聊聊 餘數 提起來餘數,我想你肯定不陌生,因為我們生活中就有很多很多與餘數相關的例子。比如說,今天是星期三,你想知道 50 天之後是星期幾,那你可以這樣算,拿 50 除以 7 因為乙個星期有 7 天 然後餘 1,最後在今天的基礎上加一天,這樣你就能知道 50 天之後是星期四...
2020最新 程式設計師數學(基礎 高階)
課程目錄 程式設計師的數學10.mp4 程式設計師的數學11 1.mp4 程式設計師的數學11 2.mp4 程式設計師的數學11 3.mp4 程式設計師的數學11 4.mp4 程式設計師的數學11 5.mp4 程式設計師的數學11 6.mp4 程式設計師的數學12.mp4 程式設計師的數學1.mp4...