日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

算法运行时间计算

發布時間:2023/12/20 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法运行时间计算 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

摘自《數據結構和算法分析》Java語言描述

如果認為兩個程序花費大致相同的時間,要確定哪個程序更快的最好辦法很可能是將他們編碼并運行。

一般地,存在集中算法思想,而我們總愿意盡早除去那些不好的算法思想,因此,通常需要分析算法.不僅如此,進行分析的能力。不僅如此,進行分析的能力常常提供對于計算優先算法的動產能力。一般來說,分析還能準確地確定瓶頸,這些地方值得仔細編碼。

為了簡化分析,我們將采納如下的約定:不存在特定的時間單位。因此我們拋棄一些前導的常數,我們還將拋棄低階項,從而要做的事計算大O運行時間。由于大O是一個上界,因此我們必須仔細,絕不要低估程序的運行時間。實際上,分析的結果為程序在一定時間范圍內能夠終止運行提供了保障。程序可能提前結束,但是絕不可能錯后。

?一個簡單的例子:1^3+2^3+3^3+4^3+……+n^3+……

public static int sum(int n) {int partialSum;partialSum = 0;for (int i = 1; i <= n; i++) {partialSum += i *i * i;}return partialSum; }

對這個程序段的分析是簡單的。所有的聲明均不計時間。partialSum = 0和return partialSum各占一個時間單位。partialSum += i *i * i每執行一次占用4個時間單元(兩次乘法,一次加法和一次賦值),而執行N次共占4N個時間單元。for循環在初始化i、測試i<=N和對i的自增運算隱含著開銷。所有這些總開銷是初始化一個時間單元,所有測試為N+1個單位時間,而所有的自增運算為N個單位時間,共2N+2個時間單元。我們忽略調用方法和返回值的開銷,得到的總量是6N+4個時間單元。因此我們說該方法是O(N)。

如果每次分析一個程序都要演示所有的這些工作,那么這項任務很快就會變成負擔。由于我們有了大O的結果,因此就存在許多可以采取的捷徑并且不影響最后的結果。例如每次都執行的partialSum += i *i * i的時間明顯是類似O(1),至于精確計算它究竟是2、3、或者4等是愚蠢的,因為這無關緊要。而int partialSum和for循環顯然是不重要的,所以在這里話費時間是不明智的。這使我們得到若干法則。

法則1——for循環

一個for循環的運行時間至多使該for循環內部那些語句的運行時間乘以迭代的次數。

法則2——嵌套的for循環

從里向外分析這些循環。在一組嵌套循環內部的一條語句總的運行時間為該語句的運行時間乘以該組所有的for循環的大小的乘積。例如下列程序片段為O(N^2)

for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)System.out.println();

法則3——順序語句

將各個語句的運行時間求和即可(這意味著,,其中的最大值就是所得的運行時間)例如,下面的程序片段顯示花費O(N),接著使O(N^2),因此總量也是O(N^2),而忽略O(N)

for (int i = 1; i < n; i++) {System.out.println(); } for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)System.out.println();

法則4——if/else語句

if(condition)S1 else S2

一個if/else語句的運行時間從不超過判斷的運行時間再加上S1和S2中運行時間長者的總的運行時間,即運行時間不會超過 判斷運行時間加上S1或者S2中較大的運行時間。

…………

其他的法則都是冥想的,但是分析的基本策略使從內部(或最深層部分)向外開展工作的。如果有方法調用,那么要首先分析這些調用。如果有遞歸過程,那么存在幾種情況:若遞歸實際上只是被薄面紗遮住的for循環(很容易轉換成for循環),則分析很簡單。如下面遞歸實際上就是一個for循環:

public static long factorial(int n) {if (n <= 1)return 1;elsereturn n * factorial(n - 1); }

這是一個特殊的例子,但當遞歸被正常使用時,很難將其轉換成循環結構。這種情況下,分析將設計求解一個遞推關系。

public static long fib(int n) {if (n <= 1)return 1;elsereturn fib(n - 1) + fib(n - 2); }

如果將程序編碼并使N為40左右運行,程序效率特別低。令T(N)為調用函數fib(n)的運行時間。如果N=0或者N=1,則運行時間是個常數,因為常數不重要并且為了方便計算,我們可以將T(0)=T(1)=1。對于N的其他值的運行時間則都是基于基準情形的運行時間來度量的。若N>2,則執行時間是判斷時間加上else語句上的執行時間,而else語句有一次家發和兩次方法調用組成。第一次方法調用是fib(n-1),及T(N-1)運行時間。以此類推可以得到fib(n)的運行時間:
T(N)=T(N-1)+T(N-2)+2 并且

fib(N)=fib(N-1)+fib(N-2)

由歸納法很容易的可以得出T(N)>=fib(N)的結論。而由fib(N)=fib(N-1)+fib(N-2)使用歸納法可以得出fib(N)>=(3/2)^N,及可得出T(N)>=(3/2)^N,可以看出運行時間以指數的速度增長。

這個程序之所以運行緩慢,是因為存在大量多余的工作要做。在fib(n - 1) + fib(n - 2)語句中,fib(n - 1)調用的時候實際上已經計算過一次fib(n - 2),而這個信息被拋棄,之后在+之后又計算了一次fib(n - 2)。這些拋棄的信息遞歸地合起來就導致了巨大的運行時間。這或許是“計算任何事情不要超過一次”的最好的實例,但它不應使你被嚇得遠離遞歸而不敢使用。

?

總結

以上是生活随笔為你收集整理的算法运行时间计算的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。