程式設計師必修數學課 基礎思想篇 迭代法

2021-10-04 22:11:58 字數 3126 閱讀 8575

這裡引用乙個大家從小就聽過的小故事。

傳說,印度的舍罕國王打算重賞西洋棋的發明人——大臣西薩·班·達依爾。這位聰明的大臣跪在國王面敢說:「陛下,請你在這張棋盤的第乙個小格內,賞給我一粒麥子,在第二個小格內給兩粒,在第三個小格內給四粒,照這樣下去,每一小格內都比前一小格加一倍。陛下啊,把這樣擺滿棋盤上所有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,是因為如果maxmin都已經接近資料的極限,兩個數相加就會溢位,所以替換成了先減,然後用兩個數的差的二分之一再加,這樣就不會溢位了。兩個式子化簡下來其實是一樣的。

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...