C++——《算法分析與設計》實驗報告——最長公共子序列問題

實驗名稱: 最長公共子序列問題

實驗地點:

實驗目的:

理解動態規劃算法的概念;

掌握動態規劃算法的基本要素;

掌握設計動態規劃算法的步驟;

通過應用範例學習動態規劃算法的設計技巧與策略;

 

實驗原理

動態規劃(dynamic programming)是運籌學的一個分支,是求解決策過程(decision process)最優化的數學方法。20世紀50年代初美國數學家R.E.Bellman等人在研究多階段決策過程(multistep decision process)的優化問題時,提出了著名的最優化原理(principle of optimality),把多階段過程轉化爲一系列單階段問題,利用各階段之間的關係,逐個求解,創立了解決這類過程優化問題的新方法——動態規劃。1957年出版了他的名著Dynamic Programming,這是該領域的第一本著作。

算法總體思想:

1)動態規劃算法與分治法類似,其基本思想也是將待求解問題分解成若干個子問題,先求解子問題,然後從這些子問題的解得到原問題的解。

2)與分治法不同的是,適合於用動態規劃法求解的問題,經分解得到的子問題往往不是獨立的。子問題中存在大量的公共子問題,在分治求解過程中被多次重複計算,保存計算結果,爲後面的計算直接引用,減少重複計算次數這就是動態規劃的基本思想。

3)用動態規劃算法求解問題,可依據其遞歸式以自底向上的方式進行計算。在計算過程中,保存已解決的子問題的答案。每個子問題只計算一次,而在後面需要時只要簡單查一下,從而避免大量重複計算,最終得到多項式時間算法。

動態規劃基本步驟:

找出最優解的性質,並刻畫其結構特徵。

遞歸地定義最優值。

以自底向上的方式計算出最優值。

根據計算最優值時得到的信息,構造最優解。

前三個步驟是動態規劃算法的基本步驟。在只需求出最優值的情況,步驟四可以省去。若需要求最優解,則必須執行步驟四,根據所記錄的信息,快速構造出最優解。

 

實驗內容:

1、使用動態規劃算法解決最長公共子序列問題:給定兩個序列X={x1,x2,…,xm}和Y={y1,y2,…,yn},找出X和Y的最長公共子序列。。

2、通過上機實驗進行算法實現。

3、保存和打印出程序的運行結果,並結合程序進行分析,上交實驗報告。

 

源程序:

#include <iostream>
#include <string>
#include <stack>
using namespace std;
void LCS(string s1,string s2)
{
    int m=s1.length()+1;
    int n=s2.length()+1;
    int c[m][n];
    int b[m][n];
    for(int i=0;i<m;i++)
    {
        for(int j=0;j<n;j++)
            b[i][j]=0;
    }
    for(int i=0;i<m;i++)
        c[i][0]=0;
    for(int i=0;i<n;i++)
        c[0][i]=0;
    for(int i=0;i<m-1;i++)
    {
        for(int j=0;j<n-1;j++)
        {
            if(s1[i]==s2[j])
            {
                c[i+1][j+1]=c[i][j]+1;
                b[i+1][j+1]=1;         
            }
            else if(c[i][j+1]>=c[i+1][j])
            {
                c[i+1][j+1]=c[i][j+1];
                b[i+1][j+1]=2;        
            }
            else
            {
                c[i+1][j+1]=c[i+1][j];
                b[i+1][j+1]=3;      
            }
        }
    }
    stack<char> same;                  
    stack<int> same1,same2;          
    for(int i = m-1,j = n-1;i >= 0 && j >= 0; )
    {
        if(b[i][j] == 1)
        {
            i--;
            j--;
            same.push(s1[i]);
            same1.push(i);
            same2.push(j);
        }
        else if(b[i][j] == 2)
                i--;
             else
                j--;
    }
    cout<<endl<<"最長公共子序列爲:";
    while(!same.empty())
    {
        cout<<same.top();
        same.pop();
    }
    cout<<endl<<"長度爲:"<<c[m-1][n-1]<<endl;
}
int main()
{
	string s1="ABCPDSFJGODIHJOFDIUSHGD";
    string s2="OSDIHGKODGHBLKSJBHKAGHI";
	cout<<"第一個字符串"<<endl;
	cin>> s1; 
    cout<<"第二個字符串"<<endl;
	cin>> s2; 
    LCS(s1,s2);
    return 0;
}

 

 

 

實驗結果:

 

心得與體會:

  1. 理解動態規劃算法的概念;
  2. 掌握動態規劃算法的基本要素;
  3. 掌握設計動態規劃算法的步驟;
  4. 通過應用範例學習動態規劃算法的設計技巧與策略;

 

參考文章

https://blog.csdn.net/weixin_40673608/article/details/84262695

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章