- 1、#Python乾貨#python實現——最優化演算法
- 2、python中有哪些簡單的演算法?
- 3、Python之動態規劃演算法
函數詳見rres,此代碼使該演算法運行了兩次
收穫:
這是我第一個實現的代碼。學習完該演算法以後,邏輯框架基本上就有了,剩下需要明確的就是對應的python的語言。於是我就開始了查找「如何定義函數」(詳見mofan的優酷),「循環體」和「if條件語句」的格式()「數學符號」(詳見mofan的優酷),以及print的使用
1.def是python中指定義,一般用來定義函數,如果需要深度學習搭建網路可用來定義網路。值得注意的一點是
我不清楚為什麼,但是如果沒有加的話,那個函數公式就是一個花瓶,就像一個結果輸不出去。
2.最坑的就是邏輯。一開始邏輯沒理清楚,或者說在代碼上有疏漏,導致我將left和right放在了循環體里,結果可想而知。不過也是因為這個錯誤,我知道pycharm中的debug怎麼用,挺簡單的,百度一下就出來了。
3.不知道什麼原因,看的莫煩視頻中的print多個變數一起輸出是沒有辦法在我的pycharm中使用的,出來的結果很奇怪。可能是因為我是win10不是ios吧。print如果多個變數一起輸出必須是print(“名字:%s,名字2:%s”%(a,b))結果輸出就是名字:a ,名字2:b
關於python中數據變數。第一遍運行結果出現很明顯不對,於是我採用了debug。結果發現,mid1處一直為1而不是1.5,於是就開始了解數據變數。起初我猜測python默認所有變數為整型,但是根據二分法的結果我意識到此猜測不對,所以要改整個file的變數格式沒有必要。所以我就在mid1式子前面加了一個float,結果就顯示為1.5了。但是如果我將整個式子用()括起來,前面加float,結果還是1。我不太理解為什麼。不過我知道了python的數據格式是根據輸入量決定的,也就是說你的輸入量如果是整型,那麼與其直接相關的計算輸出結果一定是整型,而且還是不採用進位的整型。在我沒有採用+float/+.0這兩種方法之前,mid1~3全部是整型。
或者不再mid1前面加float,直接將輸入量後面點個點就行
真的很想吐槽一下print,好麻煩啊啊啊啊每次都得弄個%s,而且有時候還不能放一起!!!!
不要問我掌握了什麼,要問我現在寫完這個代碼後有多麼的愛python的精度表示 :-)我決定以後只要再編寫數學公式的代碼都將輸入量的小數學點後面補很多0
fibonacci函數定義,每次debug後我的手都是抖的O( _ )O~
不知道自己什麼時候有的強迫症,只要是代碼下面有「~」我就必須要消掉。笑哭。這個很簡單,前四個除了費波納茨,都很簡單。
這個公式看起來很麻煩,便寫的時候更要謹慎。我上回把那個2擱在了分號下面,結果很大,所以還是換算成0.5更好(PS:勿忘那長河般的0)。
雖然代碼很長,但是主要是因為print太多。本打算在開頭print,最後結果會漏掉最後一部分。懶得想其他辦法了,直接就這樣吧
一開始while裡面寫成了,導致run不出來。繼而,debug也沒法用。在網上一查才知道 「沒聯網」+「沒選斷點」。最後想嘗試將else裡面的內容輸出來,結果發現run以後被刷屏了。於是改成i7以後還是不行,於是想著加一個break跳出循環,結果成效了。
然後剛剛由debug了一下,才知道原來是i+1在if裡面,因為沒有辦法+1,所以i=6一直存在,就不斷循環。因為加break也好,i+1也好,都可以。
這是我第一組自己實現的python代碼,就是數學公式用python語言組裝起來。剛開始的時候知道大概需要在語言中體現什麼,但不太清楚。於是我就在網上找了幾個二分法的,他們都各有不同,但框架都差不多,不過如果要用到我們的那個公式里還需要改變很多。然後我就開始分析我們的題,我發現大體需要兩部分,一部分函數定義,一部分循環體。但我不知道如何定義函數,如何寫數學公式,如何弄變數,也就是說一些小點不太會,所以我選擇直接百度。因為我知道自己閱讀的能力不錯,相比於從視頻中提取要素,我更擅長通過閱讀獲得要點。有目的性地找知識點,掌握地更牢固。
於是我就開始了第一個——二分法的編寫。我發現,自己出現了很多錯誤而且有很多地方都很基礎。但我依然沒選擇視頻,而是將這些問題直接在百度上找,因為視頻講完或許你也沒找到點。當然,這是一步一步走的,不是直接就將程序擺上去,一點一點改。
隨著前兩個的成功,我發現自己對於這些代碼有了自信,似乎看透了他們的偽裝,抓住了本質。除此之外,我還意識到自己自從8月份以後,學習能力似乎提高了不少,而且有了更為有效的學習方法。各方面都有了一定的覺醒。除了第一個找了幾個牛頭不對馬嘴的代碼,其他都是根據自己的邏輯寫,邏輯通下來以後,對應語言中某一部分不知道如何翻譯就去百度,其實這幾個套路都一樣或者說數學公式轉化的套路都一樣。
我還意識到,彙編其實是最難的語言,目前為止所學到的,因為很多都需要自己去定義,去死摳,需要記住大量的指令且不能靈活變通。但是其他的卻只需要將一些對應的記下來就好。python真的挺簡單的。而且,我發現自己今天似乎打開了新世界的大門,我愛上了這種充滿了靈性的東西,充滿了嚴謹的美麗,還有那未知的變化,我發現我似乎愛上了代碼。可能不僅僅局限於python,這些語言都充滿了挑戰性。我覺得當你疑惑的時候,就需要相信直覺,至少我發現它很准
Python中的基礎演算法有以下幾種:
基礎加減乘除演算法:
加法 2 + 2;
減法 2 – 2;
乘法 2 * 2;
除法 2 / 2。
整除運算:
第一種 2 / 3 整型與整型相除,獲取整數,條件是除數被除數都是整數;
第二種 2 // 3 雙斜杠整除演算法,只獲取小數點前的部分整數值。
冥運算:
例子1: 2 ** 3;
例子2; -2 ** 3;
例子3: (-2) ** 3
動態規劃演算法中是將複雜問題遞歸分解為子問題,通過解決這些子問題來解決複雜問題。與遞歸演算法相比,動態編程減少了堆棧的使用,避免了重複的計算,效率得到顯著提升。
先來看一個簡單的例子,斐波那契數列.
斐波那契數列的定義如下。
斐波那契數列可以很容易地用遞歸演算法實現:
上述代碼,隨著n的增加,計算量呈指數級增長,演算法的時間複雜度是 。
採用動態規劃演算法,通過自下而上的計算數列的值,可以使演算法複雜度減小到 ,代碼如下。
下面我們再看一個複雜一些的例子。
這是小學奧數常見的硬幣問題: 已知有1分,2分,5分三種硬幣數量不限,用這些硬幣湊成為n分錢,那麼一共有多少種組合方法。
我們將硬幣的種類用列表 coins 定義;
將問題定義為一個二維數組 dp,dp[amt][j] 是使用 coins 中前 j+1 種硬幣( coins[0:j+1] )湊成總價amt的組合數。
例如: coins = [1,2,5]
dp[5][1] 就是使用前兩種硬幣 [1,2] 湊成總和為5的組合數。
對於所有的 dp[0][j] 來說,湊成總價為0的情況只有一種,就是所有的硬幣數量都為0。所以對於在有效範圍內任意的j,都有 dp[0][j] 為1。
對於 dp[amt][j] 的計算,也就是使用 coins[0:j+1] 硬幣總價amt的組合數,包含兩種情況計算:
1.當使用第j個硬幣時,有 dp[amt-coins[j]][j] 種情況,即amt減去第j個硬幣幣值,使用前j+1種硬幣的組合數;
2.當不使用第j個硬幣時,有 dp[amt][j-1] 種情況,即使用前j種硬幣湊成amt的組合數;
所以: dp[amt][j] = dp[amt – coins[j]][j]+dp[amt][j-1]
我們最終得到的結果是:dp[amount][-1]
上述分析省略了一些邊界情況。
有了上述的分析,代碼實現就比較簡單了。
動態規劃演算法代碼簡潔,執行效率高。但是與遞歸演算法相比,需要仔細考慮如何分解問題,動態規劃代碼與遞歸調用相比,較難理解。
我把遞歸演算法實現的代碼也附在下面。有興趣的朋友可以比較一下兩種演算法的時間複雜度有多大差別。
上述代碼在Python 3.7運行通過。
原創文章,作者:簡單一點,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/126749.html