1. 程式人生 > 其它 >動態規劃+廣度優先搜尋,實戰經驗總結

動態規劃+廣度優先搜尋,實戰經驗總結

在實際生產中,遇到一個技術問題,在整個攻堅的過程中,回看的時候,才發現自己寫了一個廣度優先搜尋的動態規劃。這裡把過程記錄下來,原始碼是貼不出來了,但是可以把解決的思路記錄下來。

需求:寫一個查詢介面,去資料庫查表,把所有查詢出來的資料,整合到一個數據結構中,返回給前端展示。這個介面查詢的資料,是樹形結構,樹有6層,每個層級之間的節點,不會互相呼叫,都是上一層呼叫下一層,這樣的關係。有一個鮮明的特點是,第一層,假設是A層,第二層,假設是B層,那麼A1可以呼叫B1、B2、B3;A2可以呼叫B1、B3、B4,以此類推,一直到最後一層,都是這樣的關係,下一層的同一個節點,會被上一層,重複多次呼叫。記住這裡重複

的問題。

遇到的問題:

一開始的時候,我是按照慣性,依次迴圈遍歷每個層級,在每一層迴圈中,把遍歷到的每個節點都去資料庫查一遍。整個資料庫的查詢,耗時長達107s。

迴圈的層級太多,是一個問題;大量的呈指數級上升的重複查詢,也是一個問題。

解決辦法:

深度優先-改廣度優先

每一層級的查詢,程式碼相似度都很高,如果按照慣性,肯定是寫深度優先查詢,這樣邏輯是順暢的,但是有一個問題,深度優先搜尋,都是迴圈巢狀迴圈,一層一層嵌進去,這樣程式碼無法複用,所以為了程式碼塊的複用,我把深度優先改成了廣度優先搜尋。把當前的迴圈層級,在整個迴圈體外面,設一個變數dic_(資料型別儲存介質),把當前迴圈的每個元素,進行去重,存入dic_,待迴圈結束,拿著dic_,開始下一層的迴圈,不斷複用即可。這樣,就沒有巢狀的多層迴圈了,時間複雜度O(5*n),廣度優先搜尋,跟深度優先比較起來,時間複雜度也降下來。同時解決了程式碼複用以及時間複雜度降低兩個維度的問題。

動態規劃

在整個迴圈體中,設定中間儲存介質,把所有遍歷過的節點都存進去,在迴圈的時候,增加一層攔截判斷,如果該節點,已經被遍歷過,就continue,繼續遍歷下一個節點資料,這樣,就是動態規劃的實現。在迴圈中,設定中間儲存單元,這是動態規劃的本質。這樣就避免了大量重複的資料庫查詢,效率瞬間提升十幾倍。到這一步做完,整個資料庫查詢的耗時從107s,降到8.24s。

到此,動態規劃的厲害,可見一斑。果然,名不虛傳,經此一遭,深刻認識到了演算法的強大。還是要好好學習啊。