1 / 19

Search (I)

Search (I). for Sprout 2014 by Yuan. 搜尋. 聽起來就很慢 …… 但是 , 無計可施的時候 , 你也只能這樣做 XD 在這個年代 呢 … 資訊界許多好做的問題做得差不多了 , 但是世界上實際的問題 , 模型都不太漂亮 …… 所以就只能暴力搜尋了 , 太複雜了 其中搜尋的過程 ,也許可以透過一些以前學過的演算法加速 可是 … 要怎麼搜尋會比較快 ?. 位元運算. 大家還記得位元運算嗎 XD 一個 32 位元的數 , 可以儲存 32 格 0/1 的狀態

Download Presentation

Search (I)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Search (I) for Sprout 2014 by Yuan

  2. 搜尋 • 聽起來就很慢…… • 但是, 無計可施的時候, 你也只能這樣做 XD • 在這個年代呢…資訊界許多好做的問題做得差不多了, 但是世界上實際的問題, 模型都不太漂亮…… • 所以就只能暴力搜尋了, 太複雜了 • 其中搜尋的過程,也許可以透過一些以前學過的演算法加速 • 可是…要怎麼搜尋會比較快?

  3. 位元運算 • 大家還記得位元運算嗎 XD • 一個32位元的數, 可以儲存32格0/1的狀態 • 01011011001010100100100101010101 • 換句話說, 我們讓原本需要32單位時間的運算縮減成1個單位!

  4. 要不要搜到完呢

  5. 背包問題 • 有N樣物品, N<=40 • 物品的價值<=100000000000000000 • 希望選若干個物品, 湊出恰好總和價值為M • 該怎麼選 ?

  6. 我把它搜完!! • 物品數量 N=40 • 每種物品都有可能選取或是不選 • 恭喜你! 我們獲得了 O(2^40) 的時間複雜度!!!!! • 說不定我們可以好好的剪枝, 讓他跑得比較快一點? • TOJ上有, 你可以試試看……

  7. 該怎麼辦 • 有沒有可能有很棒的演算法呢…? • 例如 O(n^3) 或 O(n^4) 之類的? • 且慢!! 這是NP-Complete問題 • 為什麼是 NP-Complete~~~by 興國哥 • 總而言之, 現代人類認為這類的問題不太可能有很棒的解法 • 至少至少需要對於問題規模 n 成指數等級的時間複雜度 • 例如 O(2^n), O(3^n), ……

  8. 那麼… • 沒有太好的方法, 但難道真的不可能有更好一點點的解法了嗎? • 想一想:N大約為多少的時候, 我們可以輕鬆做出來呢? • N=10, 執行時間約10us • N=20, 執行時間約10ms • N=30, 執行時間約10s…勉強可以忍受 • N=40, ……………………… 10000s 天荒地老的三小時 • 換句話說, 只要有機會讓 N再小一點點 我們就有機會可以做!

  9. 之前的經驗 • 如果我們可以把問題分割成”規模相近”,的兩部分 • 而且可以用”好方法”把問題的兩個部分合併 • 那就有機會藉此減少時間複雜度! • 40個物品…任意分割成兩個大小類似的集合

  10. 左半邊可以組合出什麼組合呢 • {}、{3}、{7}、{12}、{3,7}、{3,12}、{7,12}、{3,7,12} • 總和分別為 {0,3,7,12,10,15,19,33} • 那麼, 右半邊呢 • {}、{5}、{1}、{4}、{5,1}、{1,4}、{5,4}、{5,1,4} • 總和分別為 {0,5,1,4,6,5,9,10}

  11. 如果我們想要湊出總和為 M 的總和 • 左半邊總和分別為 {0,3,7,12,10,15,19,33} • 右半邊總和分別為 {0,5,1,4,6,5,9,10} • 如果左邊所取的物品, 價值總和為 i • 右邊就必須拿到 M-i

  12. 流程: • 分別考慮左邊的所有物品能湊出的價值 • 右邊也一樣 • 需要多少時間? 分別需要 O(2^(N/2)) • 我們總共想要價值M • 瓊舉左邊集合的所有價值 i • 如果在右邊找的到 M-i, 那就成功了! • 如果右邊找不到M-i呢? 那就表示不存在”從左邊集合取出總和i, 右邊集合取出總和 M-i的方法”

  13. 如何從右邊的集合中尋找 M-i呢? • 先排序! 再搜尋 • O(log(2^(N/2))) • O(2^20 * log2 (2^20)) • 大約 10ms * 20 = 200ms~! • 可以接受! • 雖然不太爽, 但至少比原先的 O(2^40) 快多了

  14. 進一步探討 • 要如何找出一組可行的方案? • Struct XDDD { • long long sum; //儲存總和 • bool used[N]; //紀錄每個元素是否用到 • } • 位元運算終於派上用場了!

  15. Struct XDDD {//照sum排序 • long long sum; //儲存總和 • int used; //紀錄每個元素是否用到, 用一個int就過了 • } • 因為搜索的問題本身規模不會太大, • 位元運算是方便好寫的好選擇! • 很快, 很節省空間

  16. 還記得這張圖嗎~~ • 搜尋的順序

  17. 木棒問題 • 許多等長的木棒 • 隨機切成很多份 • 例如 長度=10 共有三根 • 10 = 2+5+3 • = 5+4+1 • = 3+4+3 • 給你切斷後的長度 • 1,2,3,3,3,4,4,5,5 • 請求出原始木棒可能的最小長度

  18. 加速每個步驟的時間 • 讓錯誤盡早發生, 上下界如果已經沒機會了, 就別再執著了 • 盡量不考慮重複的方案 (*因為會浪費時間) • 搜尋的順序(*), 方案替代(*) • 跳過重複的可能(*)

  19. 小試身手~~!!

More Related