⑴ 學關於數學建模的推薦書籍以及入門級使用的編程軟體及教材
我也要參加今年九月份的數學建模比賽,以下是我們老師給我們的幾點建議,希望對你有些幫助。
賽前學習內容
1建模基礎知識、常用工具軟體的使用
一、掌握建模必備的數學基礎知識(如初等數學、高等數學等),數學建模中常用的但尚未學過的方法,如圖論方法、優化中若干方法、概率統計以及運籌學等方法。
二、,針對建模特點,結合典型的建模題型,重點學習一些實用數學軟體(如 Mathematica 、Matlab、Lindo 、Lingo、SPSS)的使用及一般性開發,尤其注意同一數學模型可以用多個軟體求解的問題。
例如, 貸款買房問題: 某人貸款8 萬元買房,每月還貸款880.87 元,月利率1%。
(1)已經還貸整6 年。還貸6 年後,某人想知道自己還欠銀行多少錢,請你告訴他。
(2)此人忘記這筆貸款期限是多少年,請你告訴他。
這問題我們可以用 Mathematica 、Matlab、Lindo 、Lingo 等多個不同軟體包編程求解
2 建模的過程、方法
數學建模是一項非常具有創造性和挑戰性的活動,不可能用一些條條框框規定出各種模型如何具體建立。但一般來說,建模主要涉及兩個方面:第一,將實際問題轉化為理論模型;第二,對理論模型進行計算和分析。簡而言之,就是建立數學模型來解決各種實際問題的過程。這個過程可以用如下圖1來表示。
3常用演算法的設計
建模與計算是數學模型的兩大核心,當模型建立後,計算就成為解決問題的關鍵要素了,而演算法好壞將直接影響運算速度的快慢答案的優劣。根據競賽題型特點及前參賽獲獎選手的心得體會,建議大家多用數學軟體(Mathematica,Matlab,Maple,Lindo,Lingo,SPSS 等)設計演算法,這里列舉常用的幾種數學建模演算法.
(1)蒙特卡羅演算法(該演算法又稱隨機性模擬演算法,是通過計算機模擬來解決問題的演算法,同時可以通過模擬可以來檢驗自己模型的正確性,是比賽時必用的方法,通常使用Mathematica、Matlab 軟體實現)。
(2)數據擬合、參數估計、插值等數據處理演算法(比賽中通常會遇到大量的數據需要處理,而處理數據的關鍵就在於這些演算法,通常使用Matlab 作為工具)。
(3)線性規劃、整數規劃、多元規劃、二次規劃等規劃類問題(建模競賽大多數問題屬於最優化問題,很多時候這些問題可以用數學規劃演算法來描述,通常使用Lindo、Lingo 軟體實現)。
(4)圖論演算法(這類演算法可以分為很多種,包括最短路、網路流、二分圖等演算法,涉及到圖論的問題可以用這些方法解決,需要認真准備,通常使用Mathematica、Maple 作為工具)。
(5)動態規劃、回溯搜索、分治演算法、分支定界等計算機演算法(這些演算法是演算法設計中比較常用的方法,很多場合可以用到競賽中,通常使用Lingo 軟體實現)。
(6)圖象處理演算法(賽題中有一類問題與圖形有關,即使與圖形無關,論文中也應該要不乏圖片的,這些圖形如何展示以及如何處理就是需要解決的問題,通常使用Matlab 進行處理)。
(7)最優化理論的三大非經典演算法:模擬退火法、神經網路、遺傳演算法(這些問題是用來解決一些較困難的最優化問題的演算法,對於有些問題非常有幫助,但是演算法的實現比較困難,需慎重使用,通常使用Lingo、 Matlab、SPSS 軟體實現)。
4 論文結構,寫作特點和要求
答卷(論文)是競賽活動成績結晶的書面形式,是評定競賽活動的成績好壞、高低,獲獎級別的唯一依據。因此,寫好數學建模論文在競賽活動中顯得尤其重要,這也是參賽學生必須掌握的。為了使學生較好地掌握競賽論文的撰寫要領,(1)要求同學們認真學習和掌握全國大學生數學建模競賽組委會最新制定的論文格式要求且多閱讀科技文獻。(2)通過對歷屆建模競賽的優秀論文(如以中國人民解放軍信息工程學院李開鋒、趙玉磊、黃玉慧2004 年獲全國一等獎論文:奧運場館周邊的MS 網路設計方案為範例)進行剖析,總結出建模論文的一般結構及寫作要點,去學習體會和摸索。
參加全國大學生數學建模競賽應注意的問題
一、心裡要有「底」
首先,賽題來自於哪個實際領地的確難以預料,但絕不會過於「專」,它畢竟是經過簡化、加工的。大部分賽題僅憑意識便能理解題意,少數賽題的實際背景可能生疏,只需要查閱一些資料,便可以理解題意。其次,所有的賽題當然要用到數學知識,但一定不會過於高深。用得較多的有運籌學、概率與統計、計算方法、離散數學、微分方程等方面的一部分理論和方法,這些內容在賽前培訓要學過一些,真的用到了,總知道在哪些資料中查找。
二、當斷即斷
在兩個賽題中選擇做哪一個不能久議不決,因為你們只有三天時間,一旦選定了,就不要再猶豫,更不要反復。選定了賽題之後,在討論建模思路和求解方法時會有爭論,但不能無休止地 爭論,而應學會妥協。方案定下來後,全隊要齊心協力地去做。
三、對困難要有足夠的心理准備
「拿到題目就有思路,做起來一帆風順」,哪有如此輕松的事?參加競賽可以說是「自討苦吃,以苦為樂」,競賽三天中所經受的磨煉一定會終生難忘,並成為自己的一份精神財富。好多同學賽後說:「參賽會後悔三天,而不參賽則遺憾一生。」做「撞到槍口上」的賽題,不一定比「外行」強。如學機械的隊員做機械方面的賽題,學投資的隊員做投資方面的賽題,學統計的隊員做統計方面的賽題,都有可能「聰明反被聰明誤」,這些情況在全國賽區都曾發生過。這就需要大家多方面涉獵知識盡全能做到全面
關於數模競賽的幾本好書
▲ 姜啟源,《數學模型(第二版)》,高等教育出版社
▲ 姜啟源、謝金星、葉俊《數學建模(第三版)》,高等教育出版社
▲ 蕭樹鐵等,《數學實驗》,高等教育出版社
▲ 朱道元,《數學建模案例精選》,科學出版社
▲ 雷功炎,《數學模型講義》,北京大學出版社
▲ 葉其孝等,《大學生數學建模競賽輔導教材(一)~(四)》,湖南教育出版社
▲ 江裕釗、辛培清,《數學模型與計算機模擬》,電子科技大學出版社
▲ 楊啟帆、邊馥萍,《數學模型》,浙江大學出版社
▲ 趙靜等,《數學建模與數學實驗》,高等教育出版社,施普林格出版社
▲ 韓中庚, 《數學建模方法與應用》,高等教育出版社
▲楊啟帆,《數學建模案例集》,高等教育出版社.
需要了解的基礎學科
1.數學分析(高等數學)
2.高等代數 (線性代數)
3.概率與數理統計
4.最優化理論 (規劃理論)
5.圖論
6.組合數學
7.微分方程穩定性分析
8.排隊論
不知道能不能幫上你
⑵ acm初學者要准備什麼 看什麼書啊
剛剛接觸信息學領域的同學往往存在很多困惑,不知道從何入手學習,在這篇文章里,我希望能將自己不多的經驗與大家分享,希望對各位有所幫助。
一、語言是最重要的基本功
無論側重於什麼方面,只要是通過計算機程序去最終實現的競賽,語言都是大家要過的第一道關。亞洲賽區的比賽支持的語言包括C/C++與java。筆者首先說說JAVA,眾所周知,作為面向對象的王牌語言,JAVA在大型工程的組織與安全性方面有著自己獨特的優勢,但是對於信息學比賽的具體場合,JAVA則顯得不那麼合適,它對於輸入輸出流的操作相比於C++要繁雜很多,更為重要的是JAVA程序的運行速度要比C++慢10倍以上,而競賽中對於JAVA程序的運行時限卻往往得不到同等比例的放寬,這無疑對演算法設計提出了更高的要求,是相當不利的。其實,筆者並不主張大家在這種場合過多地運用面向對象的程序設計思維,因為對於小程序來說這不旦需要花費更多的時間去編寫代碼,也會降低程序的執行效率。
接著說C和C++。許多現在參加講座的同學還在上大一,C的基礎知識剛剛學完,還沒有接觸過C++,其實在賽場上使用純C的選手還是大有人在的,它們主要是看重了純C在效率上的優勢,所以這部分同學如果時間有限,並不需要急著去學習新的語言,只要提高了自己在演算法設計上的造詣,純C一樣能發揮巨大的威力。
而C++相對於C,在輸入輸出流上的封裝大大方便了我們的操作,同時降低了出錯的可能性,並且能夠很好地實現標准流與文件流的切換,方便了調試的工作。如果有些同學比較在意這點,可以嘗試C和C++的混編,畢竟僅僅學習C++的流操作還是不花什麼時間的。
C++的另一個支持來源於標准模版庫(STL),庫中提供的對於基本數據結構的統一介面操作和基本演算法的實現可以縮減我們編寫代碼的長度,這可以節省一些時間。但是,與此相對的,使用STL要在效率上做出一些犧牲,對於輸入規模很大的題目,有時候必須放棄STL,這意味著我們不能存在「有了STL就可以不去管基本演算法的實現」的想法;另外,熟練和恰當地使用STL必須經過一定時間的積累,准確地了解各種操作的時間復雜度,切忌對STL中不熟悉的部分濫用,因為這其中蘊涵著許多初學者不易發現的陷阱。
通過以上的分析,我們可以看出僅就信息學競賽而言,對語言的掌握並不要求十分全面,但是對於經常用到的部分,必須十分熟練,不允許有半點不清楚的地方,下面我舉個真實的例子來說明這個道理——即使是一點很細微的語言障礙,都有可能釀成錯誤:
在去年清華的賽區上,有一個隊在做F題的時候使用了cout和printf的混合輸出,由於一個帶緩沖一個不帶,所以輸出一長就混亂了。只是因為當時judge team中負責F題的人眼睛尖,看出答案沒錯只是順序不對(答案有一頁多,是所有題目中最長的一個輸出),又看了看程序發現只是輸出問題就給了個Presentation error(格式錯)。如果審題的人不是這樣而是直接給一個 Wrong Answer,相信這個隊是很難查到自己錯在什麼地方的。
現在我們轉入第二個方面的討論,基礎學科知識的積累。
二、以數學為主的基礎知識十分重要
雖然被定性為程序設計競賽,但是參賽選手所遇到的問題更多的是沒有解決問題的思路,而不是有了思路卻死活不能實現,這就是平時積累的基礎知識不夠。今年World Final的總冠軍是波蘭華沙大學,其成員出自於數學系而非計算機系,這就是一個鮮活的例子。競賽中對於基礎學科的涉及主要集中於數學,此外對於物理、電路等等也可能有一定應用,但是不多。因此,大一的同學也不必為自己還沒學數據結構而感到不知從何入手提高,把數學撿起來吧!下面我來談談在競賽中應用的數學的主要分支。
1、離散數學——作為計算機學科的基礎,離散數學是競賽中涉及最多的數學分支,其重中之重又在於圖論和組合數學,尤其是圖論。
圖論之所以運用最多是因為它的變化最多,而且可以輕易地結合基本數據結構和許多演算法的基本思想,較多用到的知識包括連通性判斷、DFS和BFS,關節點和關鍵路徑、歐拉迴路、最小生成樹、最短路徑、二部圖匹配和網路流等等。雖然這部分的比重很大,但是往往也是競賽中的難題所在,如果有初學者對於這部分的某些具體內容暫時感到力不從心,也不必著急,可以慢慢積累。
競賽中設計的組合計數問題大都需要用組合數學來解決,組合數學中的知識相比於圖論要簡單一些,很多知識對於小學上過奧校的同學來說已經十分熟悉,但是也有一些部分需要先對代數結構中的群論有初步了解才能進行學習。組合數學在競賽中很少以難題的形式出現,但是如果積累不夠,任何一道這方面的題目卻都有可能成為難題。
2、數論——以素數判斷和同餘為模型構造出來的題目往往需要較多的數論知識來解決,這部分在競賽中的比重並不大,但只要來上一道,也足以使知識不足的人冥思苦想上一陣時間。素數判斷和同餘最常見的是在以密碼學為背景的題目中出現,在運用密碼學常識確定大概的過程之後,核心演算法往往要涉及數論的內容。
3、計算幾何——計算幾何相比於其它部分來說是比較獨立的,就是說它和其它的知識點很少有過多的結合,較常用到的部分包括——線段相交的判斷、多邊形面積的計算、內點外點的判斷、凸包等等。計算幾何的題目難度不會很大,但也永遠不會成為最弱的題。
4、線性代數——對線性代數的應用都是圍繞矩陣展開的,一些表面上是模擬的題目往往可以藉助於矩陣來找到更好的演算法。
5、概率論——競賽是以黑箱來判卷的,這就是說你幾乎不能動使用概率演算法的念頭,但這也並不是說概率就沒有用。關於這一點,只有通過一定的練習才能體會。
6、初等數學與解析幾何——這主要就是中學的知識了,用的不多,但是至少比高等數學多,我覺得熟悉一下數學手冊上的相關內容,至少要知道在哪兒能查到,還是必要的。
7、高等數學——純粹運用高等數學來解決的題目我接觸的只有一道,但是一些題目的敘述背景往往需要和這部分有一定聯系,掌握得牢固一些總歸沒有壞處。
以上就是競賽所涉及的數學領域,可以說范圍是相當廣的。我認識的許多人去搞信息學的競賽就是為了逼著自己多學一點數學,因為數學是一切一切的基礎。
三、數據結構與演算法是真正的核心
雖然數學十分十分重要,但是如果讓三個只會數學的人參加比賽,我相信多數情況下會比三個只會數據結構與演算法的人得到更為悲慘的結局。
先說說數據結構。掌握隊列、堆棧和圖的基本表達與操作是必需的,至於樹,我個人覺得需要建樹的問題有但是並不多。(但是樹往往是很重要的分析工具)除此之外,排序和查找並不需要對所有方式都能很熟練的掌握,但你必須保證自己對於各種情況都有一個在時間復雜度上滿足最低要求的解決方案。說到時間復雜度,就又該說說哈希表了,競賽時對時間的限制遠遠多於對空間的限制,這要求大家盡快掌握「以空間換時間」的原則策略,能用哈希表來存儲的數據一定不要到時候再去查找,如果實在不能建哈希表,再看看能否建二叉查找樹等等——這都是爭取時間的策略,掌握這些技巧需要大家對數據結構尤其是演算法復雜度有比較全面的理性和感性認識。
接著說說演算法。演算法中最基本和常用的是搜索,主要是回溯和分支限界法的使用。這里要說的是,有些初學者在學習這些搜索基本演算法是不太注意剪枝,這是十分不可取的,因為所有搜索的題目給你的測試用例都不會有很大的規模,你往往察覺不出程序運行的時間問題,但是真正的測試數據一定能過濾出那些沒有剪枝的演算法。實際上參賽選手基本上都會使用常用的搜索演算法,題目的區分度往往就是建立在諸如剪枝之類的優化上了。
常用演算法中的另一類是以「相似或相同子問題」為核心的,包括遞推、遞歸、貪心法和動態規劃。這其中比較難於掌握的就是動態規劃,如何抽象出重復的子問題是很多題目的難點所在,筆者建議初學者仔細理解圖論中一些以動態規劃為基本思想所建立起來的基本演算法(比如Floyd-Warshall演算法),並且多閱讀一些定理的證明,這雖然不能有什麼直接的幫助,但是長期堅持就會對思維很有幫助。
四、團隊配合
通過以上的介紹大家也可以看出,信息學競賽對於知識面覆蓋的非常廣,想憑一己之力全部消化這些東西實在是相當困難的,這就要求我們盡可能地發揮團隊協作的精神。同組成員之間的熟練配合和默契的形成需要時間,具體的情況因成員的組成不同而不同,這里我就不再多說了。
五、練習、練習、再練習
知識的積累固然重要,但是信息學終究不是看出來的,而是練出來的,這是多少前人最深的一點體會,只有通過具體題目的分析和實踐,才能真正掌握數學的使用和演算法的應用,並在不斷的練習中增加編程經驗和技巧,提高對時間復雜度的感性認識,優化時間的分配,加強團隊的配合。總之,在這里光有紙上談兵是絕對不行的,必須要通過實戰來鍛煉自己。
大家一定要問,我們去哪裡找題做,又如何檢驗程序是否正確呢?這大可不必擔心,現在已經有了很多網上做題的站點,這些站點提供了大量的題庫並支持在線判卷,你只需要把程序源碼提交上去,馬上就可以知道自己的程序是否正確,運行所使用的時間以及消耗的內存等等狀況。下面我給大家推薦幾個站點,筆者不建議大家在所有這些站點上做題,選擇一個就可以了,因為每個站點的題都有一定的難易比例,系統地做一套題庫可以使你對各種難度、各種類型的題都有所認識。
1、Ural:
Ural是中國學生對俄羅斯的Ural州立大學的簡稱 ,那裡設立了一個Ural Online Problem Set,並且支持Online Judge。Ural的不少題目演算法性和趣聞性都很強,得到了國內廣大學生的厚愛。根據「信息學初學者之家」網站的統計,Ural的題目類型大概呈如下的分布:
題型
搜索
動態規劃
貪心
構造
圖論
計算幾何
純數學問題
數據結構
其它
所佔比例
約10%
約15%
約5%
約5%
約10%
約5%
約20%
約5%
約25%
這和實際比賽中的題型分布也是大體相當的。有興趣的朋友可以去看看。
2、UVA:
UVA代表西班牙Valladolid大學(University de Valladolid)。該大學有一個那裡設立了一個PROBLEM SET ARCHIVE with ONLINE JUDGE ,並且支持ONLINE JUDGE,形式和Ural大學的題庫類似。不過和Ural不同的是,UVA題目多的多,而且比較雜,而且有些題目的測試數據比較刁鑽。這使得剛到那裡做題的朋友往往感覺到無所適從,要麼難以找到合適的題目,要麼Wrong Answer了很多次以後仍然不知道錯在那裡。 如果說做Ural題目主要是為了訓練演算法,那麼UVA題目可以訓練全方位的基本功和一些必要的編程素質。UVA和許多世界知名大學聯合辦有同步網上比賽,因此那裡強人無數,不過你先要使自己具有聽懂他們在說什麼的素質:)
3、ZOJ:
ZOJ是浙江大學建立的ONLINE JUDGE,是中國大學建立的第一個同類站點,也是最好和人氣最高的一個,筆者和許多班裡的同學就是在這里練習。ZOJ雖然也定位為一個英文網站,但是這里的中國學生比較多,因此讓人覺得很親切。這里目前有500多道題目,難易分配適中,且涵蓋了各大洲的題目類型並配有索引,除此之外,ZOJ的JUDGE系統是幾個網站中表現得比較好的一個,很少出現Wrong Answer和Presentation error混淆的情況。這里每月也辦有一次網上比賽,只要是注冊的用戶都可以參加。
說起中國的ONLINE JUDGE,去年才開始參加ACM競賽的北京大學現在也建立了自己的提交系統;而我們學校也是去年開始參加比賽,現在也有可能推出自己的提交系統,如果能夠做成,到時候大家就可以去上面做題了。同類網站的飛速發展標志著有越來越多的同學有興趣進入信息學的領域探索,這是一件好事,同時也意味著更激烈的競爭。
看看這篇文章對你有什麼幫助!我也是ACM初學者!
⑶ 動態規劃的推薦書籍
《Dynamic Programming》
ISBN:3540370137
【出版日期】 2005 年7月
⑷ 請大俠給我推薦幾個演算法的書.因為我沒讀過,所以請在回答的時候告訴我推薦的理由,最好有內容.
《演算法導論》
本書深入淺出,全面地介紹了計算機演算法。對每一個演算法的分析既易於理解又十分有趣,並保持了數學嚴謹性。本書的設計目標全面,適用於多種用途。涵蓋的內容有:演算法在計算中的作用,概率分析和隨機演算法的介紹。本書專門討論了線性規劃,介紹了動態規劃的兩個應用,隨機化和線性規劃技術的近似演算法等,還有有關遞歸求解、快速排序中用到的劃分方法與期望線性時間順序統計演算法,以及對貪心演算法元素的討論。本書還介紹了對強連通子圖演算法正確性的證明,對哈密頓迴路和子集求和問題的NP完全性的證明等內容。全書提供了900多個練習題和思考題以及敘述較為詳細的實例研究。
目錄(Table of Contents)
前言(Preface)
第一部分(Part I) 基礎(Foundations)
第一章 計算中演算法的角色(The Role of Algorithms in Computing)
第二章 開始(Getting Started)
第三章 函數的增長率(Growth of Functions)
第四章 遞歸(Recurrences)
第五章 概率分析與隨機化演算法(Probabilistic Analysis and Randomized Algorithms)
第二部分(Part II) 排序與順序統計(Sorting and Order Statistics)
第六章 堆排序(Heapsort)
第七章快速排序(Quicksort)
第八章 線性時間中的排序(Sorting in Linear Time)
第九章 中值與順序統計(Medians and Order Statistics)
第三部分(Part III) 數據結構(Data Structures)
第十章 基本的數據結構(Elementary Data Structures)
第十一章 散列表(Hash Tables)
第十二章 二叉查找樹(Binary Search Trees)
第十三章 紅-黑樹(Red-Black Trees)
第十四章 擴充的數據結構(Augmenting Data Structures)
第四部分(Part IV) 高級的設計與分析技術(Advanced Design and Analysis Techniques)
第十五章 動態規劃(Dynamic Programming)
第十六章 貪婪演算法(Greedy Algorithms)
第十七章 分攤分析(Amortized Analysis)
第五部分(Part V) 高級的數據結構(Advanced Data Structures)
第十八章 B-樹(B-Trees)
第十九章 二項式堆(Binomial Heaps)
第二十章 斐波納契堆(Fibonacci Heaps)
第二十一章 不相交集的數據結構(Data Structures for Disjoint Sets)
第六部分(Part VI) 圖演算法(Graph Algorithms)
第二十二章 基本的圖演算法(Elementary Graph Algorithms)
第二十三章 最小生成樹(Minimum Spanning Trees)
第二十四章單源最短路徑(Single-Source Shortest Paths)
第二十五章 全對的最短路徑(All-Pairs Shortest Paths)
第二十六章 最大流(Maximum Flow)
第七部分(Part VII) 精選的主題(Selected Topics)
第二十七章 排序網路(Sorting Networks)
第二十八章矩陣運算(Matrix Operations)
第二十九章 線性規劃(Linear Programming)
第三十章 多項式與快速傅里葉變換(Polynomials and the FFT)
第三十一章 數論演算法(Number-Theoretic Algorithms)
第三十二章 字元串匹配(String Matching)
第三十三章 計算幾何學(Computational Geometry)
第三十四章 NP-完備性(NP-Completeness)
第三十五章 近似演算法(Approximation Algorithms)
第八部分(Part VIII) 附錄:數學背景(Mathematical Background)
附錄A 求和(Summations)
附錄B 集合,等等。(Sets, Etc.)
附錄C 計數與概率(Counting and Probability)
參考文獻(Bibliography)
索引(Index)
⑸ 什麼是動態規劃動態規劃的意義是什麼
動態規劃是用來求解最優化問題的一種方法。常規演算法書上強調的是無後效性和最優子結構描述,這套理論是正確的,但是適用與否與你的狀態表述有關。至於劃分階段什麼的就有些扯淡了:動態規劃不一定有所謂的階段。其實質是狀態空間的狀態轉移。下面的理解為我個人十年競賽之總結。基本上在oi和acm中我沒有因為動態規劃而失手過。所有的決策類求最優解的問題都是在狀態空間內找一個可以到達的最佳狀態。搜索的方式是去遍歷每一個點,而動態規劃則是把狀態空間變形,由此變成從初始到目標狀態的最短路問題。依照這種描述:假若你的問題的結論包含若干決策,則可以認為從初始狀態(邊界條件)到解中間的決策流程是一個決策狀態空間中的轉移路線。前提是:你的狀態描述可以完整且唯一地覆蓋所有有效的狀態空間中的點,且轉移路線包含所有可能的路徑。這個描述是包含動態規劃兩大條件的。所謂無後效性,指狀態間的轉移與如何到達某狀態無關。如果有關,意味著你的狀態描述不能完整而唯一地包括每一個狀態。如果你發現一個狀態轉移有後效性,很簡單,把會引起後效性的參數作為狀態描述的一部分放進去將其區分開來就可以了;最優子結構說明轉移路線包含了所有可能的路徑,如果不具備最優子結構,意味著有部分情況沒有在轉移中充分體現,增加轉移的描述就可以了。最終所有的搜索問題都可以描述成狀態空間內的狀態轉移方程,只是有可能狀態數量是指數階的,有可能不滿足計算要求罷了。這樣的描述下,所有的動態規劃問題都可以轉變為狀態空間內大量可行狀態點和有效轉移構成的圖的從初始狀態到最終狀態的最短路問題。於是乎,對於動態規劃,他的本質就是圖論中的最短路;階段可以去除,因為不一定有明確的階段劃分。
⑹ 哪些學習數據結構與演算法的書籍值得推薦
大學計算機數據結構教材是 嚴蔚敏版的《數據結構》可以拿來入門。然後可以根據自己的實際情況來安排怎麼樣學習數據結構。很多人是看一遍書,然後在遇到演算法之後再去實現它。在這里列出一些我知道的演算法書籍,以供參考。(我也只看過演算法導論,編程之美)
1. CLRS 演算法導論
演算法網路全書,只做了前面十幾章的習題,便感覺受益無窮。
2. Algorithms 演算法概論
短小精悍,別據一格,准經典之作。一個壞消息: 同演算法導論,該書沒有習題答案。好消息:習題很經典,難度也適中,只需花點點時間自己也都能做出來。不好也不壞的消息:我正在寫習題的答案,已完成前三章,還剩九章約二百道題,順利的話二個月之後發布。另有中文版名《演算法概論》,我沒看過,不知道翻譯得怎麼樣。如果有心的話,還是盡量看原版吧,其實看原版與看中文版花費時間不會相差很大,因為大部分時間其實都花費在做習題上了。
作者:向小剛
鏈接:http://www.hu.com/question/19987046/answer/13945644
來源:知乎
著作權歸作者所有,轉載請聯系作者獲得授權。
⑺ 動態規劃習題(清華出版演算法與分析屈婉玲、劉田、張立昂、王捍貧、編著),急求此題答案,在線等!
這可以轉化為完全背包問題,付款數為背包容量,幣值為物品重量,重量為物品價值, 求剛好裝滿時候的最小值
狀態轉移方程 你應該會吧、、、
⑻ 求動態規劃的資料
動態規劃的特點及其應用
安徽 張辰
【關鍵詞】動態規劃 階段
【摘要】
動態規劃是信息學競賽中的常見演算法,本文的主要內容就是分析它的特點。
文章的第一部分首先探究了動態規劃的本質,因為動態規劃的特點是由它的本質所決定的。第二部分從動態規劃的設計和實現這兩個角度分析了動態規劃的多樣性、模式性、技巧性這三個特點。第三部分將動態規劃和遞推、搜索、網路流這三個相關演算法作了比較,從中探尋動態規劃的一些更深層次的特點。
文章在分析動態規劃的特點的同時,還根據這些特點分析了我們在解題中應該怎樣利用這些特點,怎樣運用動態規劃。這對我們的解題實踐有一定的指導意義。
【正文】
動態規劃是編程解題的一種重要的手段,在如今的信息學競賽中被應用得越來越普遍。最近幾年的信息學競賽,不分大小,幾乎每次都要考察到這方面的內容。因此,如何更深入地了解動態規劃,從而更為有效地運用這個解題的有力武器,是一個值得深入研究的問題。
要掌握動態規劃的應用技巧,就要了解它的各方面的特點。首要的,是要深入洞悉動態規劃的本質。
§1動態規劃的本質
動態規劃是在本世紀50年代初,為了解決一類多階段決策問題而誕生的。那麼,什麼樣的問題被稱作多階段決策問題呢?
§1.1多階段決策問題
說到多階段決策問題,人們很容易舉出下面這個例子。
[例1] 多段圖中的最短路徑問題:在下圖中找出從A1到D1的最短路徑。
仔細觀察這個圖不難發現,它有一個特點。我們將圖中的點分為四類(圖中的A、B、C、D),那麼圖中所有的邊都處於相鄰的兩類點之間,並且都從前一類點指向後一類點。這樣,圖中的邊就被分成了三類(AàB、BàC、CàD)。我們需要從每一類中選出一條邊來,組成從A1到D1的一條路徑,並且這條路徑是所有這樣的路徑中的最短者。
從上面的這個例子中,我們可以大概地了解到什麼是多階段決策問題。更精確的定義如下:
多階段決策過程,是指這樣的一類特殊的活動過程,問題可以按時間順序分解成若干相互聯系的階段,在每一個階段都要做出決策,全部過程的決策是一個決策序列[1]。要使整個活動的總體效果達到最優的問題,稱為多階段決策問題。
從上述的定義中,我們可以明顯地看出,這類問題有兩個要素。一個是階段,一個是決策。
§1.2階段與狀態
階段:將所給問題的過程,按時間或空間特徵分解成若干相互聯系的階段,以便按次序去求每階段的解。常用字母k表示階段變數。[1]
階段是問題的屬性。多階段決策問題中通常存在著若干個階段,如上面的例子,就有A、B、C、D這四個階段。在一般情況下,階段是和時間有關的;但是在很多問題(我的感覺,特別是信息學問題)中,階段和時間是無關的。從階段的定義中,可以看出階段的兩個特點,一是「相互聯系」,二是「次序」。
階段之間是怎樣相互聯系的?就是通過狀態和狀態轉移。
狀態:各階段開始時的客觀條件叫做狀態。描述各階段狀態的變數稱為狀態變數,常用sk表示第k階段的狀態變數,狀態變數sk的取值集合稱為狀態集合,用Sk表示。[1]
狀態是階段的屬性。每個階段通常包含若干個狀態,用以描述問題發展到這個階段時所處在的一種客觀情況。在上面的例子中,行人從出發點A1走過兩個階段之後,可能出現的情況有三種,即處於C1、C2或C3點。那麼第三個階段就有三個狀態S3={C1,C2,C3}。
每個階段的狀態都是由以前階段的狀態以某種方式「變化」而來,這種「變化」稱為狀態轉移(暫不定義)。上例中C3點可以從B1點過來,也可以從B2點過來,從階段2的B1或B2狀態走到階段3的C3狀態就是狀態轉移。狀態轉移是導出狀態的途徑,也是聯系各階段的途徑。
說到這里,可以提出應用動態規劃的一個重要條件。那就是將各階段按照一定的次序排列好之後,對於某個給定的階段狀態,它以前各階段的狀態無法直接影響它未來的發展,而只能通過當前的這個狀態。換句話說,每個狀態都是「過去歷史的一個完整總結[1]」。這就是無後效性。對這個性質,下文還將會有解釋。
§1.3決策和策略
上面的階段與狀態只是多階段決策問題的一個方面的要素,下面是另一個方面的要素——決策。
決策:當各段的狀態取定以後,就可以做出不同的決定,從而確定下一階段的狀態,這種決定稱為決策。表示決策的變數,稱為決策變數,常用uk(sk)表示第k階段當狀態為sk時的決策變數。在實際問題中,決策變數的取值往往限制在一定范圍內,我們稱此范圍為允許決策集合。常用Dk(sk)表示第k階段從狀態sk出發的允許決策集合。顯然有uk(sk) ?Dk(sk)。[1]
決策是問題的解的屬性。決策的目的就是「確定下一階段的狀態」,還是回到上例,從階段2的B1狀態出發有三條路,也就是三個決策,分別導向階段3的C1、C2、C3三個狀態,即D2(B1)={C1,C2,C3}。
有了決策,我們可以定義狀態轉移:動態規劃中本階段的狀態往往是上一階段和上一階段的決策結果,由第k段的狀態sk和本階段的決策uk確定第k+1段的狀態sk+1的過程叫狀態轉移。狀態轉移規律的形式化表示sk+1=Tk(sk,uk)稱為狀態轉移方程。
這樣看來,似乎決策和狀態轉移有著某種聯系。我的理解,狀態轉移是決策的目的,決策是狀態轉移的途徑。
各段決策確定後,整個問題的決策序列就構成一個策略,用p1,n={u1(s1),u2(s2),…, un(sn)}表示。對每個實際問題,可供選擇的策略有一定范圍,稱為允許策略集合,記作P1,n,使整個問題達到最有效果的策略就是最優策略。[1]
說到這里,又可以提出運用動態規劃的一個前提。即這個過程的最優策略應具有這樣的性質:無論初始狀態及初始決策如何,對於先前決策所形成的狀態而言,其以後的所有決策應構成最優策略[1]。這就是最優化原理。簡言之,就是「最優策略的子策略也是最優策略」。
§1.4最優化原理與無後效性
這里,我把最優化原理定位在「運用動態規劃的前提」。這是因為,是否符合最優化原理是一個問題的本質特徵。對於不滿足最優化原理的一個多階段決策問題,整體上的最優策略p1,n同任何一個階段k上的決策uk或任何一組階段k1…k2上的子策略pk1,k2都不存在任何關系。如果要對這樣的問題動態規劃的話,我們從一開始所作的劃分階段等努力都將是徒勞的。
而我把無後效性定位在「應用動態規劃的條件」,是因為動態規劃是按次序去求每階段的解,如果一個問題有後效性,那麼這樣的次序便是不合理的。但是,我們可以通過重新劃分階段,重新選定狀態,或者增加狀態變數的個數等手段,來是問題滿足無後效性這個條件。說到底,還是要確定一個「序」。
在信息學的多階段決策問題中,絕大部分都是能夠滿足最優化原理的,但它們往往會在後效性這一點上來設置障礙。所以在解題過程中,我們會特別關心「序」。對於有序的問題,就會考慮到動態規劃;對於無序的問題,也會想方設法來使其有序。
§1.5最優指標函數和規劃方程
最優指標函數:用於衡量所選定策略優劣的數量指標稱為指標函數,最優指標函數記為fk(sk),它表示從第k段狀態sk採用最優策略p*k,n到過程終止時的最佳效益值[1]。
最優指標函數其實就是我們真正關心的問題的解。在上面的例子中,f2(B1)就表示從B1點到終點D1點的最短路徑長度。我們求解的最終目標就是f1(A1)。
最優指標函數的求法一般是一個從目標狀態出發的遞推公式,稱為規劃方程:
其中sk是第k段的某個狀態,uk是從sk出發的允許決策集合Dk(sk)中的一個決策,Tk(sk,uk)是由sk和uk所導出的第k+1段的某個狀態sk+1,g(x,uk)是定義在數值x和決策uk上的一個函數,而函數opt表示最優化,根據具體問題分別表為max或min。
,稱為邊界條件。
上例中的規劃方程就是:
邊界條件為
這里是一種從目標狀態往回推的逆序求法,適用於目標狀態確定的問題。在我們的信息學問題中,也有很多有著確定的初始狀態。當然,對於初始狀態確定的問題,我們也可以採用從初始狀態出發往前推的順序求法。事實上,這種方法對我們來說要更為直觀、更易設計一些,從而更多地出現在我們的解題過程中。
我們本節所討論的這些理論雖然不是本文的主旨,但是卻對下面要說的動態規劃的特點起著基礎性的作用。
§2動態規劃的設計與實現
上面我們討論了動態規劃的一些理論,本節我們將通過幾個例子中,動態規劃的設計與實現,來了解動態規劃的一些特點。
§2.1動態規劃的多樣性
[例2] 花店櫥窗布置問題(IOI99)試題見附錄
本題雖然是本屆IOI中較為簡單的一題,但其中大有文章可作。說它簡單,是因為它有序,因此我們一眼便可看出這題應該用動態規劃來解決。但是,如何動態規劃呢?如何劃分階段,又如何選擇狀態呢?
<方法1>以花束的數目來劃分階段。在這里,階段變數k表示的就是要布置的花束數目(前k束花),狀態變數sk表示第k束花所在的花瓶。而對於每一個狀態sk,決策就是第k-1束花應該放在哪個花瓶,用uk表示。最優指標函數fk(sk)表示前k束花,其中第k束插在第sk個花瓶中,所能取得的最大美學值。
狀態轉移方程為
規劃方程為
(其中A(i,j)是花束i插在花瓶j中的美學值)
邊界條件 (V是花瓶總數,事實上這是一個虛擬的邊界)
<方法2>以花瓶的數目來劃分階段。在這里階段變數k表示的是要佔用的花瓶數目(前k個花瓶),狀態變數sk表示前k個花瓶中放了多少花。而對於任意一個狀態sk,決策就是第sk束花是否放在第k個花瓶中,用變數uk=1或0來表示。最優指標函數fk(sk)表示前k個花瓶中插了sk束花,所能取得的最大美學值。
狀態轉移方程為
規劃方程為
邊界條件為
兩種劃分階段的方法,引出了兩種狀態表示法,兩種規劃方式,但是卻都成功地解決了問題。只不過因為決策的選擇有多有少,所以演算法的時間復雜度也就不同。[2]
這個例子具有很大的普遍性。有很多的多階段決策問題都有著不止一種的階段劃分方法,因而往往就有不止一種的規劃方法。有時各種方法所產生的效果是差不多的,但更多的時候,就像我們的例子一樣,兩種方法會在某個方面有些區別。
所以,在用動態規劃解題的時候,可以多想一想是否有其它的解法。對於不同的解法,要注意比較,好的演算法好在哪裡,差一點的演算法差在哪裡。從各種不同演算法的比較中,我們可以更深刻地領會動態規劃的構思技巧。
§2.2動態規劃的模式性
這個可能做過動態規劃的人都有體會,從我們上面對動態規劃的分析也可以看出來。動態規劃的設計都有著一定的模式,一般要經歷以下幾個步驟。
劃分階段:按照問題的時間或空間特徵,把問題分為若干個階段。注意這若干個階段一定要是有序的或者是可排序的,否則問題就無法求解。
選擇狀態:將問題發展到各個階段時所處於的各種客觀情況用不同的狀態表示出來。當然,狀態的選擇要滿足無後效性。
確定決策並寫出狀態轉移方程:之所以把這兩步放在一起,是因為決策和狀態轉移有著天然的聯系,狀態轉移就是根據上一階段的狀態和決策來導出本階段的狀態。所以,如果我們確定了決策,狀態轉移方程也就寫出來了。但事實上,我們常常是反過來做,根據相鄰兩段的各狀態之間的關系來確定決策。
寫出規劃方程(包括邊界條件):在第一部分中,我們已經給出了規劃方程的通用形式化表達式。一般說來,只要階段、狀態、決策和狀態轉移確定了,這一步還是比較簡單的。
動態規劃的主要難點在於理論上的設計,一旦設計完成,實現部分就會非常簡單。大體上的框架如下:
對f1(s1)初始化(邊界條件)
for k?2 to n(這里以順序求解為例)
對每一個sk?Sk
fk(sk)?一個極值(∞或-∞)
對每一個uk(sk)?Dk(sk)
sk-1?Tk(sk,uk)
t?g(fk-1(sk-1),uk)
y t比fk(sk)更優 n
fk(sk)?t
輸出fn(sn)
這個N-S圖雖然不能代表全部,但足可以概括大多數。少數的一些特殊的動態規劃,其實現的原理也是類似,可以類比出來。我們到現在對動態規劃的分析,主要是在理論上、設計上,原因也就在此。
掌握了動態規劃的模式性,我們在用動態規劃解題時就可以把主要的精力放在理論上的設計。一旦設計成熟,問題也就基本上解決了。而且在設計演算法時也可以按部就班地來。
但是「物極必反」,太過拘泥於模式就會限制我們的思維,扼殺優良演算法思想的產生。我們在解題時,不妨發揮一下創造性,去突破動態規劃的實現模式,這樣往往會收到意想不到的效果。[3]
§2.3動態規劃的技巧性
上面我們所說的動態規劃的模式性,主要指的是實現方面。而在設計方面,雖然它較為嚴格的步驟性,但是它的設計思想卻是沒有一定的規律可循的。這就需要我們不斷地在實踐當中去掌握動態規劃的技巧,下面僅就一個例子談一點我自己的體會。
[例3] 街道問題:在下圖中找出從左下角到右上角的最短路徑,每步只能向右方或上方走。
這是一道簡單而又典型的動態規劃題,許多介紹動態規劃的書與文章中都拿它來做例子。通常,書上的解答是這樣的:
按照圖中的虛線來劃分階段,即階段變數k表示走過的步數,而狀態變數sk表示當前處於這一階段上的哪一點(各點所對應的階段和狀態已經用ks在地圖上標明)。這時的模型實際上已經轉化成了一個特殊的多段圖。用決策變數uk=0表示向右走,uk=1表示向上走,則狀態轉移方程如下:
(這里的row是地圖豎直方向的行數)
我們看到,這個狀態轉移方程需要根據k的取值分兩種情況討論,顯得非常麻煩。相應的,把它代入規劃方程而付諸實現時,演算法也很繁。因而我們在實現時,一般是不會這么做的,而代之以下面方法:
將地圖中的點規則地編號如上,得到的規劃方程如下:
(這里Distance表示相鄰兩點間的邊長)
這樣做確實要比上面的方法簡單多了,但是它已經破壞了動態規劃的本來面目,而不存在明確的階段特徵了。如果說這種方法是以地圖中的行(A、B、C、D)來劃分階段的話,那麼它的「狀態轉移」就不全是在兩個階段之間進行的了。
也許這沒什麼大不了的,因為實踐比理論更有說服力。但是,如果我們把題目擴展一下:在地圖中找出從左下角到右上角的兩條路徑,兩條路徑中的任何一條邊都不能重疊,並且要求兩條路徑的總長度最短。這時,再用這種「簡單」的方法就不太好辦了。
如果非得套用這種方法的話,則最優指標函數就需要有四維的下標,並且難以處理兩條路徑「不能重疊」的問題。
而我們回到原先「標准」的動態規劃法,就會發現這個問題很好解決,只需要加一維狀態變數就成了。即用sk=(ak,bk)分別表示兩條路徑走到階段k時所處的位置,相應的,決策變數也增加一維,用uk=(xk,yk)分別表示兩條路徑的行走方向。狀態轉移時將兩條路徑分別考慮:
在寫規劃方程時,只要對兩條路徑走到同一個點的情況稍微處理一下,減少可選的決策個數:
從這個例子中可以總結出設計動態規劃演算法的一個技巧:狀態轉移一般是在相鄰的兩個階段之間(有時也可以在不相鄰的兩個階段間),但是盡量不要在同一個階段內進行。
動態規劃是一種很靈活的解題方法,在動態規劃演算法的設計中,類似的技巧還有很多。要掌握動態規劃的技巧,有兩條途徑:一是要深刻理解動態規劃的本質,這也是我們為什麼一開始就探討它的本質的原因;二是要多實踐,不但要多解題,還要學會從解題中探尋規律,總結技巧。
§3動態規劃與一些演算法的比較
動態規劃作為諸多解題方法中的一種,必然和其他一些演算法有著諸多聯系。從這些聯系中,我們也可以看出動態規劃的一些特點。
§3.1動態規劃與遞推
——動態規劃是最優化演算法
由於動態規劃的「名氣」如此之大,以至於很多人甚至一些資料書上都往往把一種與動態規劃十分相似的演算法,當作是動態規劃。這種演算法就是遞推。實際上,這兩種演算法還是很容易區分的。
按解題的目標來分,信息學試題主要分四類:判定性問題、構造性問題、計數問題和最優化問題。我們在競賽中碰到的大多是最優化問題,而動態規劃正是解決最優化問題的有力武器,因此動態規劃在競賽中的地位日益提高。而遞推法在處理判定性問題和計數問題方面也是一把利器。下面分別就兩個例子,談一下遞推法和動態規劃在這兩個方面的聯系。
[例4] mod 4 最優路徑問題:在下圖中找出從第1點到第4點的一條路徑,要求路徑長度mod 4的余數最小。
這個圖是一個多段圖,而且是一個特殊的多段圖。雖然這個圖的形式比一般的多段圖要簡單,但是這個最優路徑問題卻不能用動態規劃來做。因為一條從第1點到第4點的最優路徑,在它走到第2點、第3點時,路徑長度mod 4的余數不一定是最小,也就是說最優策略的子策略不一定最優——這個問題不滿足最優化原理。
但是我們可以把它轉換成判定性問題,用遞推法來解決。判斷從第1點到第k點的長度mod 4為sk的路徑是否存在,用fk(sk)來表示,則遞推公式如下:
(邊界條件)
(這里lenk,i表示從第k-1點到第k點之間的第i條邊的長度,方括弧表示「或(or)」運算)
最後的結果就是可以使f4(s4)值為真的最小的s4值。
這個遞推法的遞推公式和動態規劃的規劃方程非常相似,我們在這里借用了動態規劃的符號也就是為了更清楚地顯示這一點。其實它們的思想也是非常相像的,可以說是遞推法借用了動態規劃的思想解決了動態規劃不能解決的問題。
有的多階段決策問題(像這一題的階段特徵就很明顯),由於不能滿足最優化原理等使用動態規劃的先決條件,而無法應用動態規劃。在這時可以將最優指標函數的值當作「狀態」放到下標中去,從而變最優化問題為判定性問題,再借用動態規劃的思想,用遞推法來解決問題。
§3.2動態規劃與搜索
——動態規劃是高效率、高消費演算法
同樣是解決最優化問題,有的題目我們採用動態規劃,而有的題目我們則需要用搜索。這其中有沒有什麼規則呢?
我們知道,撇開時空效率的因素不談,在解決最優化問題的演算法中,搜索可以說是「萬能」的。所以動態規劃可以解決的問題,搜索也一定可以解決。
把一個動態規劃演算法改寫成搜索是非常方便的,狀態轉移方程、規劃方程以及邊界條件都可以直接「移植」,所不同的只是求解順序。動態規劃是自底向上的遞推求解,而搜索則是自頂向下的遞歸求解(這里指深度搜索,寬度搜索類似)。
反過來,我們也可以把搜索演算法改寫成動態規劃。狀態空間搜索實際上是對隱式圖中的點進行枚舉,這種枚舉是自頂向下的。如果把枚舉的順序反過來,變成自底向上,那麼就成了動態規劃。(當然這里有個條件,即隱式圖中的點是可排序的,詳見下一節。)
正因為動態規劃和搜索有著求解順序上的不同,這也造成了它們時間效率上的差別。在搜索中,往往會出現下面的情況:
對於上圖(a)這樣幾個狀態構成的一個隱式圖,用搜索演算法就會出現重復,如上圖(b)所示,狀態C2被搜索了兩次。在深度搜索中,這樣的重復會引起以C2為根整個的整個子搜索樹的重復搜索;在寬度搜索中,雖然這樣的重復可以立即被排除,但是其時間代價也是不小的。而動態規劃就沒有這個問題,如上圖(c)所示。
一般說來,動態規劃演算法在時間效率上的優勢是搜索無法比擬的。(當然對於某些題目,根本不會出現狀態的重復,這樣搜索和動態規劃的速度就沒有差別了。)而從理論上講,任何拓撲有序(現實中這個條件常常可以滿足)的隱式圖中的搜索演算法都可以改寫成動態規劃。但事實上,在很多情況下我們仍然不得不採用搜索演算法。那麼,動態規劃演算法在實現上還有什麼障礙嗎?
考慮上圖(a)所示的隱式圖,其中存在兩個從初始狀態無法達到的狀態。在搜索演算法中,這樣的兩個狀態就不被考慮了,如上圖(b)所示。但是動態規劃由於是自底向上求解,所以就無法估計到這一點,因而遍歷了全部的狀態,如上圖(c)所示。
一般說來,動態規劃總要遍歷所有的狀態,而搜索可以排除一些無效狀態。更重要的事搜索還可以剪枝,可能剪去大量不必要的狀態,因此在空間開銷上往往比動態規劃要低很多。
如何協調好動態規劃的高效率與高消費之間的矛盾呢?有一種折衷的辦法就是記憶化演算法。記憶化演算法在求解的時候還是按著自頂向下的順序,但是每求解一個狀態,就將它的解保存下來,以後再次遇到這個狀態的時候,就不必重新求解了。這種方法綜合了搜索和動態規劃兩方面的優點,因而還是很有實用價值的。
§3.3動態規劃與網路流
——動態規劃是易設計易實現演算法
由於圖的關系復雜而無序,一般難以呈現階段特徵(除了特殊的圖如多段圖,或特殊的分段方法如Floyd),因此動態規劃在圖論中的應用不多。但有一類圖,它的點卻是有序的,這就是有向無環圖。
在有向無環圖中,我們可以對點進行拓撲排序,使其體現出有序的特徵,從而據此劃分階段。在有向無還圖中求最短路徑的演算法[4],已經體現出了簡單的動態規劃思想。但動態規劃在圖論中還有更有價值的應用。下面先看一個例子。
[例6] N個人的街道問題:在街道問題(參見例3)中,若有N個人要從左下角走向右上角,要求他們走過的邊的總長度最大。當然,這里每個人也只能向右或向上走。下面是一個樣例,左圖是從出發地到目的地的三條路徑,右圖是他們所走過的邊,這些邊的總長度為5 + 4 + 3 + 6 + 3 + 3 + 5 + 8 + 8 + 7 + 4 + 5 + 9 + 5 + 3 = 78(不一定是最大)。
這個題目是對街道問題的又一次擴展。仿照街道問題的解題方法,我們仍然可以用動態規劃來解決本題。不過這一次是N個人同時走,狀態變數也就需要用N維來表示,。相應的,決策變數也要變成N維,uk=(uk,1,uk,2,…,uk,N)。狀態轉移方程不需要做什麼改動:
在寫規劃方程時,需要注意在第k階段,N條路徑所走過的邊的總長度的計算,在這里我就用gk(sk,uk)來表示了:
邊界條件為
可見將原來的動態規劃演算法移植到這個問題上來,在理論上還是完全可行的。但是,現在的這個動態規劃演算法的時空復雜度已經是關於N的指數函數,只要N稍微大一點,這個演算法就不可能實現了。
下面我們換一個思路,將N條路徑看成是網路中一個流量為N的流,這樣求解的目標就是使這個流的費用最大。但是本題又不同於一般的費用流問題,在每一條邊e上的流費用並不是流量和邊權的乘積 ,而是用下式計算:
為了使經典的費用流演算法適用於本題,我們需要將模型稍微轉化一下:
如圖,將每條邊拆成兩條。拆開後一條邊上有權,但是容量限制為1;另一條邊沒有容量限制,但是流過這條邊就不能計算費用了。這樣我們就把問題轉化成了一個標準的最大費用固定流問題。
這個演算法可以套用經典的最小費用最大流演算法,在此就不細說了。(參見附錄中的源程序)
這個例題是我仿照IOI97的「障礙物探測器」一題[6]編出來的。「障礙物探測器」比這一題要復雜一些,但是基本思想是相似的。類似的題目還有99年冬令營的「迷宮改造」[7]。從這些題目中都可以看到動態規劃和網路流的聯系。
推廣到一般情況,任何有向無環圖中的費用流問題在理論上說,都可以用動態規劃來解決。對於流量為N(如果流量不固定,這個N需要事先求出來)的費用流問題,用N維的變數sk=(sk,1,sk,2,…,sk,N)來描述狀態,其中sk,i?V(1£i£N)。相應的,決策也用N維的變數uk=(uk,1,uk,2,…,uk,N)來表示,其中uk,i?E(sk,i)(1£i£N),E(v)表示指向v的弧集。則狀態轉移方程可以這樣表示:
sk-1,i = uk,i的弧尾結點
規劃方程為
邊界條件為
但是,由於動態規劃演算法是指數級演算法,因而在實現中的局限性很大,僅可用於一些N非常小的題目。然而在競賽解題中,比如上面說到的IOI97以及99冬令營測試時,我們使用動態規劃的傾向性很明顯(「障礙物探測器」中,我們用的是貪心策略,求N=1或N=2時的局部最優解[8])。這主要有兩個原因:
一. 雖然網路流有著經典的演算法,但是在競賽中不可能出現經典的問題。如果要運用網路流演算法,則需要經過一番模型轉化,有時這個轉化還是相當困難的。因此在演算法的設計上,靈活巧妙的動態規劃演算法反而要更為簡單一些。
二. 網路流演算法實現起來很繁,這是被人們公認的。因而在競賽的緊張環境中,實現起來有一定模式的動態規劃演算法又多了一層優勢。
正由於動態規劃演算法在設計和實現上的簡便性,所以在N不太大時,也就是在動態規劃可行的情況下,我們還是應該盡量運用動態規劃。
§4結語
本文的內容比較雜,是我幾年來對動態規劃的參悟理解、心得體會。雖然主要的篇幅講的都是理論,但是根本的目的還是指導實踐。
動態規劃,據我認為,是當今信息學競賽中最靈活、也最能體現解題者水平的一類解題方法。本文內容雖多,不能涵蓋動態規劃之萬一。「紙上得來終覺淺,絕知此事要躬行。」要想真正領悟、理解動態規劃的思想,掌握動態規劃的解題技巧,還需要在實踐中不斷地挖掘、探索。實踐得多了,也就能體會到漸入佳境之妙了。
動態規劃,
演算法之常,
運用之妙,
存乎一心。
⑼ 《演算法導論(原書第2版)》pdf下載在線閱讀,求百度網盤雲資源
《演算法導論(原書第2版)》([美] Thomas H.Cormen)電子書網盤下載免費在線閱讀
鏈接:https://pan..com/s/1fH3Yg9FLAppoeaKrmc639A
書名:演算法導論(原書第2版)
作者:[美] Thomas H.Cormen
譯者:潘金貴 等
豆瓣評分:9.3
出版社:機械工業出版社
出版年份:2006-9
頁數:754
內容簡介:
這本書深入淺出,全面地介紹了計算機演算法。對每一個演算法的分析既易於理解又十分有趣,並保持了數學嚴謹性。本書的設計目標全面,適用於多種用途。涵蓋的內容有:演算法在計算中的作用,概率分析和隨機演算法的介紹。書中專門討論了線性規劃,介紹了動態規劃的兩個應用,隨機化和線性規劃技術的近似演算法等,還有有關遞歸求解、快速排序中用到的劃分方法與期望線性時間順序統計演算法,以及對貪心演算法元素的討論。此書還介紹了對強連通子圖演算法正確性的證明,對哈密頓迴路和子集求和問題的NP完全性的證明等內容。全書提供了900多個練習題和思考題以及敘述較為詳細的實例研究。
作者簡介:
Thomas H.Cormen
達特茅斯學院計算機科學系副教授
Charles E.Leiserson
麻省理工學院計算機科學與電氣工程系教授
Ronald L.Rivest
麻省理工學院計算機科學系Andrew與Erna Viterbi具名教授
Clifford Stein
哥倫比亞大學工業工程與運籌學副教授
⑽ java數據結構書籍推薦
1. 入門級
針對剛入門的同學,建議不要急著去看那些經典書,像《演算法導論》、《演算法》這些比較經典、權威的書。雖然書很好,但看起來很費勁,如果看不完,效果會很不好。所以建議先看兩本入門級的趣味書:
《大話數據結構》
《演算法圖解》
大話數據結構
將理論講的很有趣,不枯燥。作者結合生活中的例子去對每個數據結構和演算法進行講解,讓人通俗易懂。
演算法圖解
這是一本像小說一樣有趣的演算法入門書,書中有大量的圖解,通俗易懂。
看完上面一本或兩本入門級的書,你就會對數據結構和演算法有個大概認識和學習。但這些入門級的書缺少細節、不夠系統。所以想要深入的學習數據結構和演算法,光看這兩本書肯定是不夠的。
2. 不同語言的教科書
國內外很多大學都是將《數據結構和演算法分析》作為教科書。這本書非常系統、嚴謹、全面,難度適中,很適合對數據結構和演算法有些了解,並且已經掌握了至少一門語言的同學學習。針對不同的語言,分別有:
《數據結構與演算法分析:C語言描述》
《數據結構與演算法分析:C++描述》
《數據結構與演算法分析:java語言描述》
如果你不會C、C++、java,會Python或者JavaScript,可以看:
《數據結構與演算法JavaScript描述》
《數據結構與演算法:Python語言描述》
3. 面試書籍
現在很多大廠的面試都會考演算法題,這里推薦幾本面試演算法書籍:
《劍指offer》
《編程珠璣》
《編程之美》
劍指offer
為面試演算法量身定做的一本書。幾乎包含了所有常見的、經典的面試題,如果能搞懂書裡面的內容,一般公司的演算法面試都應該沒問題。
編程珠璣
這本書豆瓣評分有9分,評分很高。這本書最大的特色是講了很多海量數據的處理技巧。其他演算法書籍很少涉及海量數據。
編程之美
有些作者是微軟工程師,演算法題目較難,比較適合要面試Google、Facebook這樣的公司的人去看。
4. 經典書籍
現在數據結構與演算法最經典的書籍就是:
《演算法導論》
《演算法》
《計算機程序設計藝術》
這三本書非常經典,但都很厚,看起來比較費勁,估計很少有人能全部看完。但如果想更深入地學一遍數據結構和演算法,還是建議去看看。
演算法導論
章節安排不是循序漸進,裡面有各種演算法正確性、復雜度的證明、推導,對數學功底有一定要求,看起來有些費勁。
演算法
偏重講演算法。內容不夠全面,對數據結構方面的知識講的不多,動態規劃這么重要的知識點卻沒有講。
計算機程序設計藝術
這本書包括很多卷,相比於其他書籍有更好的深度、廣度、系統性和全面性。但如果你對數據結構和演算法不是特別感興趣,沒有很好的數學、演算法、計算機基礎,很難把這本書讀完、讀懂。
5. 課外閱讀
有些演算法書籍也比較適合在平時悠閑的時候翻翻看看:
《演算法帝國》
《數學之美》
《演算法之美》
這些書都列舉了大量的列子來解釋說明,非常通俗易懂。