算法設計課程報告(C++實現貪心算法)

聲明:本報告比較簡單,僅供參考哦!!

報告內容(主要包括四個方面的內容):

1、算法設計簡介;

2、可以自行選擇幾種感興趣的算法進行簡介和分析;也可以針對以下給出的算法設計題,任選一題,完成編碼任務,給出運行結果;

3、學習算法的心得體會;

4、參考文獻

最小正整數問題

問題描述:鍵盤輸入一個高精度的正整數 n(n<10位 ) , 去掉任意 s 個數字後剩下的數字按原左右次序組成一個新的正整數,尋求一種方案,使得新的正整數最小。

問題分析

1) 貪心法求解:刪 k 個數符的全局最優解,包含了刪除 1個數符的子問題的最優解。

2) 以字符串形式輸入 s ,使用盡可能逼近目標的貪心法來逐一刪去其中的 k 個數符, 每一步總是選擇一個能使剩下的數最小的數符刪去。


 

 

摘要:算法是解決特定問題的描述,在計算機領域當中,算法顯得尤爲重要。本文就算法的定義、特徵以及發展歷程進行描述,並列舉了常見的算法思想。然後利用貪心算法來解決實際問題,最後談談自己學習貪心算法心得體會。

關鍵詞:算法定義;算法特徵;算法發展歷程;貪心算法;心得體會

 

目錄

1 算法設計簡介

1.1 算法的定義

1.2 算法的特徵

1.3 算法的發展流程

1.4 常見的算法

1.4.1 遞歸法

1.4.2 枚舉法

1.4.3 迭代法

2 貪心算法

2.1 貪心算法簡介

2.2 貪心算法的基本要素

2.3 貪心算法的問題描述

2.4 編碼實現

2.5 運行結果

3 學習心得體會

參考文獻


 

1 算法設計簡介

1.1 算法的定義

算法是解決特定問題求解決步驟的描述,再計算機中表現爲指令的有限序列,並且每條指令表示一個或多個操作。

不同的算法可能用不同的時間、空間或效率來完成同樣的任務。一個算法的優劣可以用空間複雜度與時間複雜度來衡量。

算法的時間複雜度是指執行算法所需要的計算工作量。一般來說,計算機算法是問題規模n 的函數f(n),算法的時間複雜度也因此記做T(n)=Ο(f(n))。而算法的空間複雜度是指算法需要消耗的內存空間。其計算和表示方法與時間複雜度類似,一般都用複雜度的漸近性來表示。同時間複雜度相比,空間複雜度的分析要簡單得多。

另外,算法的正確性、可讀性以及健壯性也是判定算法優劣的重要標準。

1.2 算法的特徵

算法的特徵可分爲輸入、輸出、有窮性、確定性以及可行性。

  1. 輸入:算法具有零個或多個輸入
  2. 輸出:算法至少有一個或多個輸出
  3. 有窮性:指算法再執行有限的步驟之後,自動結束而不會出現無心循環,並且每一個步驟再可接受的時間內完成
  4. 確定性:算法的每一個步驟都具有確定的意義,不會出現二義性
  5. 可行性:算法的每一步都必須是可行的,也就是說,每一步都能通過執行有限次數完成

 

1.3 算法的發展流程

算法思想源遠流長,中國古代數學中就蘊涵了豐富的算法思想。隨着現代信息技術飛速發展,算法在科學技術、社會發展中發揮着越來越大的作用,並且日益融入社會生活的許多方面,算法思想已成爲現代人應具備的一種數學素養。希望通過本專題內容的學習,理解算法思想的特點,瞭解中學數學對算法教學的要求。

“算法”的英文名稱Algorithm 來自於9世紀波斯數學家al-Khwarizmi,因爲al-Khwarizmi在數學上提出了算法這個概念。“算法”原爲"algorism",意思是阿拉伯數字的運算法則,在18世紀演變爲"algorithm"。歐幾里得算法被人們認爲是史上第一個算法。 第一次編寫程序是Ada Byron於1842年爲巴貝奇分析機編寫求解伯努利方程的程序,因此Ada Byron被大多數人認爲是世界上第一位程序員。因爲查爾斯·巴貝奇(Charles Babbage)未能完成他的巴貝奇分析機,這個算法未能在巴貝奇分析機上執行。 因爲"well-defined procedure"缺少數學上精確的定義,19世紀和20世紀早期的數學家、邏輯學家在定義算法上出現了困難。20世紀的英國數學家圖靈提出了著名的圖靈論題,並提出一種假想的計算機的抽象模型,這個模型被稱爲圖靈機。圖靈機的出現解決了算法定義的難題,圖靈的思想對算法的發展起到了重要作用。

1.4 常見的算法

 常見的算法有遞推法、遞歸法、枚舉法,貪心算法、回溯法以及迭代法等。下面簡單介紹幾個常見的算法:遞歸法、枚舉法以及迭代法。本報告選取的題目是關於貪心算法的,下面會具體介紹。

1.4.1 遞歸法

程序調用自身的編程技巧稱爲遞歸(recursion)。一個過程或函數在其定義或說明中有直接或間接調用自身的一種方法,它通常把一個大型複雜的問題層層轉化爲一個與原問題相似的規模較小的問題來求解,遞歸策略只需少量的程序就可描述出解題過程所需要的多次重複計算,大大地減少了程序的代碼量。遞歸的能力在於用有限的語句來定義對象的無限集合。一般來說,遞歸需要有邊界條件、遞歸前進段和遞歸返回段。當邊界條件不滿足時,遞歸前進;當邊界條件滿足時,遞歸返回。

1.4.2 枚舉法

在進行歸納推理時,如果逐個考察了某類事件的所有可能情況,因而得出一般結論,那麼這結論是可靠的,這種歸納方法叫做枚舉法。枚舉法是利用計算機運算速度快、精確度高的特點,對要解決問題的所有可能情況,一個不漏地進行檢驗,從中找出符合要求的答案,因此枚舉法是通過犧牲時間來換取答案的全面性。

1.4.3 迭代法

迭代法也稱輾轉法,是一種不斷用變量的舊值遞推新值的過程,跟迭代法相對應的是直接法(或者稱爲一次解法),即一次性解決問題。迭代法又分爲精確迭代和近似迭代。“二分法”和“牛頓迭代法”屬於近似迭代法。迭代算法是用計算機解決問題的一種基本方法。它利用計算機運算速度快、適合做重複性操作的特點,讓計算機對一組指令(或一定步驟)進行重複執行,在每次執行這組指令(或這些步驟)時,都從變量的原值推出它的一個新值。

 

2 貪心算法

 

2.1 貪心算法簡介

 

貪心算法是一種對某些求最優解問題的更簡單、更迅速的設計技術。用貪心法設計算法的特點是一步一步地進行,常以當前情況爲基礎根據某個優化測度作最優選擇,而不考慮各種可能的整體情況,它省去了爲找最優解要窮盡所有可能而必須耗費的大量時間,它採用自頂向下,以迭代的方法做出相繼的貪心選擇,每做一次貪心選擇就將所求問題簡化爲一個規模更小的子問題, 通過每一步貪心選擇,可得到問題的一個最優解,雖然每一步上都要保證能獲得局部最優解,但由此產生的全局解有時不一定是最優的,所以貪心法不要回溯。

貪心算法是一種改進了的分級處理方法,其核心是根據題意選取一種量度標準,然後將這多個輸入排成這種量度標準所要求的順序,按這種順序一次輸入一個量,如果這個輸入和當前已構成在這種量度意義下的部分最佳解加在一起不能產生一個可行解,則不把此輸入加到這部分解中。這種能夠得到某種量度意義下最優解的分級處理方法稱爲貪心算法。

對於一個給定的問題,往往可能有好幾種量度標準。初看起來,這些量度標準似乎都是可取的,但實際上,用其中的大多數量度標準作貪心處理所得到該量度意義下的最優解並不是問題的最優解,而是次優解。因此,選擇能產生問題最優解的最優量度標準是使用貪心算法的核心。

一般情況下,要選出最優量度標準並不是一件容易的事,但對某問題能選擇出最優量度標準後,用貪心算法求解則特別有效。

 

2.2 貪心算法的基本要素

 

1.貪心選擇性質。所謂貪心選擇性質是指所求問題的整體最優解可以通過一系列局部最優的選擇,即貪心選擇來達到。這是貪心算法可行的第一個基本要素,也是貪心算法與動態規劃算法的主要區別。動態規劃算法通常以自底向上的方式解各子問題,而貪心算法則通常以自頂向下的方式進行,以迭代的方式作出相繼的貪心選擇,每作一次貪心選擇就將所求問題簡化爲規模更小的子問題。對於一個具體問題,要確定它是否具有貪心選擇性質,必須證明每一步所作的貪心選擇最終導致問題的整體最優解。

2.當一個問題的最優解包含其子問題的最優解時,稱此問題具有最優子結構性質。問題的最優子結構性質是該問題可用動態規劃算法或貪心算法求解的關鍵特徵。

2.3 貪心算法的問題描述

鍵盤輸入一個高精度的正整數 n(n<10位 ) , 去掉任意 s 個數字後剩下的數字按原左右次序組成一個新的正整數,尋求一種方案,使得新的正整數最小。

問題分析

1) 貪心法求解:刪 k 個數符的全局最優解,包含了刪除 1個數符的子問題的最優解。

2) 以字符串形式輸入 s ,使用盡可能逼近目標的貪心法來逐一刪去其中的 k 個數符, 每一步總是選擇一個能使剩下的數最小的數符刪去。

 

2.4 編碼實現

採用C語言編寫,具體代碼如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
  char s[150];
  int len,n;
  while(~scanf("%s %d",s,&n))
    {
       int i;
       while(n>0)
          {
             i=0;
             len=strlen(s);//每次重新定義長度
             while(i<len&&s[i]<=s[i+1])
                   {
                       i++;}
             while(i<len)
                {
                    s[i]=s[i+1];
                     i++;
                 }
                 n--;
    }
    while(s[0]=='0')
    {
        i=0;
        len=strlen(s);
        while(i<len)
        {
            s[i]=s[i+1];
            i++;
        }
    }
    len=strlen(s);
    if(len==0) printf("0\n");
    else printf("%s\n",s);
//另一種重要輸出方法,若爲printf("%s",&s[n]);表示輸出n之後的所有字符!!!!
}
    return 0;
}

 

2.5 運行結果

 

先輸入一串數字(小於10位數),接着輸入空格,再輸入要去除的個數,最後回車。下面給出兩個輸出案例,如圖1所示:

                                                                                     圖1 運行結果測試

3 學習心得體會

首先,算法在我看來主要就是一種解題思路,能夠幫我們更好的解決生活中的我們遇到的問題,解決我們遇到的各種問題,不只是現在學習的貪心算法,還有很多的其他的算法,比如:遞歸算法,迭代法等。

貪心算法主要的內容在我看來就是將複雜的問題轉化爲一步一步的小問題,再將這些簡化後的問題分別的求出解,再將這些解整合得出最優解,貪心算法不是從整體上考慮問題,它所做出的選擇只是在某種意義上的局部最優解,而由問題自身的特性決定了該題運用貪心算法可以得到最優解。

但是貪心算法的使用也是有界限的,不可能每一個的問題都能夠使用貪心算法來解決,因此在做相關的題目的時候就要先考慮該題是否能用貪心算法,還有就是如何使用貪心算法來得到最優解,貪心選擇性質是指所求問題的整體最優解可以通過一系列局部最優的選擇,即貪心選擇來達到。

貪心算法在使用的過程中有一點貪心算法的每一次操作都對結果產生直接影響,即每一次得到的結果是不能後退的,不能夠改變。對於上述的刪數問題,給我們的幾個數字我們要想得到的最小的數字,在我看來可以將其中的排列在前面的較大數字優先刪除掉保證最高位的數字是附近幾個數字中的最小就能保證得到的數字是比較小的。

現在感覺我們所學習的算法還是比較好理解的,能夠很好的將問題按照算法的思路去解決,去代入。我們通過這樣的算法能更好的使用現在所擁有的知識,算法我覺得更像是數學中的公式,知道清楚其中的原理就能很好的解決問題。

 

參考文獻

[1] Thomas H.Cormen.算法導論》.機械工業出版社, 2013.1.

[2] 馬克·艾倫·維斯.《數據結構與算法分析—C語言》.機械工業出版社. 2019.4

[3] Anany Levitin.《算法設計與分析基礎(第3版)》.清華大學出版社. 2015.1.1

[4] 傅清祥,王曉東.《算法與數據結構》.電子工業出版社. 1998.1

 

 

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