演算法設計軟體
⑴ 數據結構和演算法在實際的軟體開發中都有哪些
應用太多了。
基本上來說C#是基於面向對象語言,你所定義的所有類/結構體都算是數據結構,而且在.net類庫中已經定義中諸多可用的類型以供使用。實際開發中根本就離不開結構與演算法。
題主之所以有這樣的問題,基本上認識到了很多程序員易犯的一個毛病——理論知識與實際應用中的脫節問題,不少程序員都說自己寫程序用不上理論知識,或者是理論無用。我一直認為理論才是真正編程的指導,別說你所學的理論知識了,有時我們必須遵守一些軟體活動上的標准/規范/規定。比如ISO29500標准有多少程序員讀過或聽說過?他實事就是關於openxml的一個國際標准,我們要想達到通用的程序,這些標准還是讀一讀的好。
扯回你的問題,什麼是數據結構,什麼是演算法?如果你真的狹義理由數據結構,或者只是從課本上例子來說,數據結構被定義成一個只有屬性成員的類或結構體才算是數據結構嗎?事實上並不是,那麼是不是只有鏈表/棧/隊列才算是數據結構呢?可以說這是某些人狹義理解數據結構時的一種常規定勢思維,但事實上來說,類或結構是數據結構的基本,否則你鏈表存在的實體到底是什麼東西?所以數據結構包含著基本結構與狹義上的順序表/鏈表/棧/隊等存在實體的集體。為什麼我說數據結構在實際運用中廣泛體現呢?就數據結構而言,課本上只是為了講明白結構而已,弱化了其中實體的真正含義,而且不語言的具體實現亦不盡相同,所以他們所講的數據結構是基本理論的。
我來個例子:鏈表(C#語言)
publicclassMember
{
publicstringName{get;set;}
publicstringResponsibility{get;set;}
publicstringPosotion{get;set;}
}
publicclassMemberNode
{
publicMemberMember{get;set;}
publicMemberNext{get;set;}
}
//Node其他就是鏈表中的一個結點結構,這個結點結構除了指明當前的Member之下還指向下Next的下一個結構結構,它最終可以形成一個鏈表。這就是定義的一個鏈表。
從以上例子上你可以看出這是一個類似於課本的標準定義,但事實上在C#語法中存在泛型的特點,那麼這類似的結構我們不須要一個個地定義了!所以在不同的語言中為了方便編程者,我們甚至可以把這樣的結構進行簡單化,從而達到一種最簡單的使用方式。以C#為例,我們可以使用Node<T>來表示鏈表/List<T>表示順序表/Stack<T>表示棧/Queue<T>表示隊列,在這種情況下,我們只需要定義我們的泛型即可,結構鏈之類的本身使用泛型已經在類庫中實現了——雖然你不用定義,但不代表不使用或者不用理解這其中的知識。而在課本講理論的時候,他不可能附帶泛型來講的,所以很多人認為自己去定義數據結構才行,那才是「真正」的數據結構,其實不然。以鏈表為例,我們需要一個節點除了其實體意義之外,還存在指向下一結點的指針(其實是地址引用)才算是數據結構。根據課本,他們必須這么定義(C#):
publicclassMemberNode
{
publicstringName{get;set;}
publicstringResponsibility{get;set;}
publicstringPosition{get;set;}
publicMemberNodeNext{get;set;}
}
//死讀書的只會承認這種才是真正的數據結構吧(鏈表節點)
事實上,鏈表講的只是一種形式,能最終形成的一種組織數據結構的形式。這個代碼會導致我們出現一種極大的誤解——每個類型的結構都需要重新定義一次。如果有多個類型結構的話,我們會出現多個不同的定義,這會導致將來類的定義越來越多,對於維護上來說是比較麻煩的。由於設計模式/面向切片等各種開發方式的介入,我們會使用相對比較簡單的形式。所以才會有我定義兩個類的進步,而後可以出現泛型的更進一步。
你可以這樣理解,這種課本上的結構,會導致我們造成每種結構基本上都需要重新定義一次,我最開始給出的例子可以使用繼承的方式,實現某個基類的數據結構(下面的似乎也行,但在使用中可能會出現部分問題),而Node<T>則從根本上解決了這個問題,可以支撐多種類型。
所以此時在理解數據結構時,比如Node<T>,他不旦要求理解鏈表的節點,還要理解T泛型,那麼在數據結構上來說,它指的不再是單一的節點結構,還在包括一個基礎的類型。
換句話來說,你在C#等語言中已經不需要再做類似的定義了,只需要定義其基本結構類型即可。但課本上在講知識的時候,它不可能只針對面向對象或支持泛型的語言來講,若不支持泛型時,我們必須使用課本上或我最開始寫的例子中的形式,若不支持繼承的面向過程語言,那麼課本上的知識就是硬性的規定,你必須以這種形式來說,而引用則使用指針引用的方式(面向對象的引用其實是一種引用型引用,也就是址引用或稱地址引用,與指針類似)。
相信講到這里你能明白,數據結構在不同的語言中只是變了個形而已,並不是必須是存在指針的才是,也不是只說表面上的那點東西。早期教程都是以fortain語言為主的,而且課本的目的是講清道理,而不是一種規定。死讀書的人以為用不到數據結構,其實他們一直在使用。
再來說一下演算法,演算法是什麼?是解決問題的一種模式,比如解二元一次方程等等,所以演算法的定義其實已經告訴你,順序代碼他也算是一種演算法,不能說只有背包問題,八皇後問題,回溯問題才算是演算法——你能明白嗎?其實你正常寫的就是一種演算法,這種演算法簡單,就是順序執行下來就可以了,他也是一種演算法的,就算解二元一次方程組有固定的模式(演算法),但不代表加減法就不是演算法了!所以演算法也是常用的東西,那麼你學習的演算法其實算是開辟思路的一種而已。演算法自身的概念已經決定,基本上程序都是由結構與演算法構成。我也來舉個例子,怎麼判斷某個鏈表是否為循環鏈表?是你的回溯演算法,貪心演算法還是背包演算法?它們只是在解決一些典型問題的一種通用方式而已,很顯然,我的問題不是這種典型問題,但不代表他不典型,我們正常的演算法是設計兩個變數等於頭元素,然後開始進入循環,一個變數每次向下推一,即找到他下一個節點,而另一個變數每次找到其孫節點,就算當於兩個變數一個每次向下推進一次,而另一個每點推進兩次(如果可能),如果不是循環鏈表,則進兩次的那個會在鏈表總長度的一半時,遇到空引用,否則會在某一時間兩指針引用同一對象(不是對象相等,而是引用相同的對象),什麼意思呢,好象兩個人在圓型跑道上跑步,一個每秒1米,另一個每秒2米,同時同地同向出發,最歸跑得快的那個會追上跑得慢的那個!當然這種情況下你也可以給他起個名字,叫「追及演算法」?如果只有你學的那幾個典型演算法是演算法的話,這個算不算演算法?
現在我們的問題是,如果語言層面上已經實現了這些東西,那麼這些理論我們是否可以不用理解就可以了?答案是可以——如果你只是一個不思進取的程序員或允許bug亂飛的沒有責任心的編程人員的話,可以不用理解——畢竟有些人只是「混」飯吃而已!
理解了不會去應用,這就是典型的理論聯系不到實際,他們也不知道自己的代碼將如何控制。我舉一個例子,由於性能等各方面的要求,我們要使用多線程對某些數據進行處理。怎麼處理?不好人會使用多線程——他們定義一個臨界資源,然後讓多個線程在讀取數據表(DataSet)時進行阻塞,然後每個線程去處理那些超時長的問題,處理完的時個再按這種方式讀取數據——這樣有問題嗎?沒有,這也算是演算法的一種!反正如果編程代碼有功底的話沒有任何問題的,這種代碼算不算優雅呢——很多人認為代碼的優雅就是代碼編寫過程的形式或是良好的編程習慣!這里邊其實用不到數據結構與演算法的。
好吧,我承認,但如果我們換一句思路來看看,如果我用一個線程負責讀取數據,並不停地放入到一個隊列中,而多個線程從隊列中不停地讀取處理這些放入的數據,這樣如何?我的意思是說,並沒有直接在DataSet中處理,而是選擇使用隊列的方式。
我們看一個問題,這個隊列Queue<T>,一個線程用來插入數據,多個線程用來讀取數據,而且要保證不能重復,那麼我們可以使用隊列的安全版本(CorrentQueue<T>,在.net中如果非線程安全的情況下,多線程使用實應該找到其對應的安全版本或者控制線程安全)。
插入線程如果發現隊列中的長度(容量)較大時,可以暫緩插入。這樣可以保證隊列的長度基本固定,佔用內存得到控制(不是DataSet批量讀來一大堆),由於使用安全隊列,所以各線程不用考慮線程之間的安全問題,每個線程從隊中獲得數據並刪除,可以保證數據只被處理一次。當然還可以考慮優雅的通知機制,插入線程在插入數據時通知處理線程啟動,如果插入速度過快,發現插入數量達指定的長度(比如30個),停止插入,插入線程阻塞;處理處理再次處理時可通知插入線程再進行插入。
這也算是一種演算法吧?它可以讓插入線程與處理線程同時工作,而使用DataSet那種常規的結果時,只能是等待處理完或加入多個控制條件進行控制,既然這么控制的話,何不直接使用隊列的方式?CorrentQueue<T>中的T也完全可以是一條記錄DataRow嘛!
如果你認為第一種是你經常使用方式,那麼演算法對於你來說學與不學無所謂的,你必須使用自己的編程/調試功底以保證你的代碼盡量很少出錯或不出錯。而如果你認為第二種方案優雅一些的話,那麼你會認為你學習的演算法與結構還是有用的,理論與實踐結合了。
我之所以舉這么一個例子,其實告訴你的無非是幾點非常重要的信息:
你有選擇演算法的自由(只不過是代碼質量、後期維護的問題)
如果你知道的較多的演算法與結構,你會有更多的選擇。
演算法或結構在實際使用中,所謂的典型問題並不是使用場景和書上描述一模一樣(試想一下,我第二種考慮的例子中,是不是跟書上比他不典型?其實也是非常典型的)
分析問題時,應該拿要點,而不是整體去套。(如果整體去套用的話,你肯定會想不到使用哪種結構或演算法)
不管是數據結構/演算法/設計模式都要求是靈活運用,而不是場景對比使用,也不是生搬硬套。
試想一下,你的背包問題,怎麼可能公司也讓你分拆包裝?你的八皇後問題公司恰好讓你下棋?你的貪心演算法公司恰好讓你找零錢?你的回溯演算法公司恰好讓你走迷宮?學不能致用的原因就是太死板——這幾個舉個例子的場景你再遇到或理能遇到的機率是非常小的,所以如果覺得學了沒用,那就真沒用了——只不過不是演算法沒用,而是人沒人!
講個小故事:從前一個家人的板凳壞了,要找一個合適的兩股叉的樹杈重新製做一個板凳腿,讓孩子到樹園里找了半天,孩子回來說「我都沒見過有向下叉的樹杈!他老爹氣得要死——怎麼會可能有向下長的樹杈呢!這孩子是不是笨——你就不會把地刨了找一個向下分叉的樹根!
演算法也是一樣,迷宮找路可以使用回溯演算法,但不是所有的回溯演算法都用於迷宮找路——它還可以用來設計迷宮!嘿嘿嘿!
⑵ 數學建模的方法有哪些
預測模塊:灰色預測、時間序列預測、神經網路預測、曲線擬合(線性回歸);
歸類判別:歐氏距離判別、fisher判別等 ;
圖論:最短路徑求法 ;
最優化:列方程組 用lindo 或 lingo軟體解 ;
其他方法:層次分析法 馬爾可夫鏈 主成分析法 等 。
建模常用演算法,僅供參考:
蒙特卡羅演算法(該演算法又稱隨機性模擬演算法,是通過計算機模擬來解決 問題的演算法,同時間=可以通過模擬可以來檢驗自己模型的正確性,是比賽時必 用的方法) 。
數據擬合、參數估計、插值等數據處理演算法(比賽中通常會遇到大量的數 據需要處理,而處理數據的關鍵就在於這些演算法,通常使用Matlab 作為工具) 。
線性規劃、整數規劃、多元規劃、二次規劃等規劃類問題(建模競賽大多 數問題屬於最優化問題,很多時候這些問題可以用數學規劃演算法來描述,通 常使用Lindo、Lingo 軟體實現) 。
圖論演算法(這類演算法可以分為很多種,包括最短路、網路流、二分圖等算 法,涉及到圖論的問題可以用這些方法解決,需要認真准備) 。
動態規劃、回溯搜索、分治演算法、分支定界等計算機演算法(這些演算法是算 法設計中比較常用的方法,很多場合可以用到競賽中) 。
最優化理論的三大非經典演算法:模擬退火法、神經網路、遺傳演算法(這些 問題是用來解決一些較困難的最優化問題的演算法,對於有些問題非常有幫助, 但是演算法的實現比較困難,需慎重使用) 。
網格演算法和窮舉法(網格演算法和窮舉法都是暴力搜索最優點的演算法,在很 多競賽題中有應用,當重點討論模型本身而輕視演算法的時候,可以使用這種 暴力方案,最好使用一些高級語言作為編程工具) 。
一些連續離散化方法(很多問題都是實際來的,數據可以是連續的,而計 算機只認的是離散的數據,因此將其離散化後進行差分代替微分、求和代替 積分等思想是非常重要的) 。
數值分析演算法(如果在比賽中採用高級語言進行編程的話,那一些數值分 析中常用的演算法比如方程組求解、矩陣運算、函數積分等演算法就需要額外編 寫庫函數進行調用) 。
圖象處理演算法(賽題中有一類問題與圖形有關,即使與圖形無關,論文 中也應該要不乏圖片的,這些圖形如何展示以及如何處理就是需要解決的問 題,通常使用Matlab 進行處理)。
⑶ 學關於數學建模的推薦書籍以及入門級使用的編程軟體及教材
我也要參加今年九月份的數學建模比賽,以下是我們老師給我們的幾點建議,希望對你有些幫助。
賽前學習內容
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.排隊論
不知道能不能幫上你