迭代反投影法代码_程序员的数学笔记3--迭代法
第三節課程,介紹的是迭代法。
03 迭代法
什么是迭代法
迭代法,簡單來說,其實就是不斷地用舊的變量值,遞推計算新的變量值。
這里采用一個故事來介紹什么是迭代法,這個故事是講述一個國王要重賞一個做出巨大貢獻的臣子,讓臣子提出他想得到的賞賜,這個聰明的臣子說出了他想得到的賞賜--在棋盤上放滿麥子,但要求是每個格子的麥子數量都是前一個格子的兩倍。國王本以為這個賞賜可以輕而易舉的滿足,但真正開始放麥子后,發現即便是拿出全國的糧食也無法滿足的臣子的這個賞賜。
這里我們可以用f(n)表示當前各自的麥子數量,而前一個格子的麥子數量就是f(n-1),那么臣子的要求就可以這么表示:
f(n) = f(n-1) * 2 f(1) = 1這也就是迭代法了,而如果用編程來實現,其實就是實現一個循環運算的過程。
用 Python 實現這個計算麥子的代碼如下所示:
def get_number_of_wheat(grid):'''計算放到給定格子數量需要的麥子數量:param grid: 格子數:return:'''# f(1) = 1wheat_numbers = 1sums = wheat_numbersfor i in range(2, grid+1):wheat_numbers *= 2sums += wheat_numbersprint('when grid = %d, wheats numbers = %d' % (grid, sums))return sums簡單的測試例子:
if __name__ == '__main__':print('compute numbers of wheat!')numbers_grid = 63get_number_of_wheat(numbers_grid)print('finish')給定格子數量是 63 個,輸出結果如下:
compute numbers of wheat! when grid = 63, wheats numbers = 9223372036854775807 finish所以這個天文數字是 19 位數--9223372036854775807,真的是非常的多!假設一袋 50 斤的麥子估計有 130 萬粒麥子,那么這個計算結果是相當于 70949 億袋 50 斤的麥子!
迭代法的應用
看完上述例子,相信應該對迭代法的基本概念比較了解了,而迭代法的基本步驟也很簡單,分為三個步驟:
- 確定用于迭代的變量。上述例子中,這個迭代變量就是f(n)和f(n-1)
- 建立迭代變量之間的遞推關系。上述例子中,這個遞歸關系是f(n)=f(n-1)*2
- 控制迭代的過程。這里需要確定迭代的初始條件和終止條件,上述例子,初始條件就是f(1)=1,而終止條件就是達到給定的格子數了。
那么迭代法有什么應用呢?
其實,它在數學和計算機領域都有很廣泛的應用,如:
- 求數值的精確或者近似解。典型的方法包括二分法(Bisection method)和牛頓迭代法(Newton's method);
- 在一定范圍內查找目標值。典型方法包括二分查找,其實也是二分法在搜索方面的應用;
- 機器學習算法中的迭代。比如 Kmeans 聚類算法(不斷迭代來對數據進行聚類)、馬爾科夫鏈(Markov chain)、梯度下降法(Gradient descent)等。迭代法在機器學習中有廣泛的應用,其實是因為機器學習的過程,就是根據已知數據和一定的假設,求一個局部最優解。迭代法可以幫助學習算法逐步搜索,直到發現這種解。
接下來會重點介紹求數值的解和查找匹配記錄,這兩個應用其實都是采用二分法來實現。
求方程的精確或者近似解
迭代法除了用于計算龐大的數字,還可以幫助我們進行無窮次地逼近,求得方程的精確或者近似解。
舉個例子,我們要計算一個給定的正整數n(n>1)的平方根,并且不能采用編程語言自帶的函數,應該如何計算呢?
首先我們可以明確的是,對于給定的正整數n,它的平方根肯定是小于它,但大于1,也就是這個平方根的取值范圍是 1 到 n ,在這個范圍內求一個數值的平方等于n。
這里就可以通過采用剛剛說的二分法。每次查看區間內的中間值,檢查它是否符合標準。
比如我們要求 10 的平方根,尋找的區間就是[1,10],第一個中間值就是(1+10)/2=11/2=5.5,而 5.5 的平方等于 30.25,明顯比 10 大,所以尋找區間變成 5.5 的左側,也就是[1, 5.5],中間值就是 3.25,但 3.25 的平方是 10.5625,依然大于 10,尋找區間變為[1, 3.25],中間值變為 2.125, 2.125 的平方是 4.515625,小于 10,所以區間就是[2.125, 3.25],這樣繼續尋找和計算中間值的平方,直到發現某個數的平方正好是 10。
具體步驟如下圖:
這里用代碼實現,如下圖所示:
def get_square_root(n, threshold, max_try):'''計算大于 1 的正整數的平方根:param n: 給定正整數:param threshold: 誤差的閾值:param max_try: 最大嘗試次數:return:'''if n <= 1:return -1.0# interval boundary 區間的左右邊界left = 1.0right = float(n)for idx in range(max_try):# 防止溢出middle = left + (right - left) / 2square = middle * middle# 誤差delta = abs(square / n - 1)if delta <= threshold:return middleelse:if square > n:right = middleelse:left = middlereturn -2.0簡單的測試例子:
square_root = get_square_root(10, 0.000001, 10000) if square_root == -1.0:print('please input a number > 1') elif square_root == -2.0:print('cannot find the square root') else:print('square root==', square_root)輸出結果是:
square root== 3.1622767448425293這里代碼中,設置了兩個控制迭代結束的參數:
查找匹配記錄
二分法通過迭代式逼近,不僅可以求得方程的近似解,還可以幫助查找匹配的記錄。
這里老師給的例子是在自然語言處理中,處理同義詞或者近義詞的擴展問題。這時,你是會有一個詞典,用于記錄每個單詞的同義詞或者近義詞。對于一個待查找單詞,我們需要在字典找到這個單詞,以及對應的所有同義詞和近義詞,然后進行拓展,例如對于單詞--西紅柿,它的同義詞包括了番茄和tomato。
詞典如下表格所示:
詞條同義詞1同義詞2同義詞3西紅柿番茄tomato...............
當處理文章的時候,遇到“西紅柿”這個單詞,就在字典里查找,返回“番茄”和“tomato"等同義詞或者近義詞,并添加到文章作為同義詞/近義詞的拓展。
這里要解決的問題就是如何在字典查詢匹配單詞的問題。一種做法就是哈希表。而如果不用哈希表的方法,還可以采用二分查找法。二分查找法進行字典查詢的思路如下:
相比于利用二分法查找方程解,二分查找必須要求數據是有序的!
用代碼實現如下:
def search_word(dictionary, word):'''查找匹配單詞:param dictionary: 排序后的字典:param word:待查找單詞:return:'''if dictionary is None:return Falseif len(dictionary) < 1:return Falseleft = 0right = len(dictionary) - 1while left <= right:middle = int(left + (right - left) / 2)if dictionary[middle] == word:return Trueelse:if dictionary[middle] > word:right = middle - 1else:left = middle + 1return False簡單的測試代碼:
print('find word in dictionary') dict_list = ['i', 'am', 'coder'] dict_list = sorted(dict_list) print('sorted dict:', dict_list) word_to_find = 'am' found = search_word(dict_list, word_to_find) if found:print('word "%s" found in dictionary--%s!' % (word_to_find, dict_list)) else:print('cannot find the word "%s"' % word_to_find)輸出結果:
find word in dictionary sorted dict: ['am', 'coder', 'i'] word "am" found in dictionary--['am', 'coder', 'i']! finish迭代法的介紹就到這里了!上述源代碼地址:
https://github.com/ccc013/CodesNotes/blob/master/Maths/lesson_iterations.py
總結
以上是生活随笔為你收集整理的迭代反投影法代码_程序员的数学笔记3--迭代法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 车险那个比较好,十大车险公司排行一览
- 下一篇: Ironic 安装和配置详解