普林斯頓演算法課下 - assignment 2

weixin_34378969發表於2015-04-08

坐在這個椅子上,腰已經很痠痛了。今天又是花了十個小時左右來寫這個作業,
首先,最重要的一句話。普林斯頓畢竟是普林斯頓。作業實在是太牛逼。
這次對圖,對最短路徑,對貪婪演算法有了很深刻的認識,畢竟寫了這麼多程式碼。
那個老教授說得對,貪心演算法是學生接觸到的第一個日後會經常使用到的演算法思想,對,是演算法思想,而不是演算法。
貪心,就是對路徑長度不停地重新整理,直到選出最優解。
最短路徑也是根據這個求出來的。弄懂了之後也沒覺得有什麼難了。自然,看我這麼一篇文章也不可能弄懂。什麼東西都得是花時間的。
對於有向無內環的圖來說,直接用 topological sort即可得出最短路徑,
複雜度僅為 E + V.
如果是有向有內環圖,則只能使用Dijkstra 最短路徑演算法,複雜度是 ElogV.
如果是有向有內環圖,且有負邊,則用上述演算法會陷入無限迴圈,於是出現了新的演算法,Bell-Fordman 演算法。複雜度為 E*V。
如果是有向有內環圖,且有負邊,且有負迴圈。額。。。天知道了。

然後說說這次作業。
這次作業就拿了90分。最後放棄除錯了,因為錯誤都沒了。剩下的就是 他覺得我記憶體用多了。我把所有用過的物件都申明為null,以此減少記憶體,但是還是太多。我想應該是我實現方法是有問題吧。我是這麼做的。用一個二維陣列來記錄到每一個點最短的energy和。再用一個二維陣列記錄到每一個點的最短路徑上一行的點,類似於edgeTo[].
然後我把topological order壓入棧中,按照老師講的方法來尋找最短路徑,並且不斷優化距離。中途也犯過很多錯誤,但是經過大量時間除錯後都解決了。就是這個記憶體問題。
他測的是 五次水平刪除後 這個Seam物件所佔的大小。只有類成員才會佔記憶體,所以我在每次刪除後,都會將這些大型陣列指向null。等到下次刪除時,再重新生成這些陣列。這樣的確會浪費一些執行時間,但應該所佔用記憶體會很小啊,怎麼會還是這麼大。不理解。
後來我也想過,每次刪除後不釋放那些大型陣列,而是再次重新整理。後來太累了,想不動了,就放棄了。
我覺得topological order總有BFS的影子。一直這麼覺得。最短路徑演算法,就是一層層向外推進,被推到的點,都將被確認為最短路徑點。然後以此作為根據,繼續向外推進。一層一層,不就是BFS麼。。。
還有一個教訓,寫程式碼最好的就是一口氣寫完。我本以為寫的差不多了。然後就和一同學閒聊了好久。結果回來繼續寫發現第一次提交就44分,自己那種狀態也沒了,很浮躁。浪費了大量的時間來除錯。而且把很多對的邏輯又改錯了,走了挺多冤枉路。
Anyway, week2 終於又搞定了。應該還有三節課了吧,一定得跟下去啊。。。

之前有個階段很累,然後bug也一直改不出來,絕望了。上網想找原始碼參考。後來還是放棄了。最終花了大量的時間調出了bug。這次花了一個多小時想著怎麼實現這個程式,還是很有效的。之後寫的比較順利。最高潮的三個小時,寫的我很爽。我感覺我自己在進步。現在也可以寫一些簡單的遍歷了。對於陣列的操作感覺理解更深刻了。這個怎麼說呢?就是看陣列看得更加透徹了。額。。。好像他成為我的一部分了。額。。。

然後是對棧和佇列的理解。也是突然就領悟到,為什麼要有棧,為什麼要有佇列。
其實不是為了存東西,或者說,不是主要為了存東西。而是為了改變事物發生的順序。
棧的話,是先進後出。佇列的話,是先進先出。這是兩種不同的順序,或者說容器的型別。也是做事情的兩種方式。

最後對於迭代器的理解。什麼是迭代器。我覺得iterator翻譯成迭代器很不成功,太複雜,讓人看不清本質。我覺得迭代器就是一種途徑,讓你可以不摸清這個容器裡面是怎麼存放成員的,但是你可以通過迭代器來獲得成員。迭代器是一種快速通道,是黑盒子通往外界的一個通道。

最累的時候,女朋友給我發來了一個碼農猝死的訊息。其實挺害怕的。思考過度應該很容易猝死吧。每次寫普林斯頓作業都是思考過度。。。實在太有挑戰了。
然後很愧疚,沒能幫女朋友做好聽力。實在是扛不住了。我先好好休息下。明天再聽力。
哦,對了。賓大也被拒了。這週五等不到CMU就去康奈爾了。
好運,Richardo. 好運,Shirley.

相關文章