求序列的最大子序列

看《編程珠璣》一書,講解求序列的最大子序列。

問題: 給定一個實數序列x1,x2,…,xn(不必是正數),尋找一個連續的子序列xi,x(i+1),…,xj,使得其數值之和在所有連續子序列數值之和中是最大的。

 算法1

思路:比較所有連續序列數值的和,找到最大的。

1. maxsofar=0;

2. for i=[0,n)

3.   sum=0;

4.   for j=[i,n)

5.      sum=sum+x[j];  

6.      maxsofar=max(sum,maxsofar);

算法複雜度是O(n2)。

 

算法2

思路:在算法1的基礎上改進。算法1中,第5行要重複求和。用一個數組預先存放從數組第一個元素開始到各個元素之間所有元素的和。比如定義數組 a[n+1],

a[0]=0,a[i]=x0+x1+…+x(i-1),(1=<i<=n)。

 

a[0]=0;

for i=[1..n]

   a[i]=a[i-1]+x[i-1];

maxsofar=0;

for i=[0,n)

sum=0;

for j=[i,n)

    sum=a[j+1]-a[i];

    maxsofar=max(sum,maxsofar).

 

算法複雜度是O(n2)。

 

算法3

思路:運用歸納法的思想。如果已知x[0…i-1]的最大子序列,那麼能知道x[0…i]的最大子序列嗎?所有不包含x[i]的子序列最大的就是x[0…i-1]的最大子序列,假設爲S(i-1),因此,找到包含x[i]的子序列的最大子序列,然後用這個子序列和S(i-1)比較得到x[0..i]的最大子序列。

 

剛開始我寫出來的算法:

a[0]=0;

for i=[1..n]

   a[i]=a[i-1]+x[i-1];

maxsofar=0;

for i=[0…n)

sum=0;

for j=[0..i-1)

    sum=max(sum,a[i+1]-a[j])

     maxsofar=max(maxsofar,sum);

算法複雜度O(n2)。

其算法複雜度跟上面的一樣。似乎沒有改進。問題出在計算包含xi的最大子序列。我開始簡單看過程序,這個計算過程沒有這麼複雜。我在想是不是也用歸納法試試求這個最大子序列。

如果 x0,x1,…x(i-1)已經知道了包含x(i-1)的最大子序列S(i-1),那麼如何能求x0,x1,…,xi,包含xi的最大子序列?包含xi的一個子序列=包含x(i-1)的子序列+xi,其中變化的是“包含x(i-1)的子序列”,不變的是xi,因此max(包含xi的一個子序列)=max(包含x(i-1)的子序列)+xi,當然如果max(包含x(i-1)的子序列)+xi < 0,則max(包含xi的一個子序列)=0,所以,

max(包含xi的一個子序列)=max(max(包含x(i-1)的子序列)+xi,0)。

這樣程序就變更新爲:

 

maxsofar=0;

maxtoend=0;

for i=[0…n)

maxtoend=max(maxtoend+x[i],0);

maxsofar=max(maxsofar,maxtoend);

算法複雜度是O(n)。

 

求最大子序列算法的歷史:

布朗大學的UIf Grenander所面對的模式匹配問題中:最初的問題所描述的是二維數組。因爲二維問題要求的時間太多以至於不能解決,所以Grenander將它簡化爲一維以對其結構有更好的瞭解。開始Grenander提出了O(n3)的算法(參加《編程珠璣》第8章),後來提出了O(n2)的算法。

他於1977年將該問題描述給Michael Shamos,這個傢伙花一個通宵設計了分治的算法。不久以後,當Shamos向Bentley介紹這個問題時,他們一致認爲那也許是可能的算法中最快的。

Shamos出息Carnegie Mellon研討會,在該會議上向統計學家Jay Kadane描述了該問題以及相關歷史,Jay Kadeane不出幾分鐘就給出了歸納算法的提綱。

 

現在我們看到歸納算法很簡單,雖然Jay Kadane很快發現了這個問題,但是當時Ulf Grenander,Michael Shamos以及Bentley三個聰明的人也沒有“顯而易見”地發現這個算法。由此可見一個方法的發現並非是那麼容易的。我們在解決問題時,同樣也並非輕而易舉的就能發現問題的解決方法。當我們沒有解決一個問題時,完全不需要失望、沮喪,那是我們可能沒有具備相關的知識、背景,靈活運用知識的能力不是突出等等客觀原因所致。要看到我們必然能解決很多的其它問題,保持對自己的信任、保持學習的熱情,這樣自己的能力必然會有增強。


發佈了36 篇原創文章 · 獲贊 3 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章