當前位置:首頁 » 編程語言 » python動態規劃

python動態規劃

發布時間: 2023-09-11 22:07:08

1. 北大青鳥設計培訓:怎樣才能提高python運行效率

python逐漸走入人們的視線,成為熱門編程語言,隨之而來,加入python培訓的准程序員大軍也成為社會熱點。
Python具有許多其他編程語言不具備的優勢,譬如能通過極少量代碼完成許多操作,以及多進程,能夠輕松支持多任務處理。
除了多種優勢外,python也有不好的地方,運行較慢,下面電腦培訓http://www.kmbdqn.cn/為大家介紹6個竅門,可以幫你提高python的運行效率。
1.在排序時使用鍵Python含有許多古老的排序規則,這些規則在你創建定製的排序方法時會佔用很多時間,而這些排序方法運行時也會拖延程序實際的運行速度。
最佳的排序方法其實是盡可能多地使用鍵和內置的sort()方法。
2.交叉編譯你的應用開發者有時會忘記計算機其實並不理解用來創建現代應用程序的編程語言。
計算機理解的是機器語言。
為了運行你的應用,你藉助一個應用將你所編的人類可讀的代碼轉換成機器可讀的代碼。
有時,你用一種諸如Python這樣的語言編寫應用,再以C++這樣的語言運行你的應用,這在運行的角度來說,是可行的。
關鍵在於,你想你的應用完成什麼事情,而你的主機系統能提供什麼樣的資源。
3.關鍵代碼使用外部功能包Python簡化了許多編程任務,但是對於一些時間敏感的任務,它的表現經常不盡人意。
使用C/C++或機器語言的外部功能包處理時間敏感任務,可以有效提高應用的運行效率。
這些功能包往往依附於特定的平台,因此你要根據自己所用的平台選擇合適的功能包。
簡而言之,這個竅門要你犧牲應用的可移植性以換取只有通過對底層主機的直接編程才能獲得的運行效率。
4.針對循環的優化每一種編程語言都強調最優化的循環方案。
當使用Python時,你可以藉助豐富的技巧讓循環程序跑得更快。
然而,開發者們經常遺忘的一個技巧是:盡量避免在循環中訪問變數的屬性。
5.嘗試多種編碼方法每次創建應用時都使用同一種編碼方法幾乎無一例外會導致應用的運行效率不盡人意。
可以在程序分析時嘗試一些試驗性的辦法。
譬如說,在處理字典中的數據項時,你既可以使用安全的方法,先確保數據項已經存在再進行更新,也可以直接對數據項進行更新,把不存在的數據項作為特例分開處理。
6.使用較新的Python版本你要保證自己的代碼在新版本里還能運行。
你需要使用新的函數庫才能體驗新的Python版本,然後你需要在做出關鍵性的改動時檢查自己的應用。
只有當你完成必要的修正之後,你才能體會新版本的不同。

2. 如何提高python的運行效率

竅門一:關鍵代碼使用外部功能包

Python簡化了許多編程任務,但是對於一些時間敏感的任務,它的表現經常不盡人意。使用C/C++或機器語言的外部功能包處理時間敏感任務,可以有效提高應用的運行效率。這些功能包往往依附於特定的平台,因此你要根據自己所用的平台選擇合適的功能包。簡而言之,這個竅門要你犧牲應用的可移植性以換取只有通過對底層主機的直接編程才能獲得的運行效率。以下是一些你可以選擇用來提升效率的功能包:

Cython
Pylnlne
PyPy
Pyrex

這些功能包的用處各有不同。比如說,使用C語言的數據類型,可以使涉及內存操作的任務更高效或者更直觀。Pyrex就能幫助Python延展出這樣的功能。Pylnline能使你在Python應用中直接使用C代碼。內聯代碼是獨立編譯的,但是它把所有編譯文件都保存在某處,並能充分利用C語言提供的高效率。

竅門二:在排序時使用鍵

Python含有許多古老的排序規則,這些規則在你創建定製的排序方法時會佔用很多時間,而這些排序方法運行時也會拖延程序實際的運行速度。最佳的排序方法其實是盡可能多地使用鍵和內置的sort()方法。譬如,拿下面的代碼來說:

import operator
somelist = [(1, 5,]
在每段例子里,list都是根據你選擇的用作關鍵參數的索引進行排序的。這個方法不僅對數值類型有效,還同樣適用於字元串類型。

竅門三:針對循環的優化

每一種編程語言都強調最優化的循環方案。當使用Python時,你可以藉助豐富的技巧讓循環程序跑得更快。然而,開發者們經常遺忘的一個技巧是:盡量避免在循環中訪問變數的屬性。譬如,拿下面的代碼來說:

lowerlist = ['this', 'is', 'lowercase']
upper = str.upper
upperlist = []
append = upperlist.append
for word in lowerlist:
append(upper(word))
print(upperlist)
#Output = ['THIS', 'IS', 'LOWERCASE']
每次你調用str.upper, Python都會計算這個式子的值。然而,如果你把這個求值賦值給一個變數,那麼求值的結果就能提前知道,Python程序就能運行得更快。因此,關鍵就是盡可能減小Python在循環中的工作量。因為Python解釋執行的特性,在上面的例子中會大大減慢它的速度。

(注意:優化循環的方法還有很多,這只是其中之一。比如,很多程序員會認為,列表推導式是提高循環速度的最佳方法。關鍵在於,優化循環方案是提高應用程序運行速度的上佳選擇。)

竅門四:使用較新的Python版本

如果你在網上搜索Python,你會發現數不盡的信息都是關於如何升級Python版本。通常,每個版本的Python都會包含優化內容,使其運行速度優於之前的版本。但是,限制因素在於,你最喜歡的函數庫有沒有同步更新支持新的Python版本。與其爭論函數庫是否應該更新,關鍵在於新的Python版本是否足夠高效來支持這一更新。

你要保證自己的代碼在新版本里還能運行。你需要使用新的函數庫才能體驗新的Python版本,然後你需要在做出關鍵性的改動時檢查自己的應用。只有當你完成必要的修正之後,你才能體會新版本的不同。

然而,如果你只是確保自己的應用在新版本中可以運行,你很可能會錯過新版本提供的新特性。一旦你決定更新,請分析你的應用在新版本下的表現,並檢查可能出問題的部分,然後優先針對這些部分應用新版本的特性。只有這樣,用戶才能在更新之初就覺察到應用性能的改觀。

竅門五:嘗試多種編碼方法

每次創建應用時都使用同一種編碼方法幾乎無一例外會導致應用的運行效率不盡人意。可以在程序分析時嘗試一些試驗性的辦法。譬如說,在處理字典中的數據項時,你既可以使用安全的方法,先確保數據項已經存在再進行更新,也可以直接對數據項進行更新,把不存在的數據項作為特例分開處理。請看下面第一段代碼:

n = 16
myDict = {}
for i in range(0, n):
char = 'abcd'[i%4]
if char not in myDict:
myDict[char] = 0
myDict[char] += 1
print(myDict)
當一開始myDict為空時,這段代碼會跑得比較快。然而,通常情況下,myDict填滿了數據,至少填有大部分數據,這時換另一種方法會更有效率。

n = 16
myDict = {}
for i in range(0, n):
char = 'abcd'[i%4]
try:
myDict[char] += 1
except KeyError:
myDict[char] = 1
print(myDict)
在兩種方法中輸出結果都是一樣的。區別在於輸出是如何獲得的。跳出常規的思維模式,創建新的編程技巧能使你的應用更有效率。

竅門六:交叉編譯你的應用

開發者有時會忘記計算機其實並不理解用來創建現代應用程序的編程語言。計算機理解的是機器語言。為了運行你的應用,你藉助一個應用將你所編的人類可讀的代碼轉換成機器可讀的代碼。有時,你用一種諸如Python這樣的語言編寫應用,再以C++這樣的語言運行你的應用,這在運行的角度來說,是可行的。關鍵在於,你想你的應用完成什麼事情,而你的主機系統能提供什麼樣的資源。

Nuitka是一款有趣的交叉編譯器,能將你的Python代碼轉化成C++代碼。這樣,你就可以在native模式下執行自己的應用,而無需依賴於解釋器程序。你會發現自己的應用運行效率有了較大的提高,但是這會因平台和任務的差異而有所不同。

(注意:Nuitka現在還處在測試階段,所以在實際應用中請多加註意。實際上,當下最好還是把它用於實驗。此外,關於交叉編譯是否為提高運行效率的最佳方法還存在討論的空間。開發者已經使用交叉編譯多年,用來提高應用的速度。記住,每一種解決辦法都有利有弊,在把它用於生產環境之前請仔細權衡。)

在使用交叉編譯器時,記得確保它支持你所用的Python版本。Nuitka支持Python2.6, 2.7, 3.2和3.3。為了讓解決方案生效,你需要一個Python解釋器和一個C++編譯器。Nuitka支持許多C++編譯器,其中包括Microsoft Visual Studio,MinGW 和 Clang/LLVM。

交叉編譯可能造成一些嚴重問題。比如,在使用Nuitka時,你會發現即便是一個小程序也會消耗巨大的驅動空間。因為Nuitka藉助一系列的動態鏈接庫(DDLs)來執行Python的功能。因此,如果你用的是一個資源很有限的系統,這種方法或許不太可行。

3. Python之動態規劃演算法

動態規劃演算法中是將復雜問題遞歸分解為子問題,通過解決這皮拆些子問題來解決復雜問題。與遞歸演算法相比,動態編程減少了堆棧的使用,避免了重復的計算,效率得到顯著提升。

先來看一個簡單的例子,斐波那契數列.

斐波那契數列的定義如下。

斐波那契數列可以很容易地用遞歸演算法實現:

上述代碼,隨燃旁棗著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運行通過。

4. Python編程題求助

該答案為組合數學中著名的卡特蘭數,其通式為C(2n,n)-C(2n,n-1)

這里採用遞推關系求解,即動態規劃的方法

設n對父子有d[n]種出場策略,注意初值d[0]=1

因為每個孩子前面必有一個父親與之對應

對於i對父子,遍歷第j個孩子,該孩子前面有j-1個孩子,對應d[j-1]種出場策略

後面有i-j個孩子,對應d[i-j]種出場策略,則d[i]+=d[j-1]*d[i-j],最終d[n]即為所求

python代碼如下:

n = int(input())

d = [0] * (n+1)

d[0] = 1

for i in range(n+1):

for j in range(i+1):

d[i] += d[j-1] * d[i-j]

print(d[n])

運行結果如下:

望採納~

熱點內容
ftp對象控制 發布:2025-03-10 23:48:06 瀏覽:327
手機配置哪些不能給別人看 發布:2025-03-10 23:47:28 瀏覽:468
通常在哪個目錄存放配置文件信息 發布:2025-03-10 23:42:25 瀏覽:197
ftp伺服器什麼意思 發布:2025-03-10 23:42:17 瀏覽:862
黑魂2腳本 發布:2025-03-10 23:30:45 瀏覽:51
安卓導航手剎設置在哪裡 發布:2025-03-10 23:29:07 瀏覽:33
如何配置一套網站系統 發布:2025-03-10 23:28:53 瀏覽:92
更相見演算法 發布:2025-03-10 23:24:59 瀏覽:293
演算法門 發布:2025-03-10 22:59:58 瀏覽:178
linux更改用戶目錄 發布:2025-03-10 22:57:38 瀏覽:190