導航:首頁 > 源碼編譯 > 演算法天下

演算法天下

發布時間:2022-07-28 13:34:11

❶ 用C++編寫一個洗牌發牌的函數,玩家可能有兩個、三個和四個

幾乎所有的程序員都寫過類似於「洗牌」的演算法,也就是將一個數組隨機打亂後輸出,雖然很簡單,但是深入研究起來,這個小小的演算法也是大有講究。我在面試程序員的時候,就會經常讓他們當場寫一個洗牌的函數,從中可以觀察到他們對於這個問題的理解和寫程序的基本功。

在深入討論之前,必須先定義出一個基本概念:究竟洗牌演算法的本質是什麼?也就是說,什麼樣的洗牌結果是「正確」的?

雲風曾經有一篇博文,專門討論了這個問題,他也給出了一個比較確切的定義,在經過洗牌函數後,如果能夠保證每一個數據出現在所有位置的概率是相等的,那麼這種演算法是符合要求的。在這個前提下,盡量降低時間復雜度和空間復雜度就能得到好的演算法。

第一個洗牌演算法:

隨機抽出一張牌,檢查這張牌是否被抽取過,如果已經被抽取過,則重新抽取,直到找到沒被抽出過的牌,然後把這張牌放入洗好的隊列中,重復該過程,直到所有的牌被抽出。

大概是比較符合大腦對於洗牌的直觀思維,這個演算法經常出現在我遇到的面試結果中,雖然它符合我們對於洗牌演算法的基本要求,但這個演算法並不好,首先它的復雜度為O(N2),而且需要額外的內存空間保存已經被抽出的牌的索引。所以當數據量比較大時,會極大降低效率。

第二個演算法:

設牌的張數為n,首先准備n個不容易碰撞的隨機數,然後進行排序,通過排序可以得到一個打亂次序的序列,按照這個序列將牌打亂。

這也是一個符合要求的演算法,但是同樣需要額外的存儲空間,在復雜度上也會取決於所採用的排序演算法,所以仍然不是一個好的演算法。

第三個演算法:

每次隨機抽出兩張牌交換,重復交換一定次數次後結束

void shuffle(int* data, int length)

{

for(int i=0; i<SWAP_COUNTS; i++)

{

//Rand(min, max)返回[min, max)區間內的隨機數

int index1 = Rand(0, length);

int index2 = Rand(0, length);

std::swap(data[index1], data[index2]);

}

}

這又是一個常見的洗牌方法,比較有意思的問題是其中的「交換次數」,我們該如何確定一個合適的交換次數?簡單的計算,交換m次後,具體某張牌始終沒有被抽到的概率為((n-2)/n)^m,如果我們要求這個概率小於1/1000,那麼 m>-3*ln(10)/ln(1-2/n),對於52張牌,這個數大約是176次,需要注意的是,這是滿足「具體某張牌」始終沒有被抽到的概率,如果需要滿足「任意一張牌」沒被抽到的概率小於1/1000,需要的次數還要大一些,但這個概率計算起來比較復雜,有興趣的朋友可以試一下。

Update: 這個概率是,推算過程可以參考這里,根據這個概率,需要交換280次才能符合要求

第四個演算法:

從第一張牌開始,將每張牌和隨機的一張牌進行交換

void shuffle(int* data, int length)

{

for(int i=0; i<length; i++)

{

int index = Rand(0, length);

std::swap(data[i], data[index]);

}

}

很明顯,這個演算法是符合我們先前的要求的,時間復雜度為O(N),而且也不需要額外的臨時空間,似乎我們找到了最優的演算法,然而事實並非如此,看下一個演算法。

第五個演算法:

void shuffle(int* data, int length)

{

for(int i=1; i<length; i++)

{

int index = Rand(0, i);

std::swap(data[i], data[index]);

}

}

一個有意思的情況出現了,這個演算法和第三種演算法非常相似,從直覺來說,似乎使數據「雜亂」的能力還要弱於第三種,但事實上,這種演算法要強於第三種。要想嚴格的證明這一點並不容易,需要一些數學功底,有興趣的朋友可以參照一下這篇論文,或者matrix67大牛的博文,也可以這樣簡單理解一下,對於n張牌的數據,實際排列的可能情況為n! 種,但第四種演算法能夠產生n^n種排列,遠遠大於實際的排列情況,而且n^n不能被n!整除,所以經過演算法四所定義的牌與牌之間的交換程序,很可能一張牌被換來換去又被換回到原來的位置,所以這個演算法不是最優的。而演算法五輸出的可能組合恰好是n!種,所以這個演算法才是完美的。

事情並沒有結束,如果真的要找一個最優的演算法,還是請出最終的冠軍吧!

第六個演算法:

void shuffle(int* data, int length)

{

std::random_shuffle(data, data+length);

}

沒錯,用c++的標准庫函數才是最優方案,事實上,std::random_shuffle在實現上也是採取了第四種方法,看來還是那句話,「不要重復製造輪子」

不想寫 - -

❷ 發現其實我學計算機其實是對的,因為計算機這個新興的東西才是賺錢的一個利器!

計算機不是新興的東西,復雜的邏輯,未來是智能演算法的天下。人腦追不上了。不知道你學的什麼

❸ C++學習及哪些應用

c++最好是學好數學,高數,線性代數,因為電腦程序主要是演算法的天下;
而你如果剛接觸其實也不急和高級的數學掛鉤。
建議配套學習的是數據結構,其實數據結構也算是c++,具體你學了就明白其中的意思了

❹ 學習數據結構,有哪些值得推薦的好書

在微信高校專業集裡面粘貼
入門
1.《啊哈!演算法》
2.《演算法設計與分析基礎》
3.《演算法引論:一種創造性方法》
4.原書名:Introction to Algorithms
中文名:演算法導論
5.數據結構與演算法分析:C語言描述(原書第2版)
進階
1.原書名:The Design and Analysis of Computer Algorithms
中文名:演算法設計與分析
作者:Aho,Hopcroft,Ullman
2.原書名:Algorithms Design Techniques and Analysis
中文名:演算法設計技巧與分析
作者:M.H.Alsuwaiyel
3.中文名:演算法與數據結構
作者:傅清祥 王曉東
程序設計競賽
1.原書名:Introction to Algorithms
中文名:演算法導論
作者:Thomas H.Cormen,Charles E.Leiserson,Ronald L.Rivest,Clifford Stein
2.原書名:Introction to The Design & Analysis of Algorithms
中文名:演算法設計與分析基礎
作者:Anany Levitin
4.演算法競賽 | 信息學奧賽一本通
5.演算法競賽 | 演算法競賽進階指南

❺ c++,請問各位 c++有哪些比較好的書推薦

遠標老師以前推薦我看《數據結構》可以拿來入門。然後可以根據自己的實際情況來安排怎麼樣學習數據結構。很多人是看一遍書,然後在遇到演算法之後再去實現它。在這里列出一些我知道的演算法書籍,以供參考。(我也只看過演算法導論,編程之美)

1. CLRS 演算法導論
演算法網路全書,只做了前面十幾章的習題,便感覺受益無窮。
2. Algorithms 演算法概論
短小精悍,別據一格,准經典之作。一個壞消息: 同演算法導論,該書沒有習題答案。好消息:習題很經典,難度也適中,只需花點點時間自己也都能做出來。不好也不壞的消息:我正在寫習題的答案,已完成前三章,還剩九章約二百道題,順利的話二個月之後發布。另有中文版名《演算法概論》,我沒看過,不知道翻譯得怎麼樣。如果有心的話,還是盡量看原版吧,其實看原版與看中文版花費時間不會相差很大,因為大部分時間其實都花費在做習題上了。
dr. dobb's essential books on Algorithm and daba structure
3. Algorithm Design 演算法設計
很經典的一本書,很久之前看的,遺憾的是現在除了就記得它很經典之外其它都忘光了。
4. SICP 計算機程序的構造和解釋
六星之書無需多言,雖然這不是一本講演算法的書,但看完此書有助於你更深入的理解什麼是遞歸。我一直很強調習題,看完此書後你至少應該做完前四章的太部分習題。否則那是你的遺憾,也是作者的遺憾。
5. Concrete Mathematics 具體數學
有人說看TAOCP之前應該先弄清楚這本書的內容,要真是如此的話那我恐怕是看不到TAOCP了。零零碎碎的看了一大半,很多東西都沒有時間來好好消化。如果你是剛進大學不久的本科生,有著大把的可自由支配時間,那你幸運又幸福了,花上幾個月時間好好的讀一下此書吧,收獲絕對大於你的期望值。
6. Introction to The Design and Analysis of Algorithms 演算法設計與分析基礎
很有趣的一本演算法書,有許多在別的書上找不到的趣題,看完此書絕對能讓你大開眼界,實在是一本居家旅行,面試裝逼的必備佳作。
7. 編程之美--微軟技術面試心得
雖說是一本面試書,但如果把前面十幾頁扯掉的話,我更願意把它看作是一本講解題思維的演算法小品。在書中,作者通常是給出一個平常解法,然後再一次又一次的優化改進,你可以很清楚的看到基本的演算法設計思想是如何得到運用以解決實際問題的。如果你已經有了一些演算法的基礎,看完本書應該能使你的演算法應用能力得到一定的提高。另外,本書生動有趣,也同樣適合於初學者。
8. Fundamentals of Algorithmics 演算法基礎
也是很久之前在學校圖書館借來看的,內容記不太清楚了,只隱約記得此書的動態規劃章節猶為出彩。應該是很經典的一本書,個人以為足以和演算法導論等所謂當世經典平分秋色,但是怎麼好像被人提到的不多,或許是我孤陋寡聞了。
9. How to solve it 怎樣解題
二十世紀最偉大的數學思想家之一波利亞的力作,講一般性的解題方法:怎麼認識問題,怎麼轉換問題,怎麼解決問題,如何在問題中得到啟發,如何找到一個通往答案的方向。
10. Programming interviews exposed 程序員面試攻略
一本消遣之作。個人以為要比國內的某「XXX面試寶典」純粹一些,至少也有一些啟發性的內容,而不單單是面試題解庫。
11. Programming Pearls 編程珠璣
學習演算法不僅需要像Alogrithms,演算法導論這樣的重量級的內功心法,像《編程之美》、《編程珠璣》這樣的輕量級的輕功身法也必不可少。前些年網上不是很流行像「給你10億個數,找到最大的n個」或者「給你10億個數,找出現次數最多的那個數」之類的網路面試題嗎?看了此書你就知道怎麼解決了。相比於《編程之美》來說,本書中的示例技巧性略低一些,但是也更有實際應用價值一些。
12. 演算法藝術與信息學競賽
如果演算法導論是九陽神功,那這本無疑就是九陰真經。本書是專為參加一些諸如ACM之類程序設計比賽的同學而寫的,江湖人稱「黑書」。裡面講的都是一些在編程比賽中常用的演算法、數據結構,以及一些數論和計算幾何等。我雖然並不搞競賽,但也從此書中受益頗多。
13. An Introction to Probability Theory and Its Applications
准備看的,現在才發現概率論有多麼重要,可惜本科的時候沒有好好學。前不久一個同學問我個問題,我半天弄了一個程序給他,他說:這里就不是相關系數么,Excel一下就完事!我暈,我還真不知道那就是相關系數。
14. Numerical Analysis
這本的作者是Richard L. Burden,J. Douglas Faires
數值分析,討論各種數值演算法,比如插值、擬合、積分、微分方程的求解、線性和非線性方程組求解等。准備詳細看。
15. TAOCP 計算機程序設計藝術
傳說中的TAOCP,說的人多,看的人少。TAOCP四卷堪稱是演算法藏經閣中的易筋經或者是少林七十二絕技。天下武學,盡出少林,天下演算法,盡出TAOCP也。這點你可以順便翻開一本演算法書看看他的引用文獻就知道了。我只讀了第四卷的部分章節,前三卷暫時還沒敢看,還在讀書計劃表中被無限期擱置。
面的「故障簡要基本解決套路」以及案例,找

❻ 尋醫問葯網在線咨詢

你實際的受孕時間在2014.07.31.左右,到2014.11.21.如果確定已孕,應當3個月又3周。
人類正常的孕期是266天,你的預產期應在2015.04.21.左右,提前或推後14天以內都算正常。
十月懷胎只是傳說,按照那種演算法,天下的女人自初潮次月到絕經,每人每次月經時都懷孕1個月了!太荒唐!

❼ 人工智慧正在邁向技術奇點嗎

人工智慧在近年來遇到了極好的發展機遇,互聯網、移動互聯網的普及讓人類的數據觸手可及,計算技術的快速發展讓機器快速處理海量數據變成了現實,「大數據、大計算」讓神經網路以深度學習的名號重出江湖。但是這並不能說人工智慧在核心技術上就有多大的突破。現有的人工智慧技術在本質上還是按照人類設計的固定演算法來思考,依然是一種機械地執行人類智能而已。所謂的機器學習,它只是人類利用機器的計算能力來學習而已,其主語是人類,而非機器。

❽ 深度學習與神經網路有什麼區別

深度學習與神經網路關系

2017-01-10

最近開始學習深度學習,基本上都是zouxy09博主的文章,寫的蠻好,很全面,也會根據自己的思路,做下刪減,細化。

五、Deep Learning的基本思想

假設我們有一個系統S,它有n層(S1,…Sn),它的輸入是I,輸出是O,形象地表示為: I =>S1=>S2=>…..=>Sn => O,如果輸出O等於輸入I,即輸入I經過這個系統變化之後沒有任何的信息損失(呵呵,大牛說,這是不可能的。資訊理論中有個「信息逐層丟失」的說法(信息處理不等式),設處理a信息得到b,再對b處理得到c,那麼可以證明:a和c的互信息不會超過a和b的互信息。這表明信息處理不會增加信息,大部分處理會丟失信息。當然了,如果丟掉的是沒用的信息那多好啊),保持了不變,這意味著輸入I經過每一層Si都沒有任何的信息損失,即在任何一層Si,它都是原有信息(即輸入I)的另外一種表示。現在回到我們的主題Deep Learning,我們需要自動地學習特徵,假設我們有一堆輸入I(如一堆圖像或者文本),假設我們設計了一個系統S(有n層),我們通過調整系統中參數,使得它的輸出仍然是輸入I,那麼我們就可以自動地獲取得到輸入I的一系列層次特徵,即S1,…, Sn。

對於深度學習來說,其思想就是對堆疊多個層,也就是說這一層的輸出作為下一層的輸入。通過這種方式,就可以實現對輸入信息進行分級表達了。

另外,前面是假設輸出嚴格地等於輸入,這個限制太嚴格,我們可以略微地放鬆這個限制,例如我們只要使得輸入與輸出的差別盡可能地小即可,這個放鬆會導致另外一類不同的Deep Learning方法。上述就是Deep Learning的基本思想。

六、淺層學習(Shallow Learning)和深度學習(Deep Learning)

淺層學習是機器學習的第一次浪潮。

20世紀80年代末期,用於人工神經網路的反向傳播演算法(也叫Back Propagation演算法或者BP演算法)的發明,給機器學習帶來了希望,掀起了基於統計模型的機器學習熱潮。這個熱潮一直持續到今天。人們發現,利用BP演算法可以讓一個人工神經網路模型從大量訓練樣本中學習統計規律,從而對未知事件做預測。這種基於統計的機器學習方法比起過去基於人工規則的系統,在很多方面顯出優越性。這個時候的人工神經網路,雖也被稱作多層感知機(Multi-layer Perceptron),但實際是種只含有一層隱層節點的淺層模型。

20世紀90年代,各種各樣的淺層機器學習模型相繼被提出,例如支撐向量機(SVM,Support Vector Machines)、 Boosting、最大熵方法(如LR,Logistic Regression)等。這些模型的結構基本上可以看成帶有一層隱層節點(如SVM、Boosting),或沒有隱層節點(如LR)。這些模型無論是在理論分析還是應用中都獲得了巨大的成功。相比之下,由於理論分析的難度大,訓練方法又需要很多經驗和技巧,這個時期淺層人工神經網路反而相對沉寂。

深度學習是機器學習的第二次浪潮。

2006年,加拿大多倫多大學教授、機器學習領域的泰斗Geoffrey Hinton和他的學生RuslanSalakhutdinov在《科學》上發表了一篇文章,開啟了深度學習在學術界和工業界的浪潮。這篇文章有兩個主要觀點:1)多隱層的人工神經網路具有優異的特徵學習能力,學習得到的特徵對數據有更本質的刻畫,從而有利於可視化或分類;2)深度神經網路在訓練上的難度,可以通過「逐層初始化」(layer-wise pre-training)來有效克服,在這篇文章中,逐層初始化是通過無監督學習實現的。

當前多數分類、回歸等學習方法為淺層結構演算法,其局限性在於有限樣本和計算單元情況下對復雜函數的表示能力有限,針對復雜分類問題其泛化能力受到一定製約。深度學習可通過學習一種深層非線性網路結構,實現復雜函數逼近,表徵輸入數據分布式表示,並展現了強大的從少數樣本集中學習數據集本質特徵的能力。(多層的好處是可以用較少的參數表示復雜的函數)

而為了克服神經網路訓練中的問題,DL採用了與神經網路很不同的訓練機制。傳統神經網路(這里作者主要指前向神經網路)中,採用的是back propagation的方式進行,簡單來講就是採用迭代的演算法來訓練整個網路,隨機設定初值,計算當前網路的輸出,然後根據當前輸出和label之間的差去改變前面各層的參數,直到收斂(整體是一個梯度下降法)。而deep learning整體上是一個layer-wise的訓練機制。這樣做的原因是因為,如果採用back propagation的機制,對於一個deep network(7層以上),殘差傳播到最前面的層已經變得太小,出現所謂的gradient diffusion(梯度擴散)。這個問題我們接下來討論。

八、Deep learning訓練過程

8.1、傳統神經網路的訓練方法為什麼不能用在深度神經網路

BP演算法作為傳統訓練多層網路的典型演算法,實際上對僅含幾層網路,該訓練方法就已經很不理想。深度結構(涉及多個非線性處理單元層)非凸目標代價函數中普遍存在的局部最小是訓練困難的主要來源。

BP演算法存在的問題:

(1)梯度越來越稀疏:從頂層越往下,誤差校正信號越來越小;

(2)收斂到局部最小值:尤其是從遠離最優區域開始的時候(隨機值初始化會導致這種情況的發生);

(3)一般,我們只能用有標簽的數據來訓練:但大部分的數據是沒標簽的,而大腦可以從沒有標簽的的數據中學習;

8.2、deep learning訓練過程

如果對所有層同時訓練,時間復雜度會太高;如果每次訓練一層,偏差就會逐層傳遞。這會面臨跟上面監督學習中相反的問題,會嚴重欠擬合(因為深度網路的神經元和參數太多了)。

2006年,hinton提出了在非監督數據上建立多層神經網路的一個有效方法,簡單的說,分為兩步,一是每次訓練一層網路,二是調優,使原始表示x向上生成的高級表示r和該高級表示r向下生成的x'盡可能一致。方法是:

1)首先逐層構建單層神經元,這樣每次都是訓練一個單層網路。

2)當所有層訓練完後,Hinton使用wake-sleep演算法進行調優。

將除最頂層的其它層間的權重變為雙向的,這樣最頂層仍然是一個單層神經網路,而其它層則變為了圖模型。向上的權重用於「認知」,向下的權重用於「生成」。然後使用Wake-Sleep演算法調整所有的權重。讓認知和生成達成一致,也就是保證生成的最頂層表示能夠盡可能正確的復原底層的結點。比如頂層的一個結點表示人臉,那麼所有人臉的圖像應該激活這個結點,並且這個結果向下生成的圖像應該能夠表現為一個大概的人臉圖像。Wake-Sleep演算法分為醒(wake)和睡(sleep)兩個部分。

1)wake階段:認知過程,通過外界的特徵和向上的權重(認知權重)產生每一層的抽象表示(結點狀態),並且使用梯度下降修改層間的下行權重(生成權重)。也就是「如果現實跟我想像的不一樣,改變我的權重使得我想像的東西就是這樣的」。

2)sleep階段:生成過程,通過頂層表示(醒時學得的概念)和向下權重,生成底層的狀態,同時修改層間向上的權重。也就是「如果夢中的景象不是我腦中的相應概念,改變我的認知權重使得這種景象在我看來就是這個概念」。

deep learning訓練過程具體如下:

1)使用自下上升非監督學習(就是從底層開始,一層一層的往頂層訓練):

採用無標定數據(有標定數據也可)分層訓練各層參數,這一步可以看作是一個無監督訓練過程,是和傳統神經網路區別最大的部分(這個過程可以看作是feature learning過程):

具體的,先用無標定數據訓練第一層,訓練時先學習第一層的參數(這一層可以看作是得到一個使得輸出和輸入差別最小的三層神經網路的隱層),由於模型capacity的限制以及稀疏性約束,使得得到的模型能夠學習到數據本身的結構,從而得到比輸入更具有表示能力的特徵;在學習得到第n-1層後,將n-1層的輸出作為第n層的輸入,訓練第n層,由此分別得到各層的參數;

2)自頂向下的監督學習(就是通過帶標簽的數據去訓練,誤差自頂向下傳輸,對網路進行微調):

基於第一步得到的各層參數進一步fine-tune整個多層模型的參數,這一步是一個有監督訓練過程;第一步類似神經網路的隨機初始化初值過程,由於DL的第一步不是隨機初始化,而是通過學習輸入數據的結構得到的,因而這個初值更接近全局最優,從而能夠取得更好的效果;所以deep learning效果好很大程度上歸功於第一步的feature learning過程。

閱讀全文

與演算法天下相關的資料

熱點內容
手中的app如何隱藏 瀏覽:1001
安卓什麼壁紙軟體號 瀏覽:436
java設置內存大小 瀏覽:434
php循環匹配 瀏覽:323
技巧pdf 瀏覽:479
單片機斷程序怎麼解決 瀏覽:160
如何製作APP的圖片 瀏覽:506
php大小排序 瀏覽:548
linuxkerberos 瀏覽:126
暗黑破壞神3如何下載亞洲伺服器 瀏覽:953
linux中ftp伺服器地址怎麼看 瀏覽:438
ansys命令流do 瀏覽:122
單片機6502 瀏覽:765
自助洗車有什麼app 瀏覽:937
程序員離職率多少 瀏覽:322
程序員那麼可愛電視劇今天沒更新 瀏覽:337
我的世界地形演算法 瀏覽:344
台灣dns的伺服器地址雲空間 瀏覽:288
音樂噴泉軟體要什麼加密狗 瀏覽:501
androidhttpmime 瀏覽:774