演算法導論(mit 6.006 第19講)
1: 定義子問題
計算子問題的數量2:猜測(嘗試所有可能的方式,獲取最好的)
計算選擇的數量3: 關聯所有的子問題
計算單個子問題所需要處理的時間4: 重用子問題結果並記下新的結果,或者使用dp的bottom-up方式(需要注意沒有環)
計算總耗時5: 解決原有的問題
對結果進行組合等等會劃掉部分額外的時間總的來說就是:嘗試所有可能的子問題的結果,將最好的可能子結果儲存下來,然後重複利用已經解決的子問題,遞迴去解決所有的問題(猜測+記憶+遞迴)
它消耗的時間為: 子問題的數量 * 每個子問題處理所需要時間
fib(n):
if n<=2:f=1;
else: f= fib(n-1)+fib(n-2);
return f;
這種方式的執行時間為 $\theta$($2^$),空間為o(1)
t(n)=t(n-1)+t(n-2)+o(1) $\geq$ 2t(n-2)= $\theta$($2^$)
fib(n):
memo={}
if n in memo:return memo[n];
if n<=2:f=1;
else f=fib(n-1)+fib(n-2);
memo[n]=f;
return f;
這種方式的執行時間為$\theta(n)$,空間為o(n)
memo的存在使得實際產生呼叫的只有 fib(1) .... fib(n),共n次,區域的直接從memo中獲取,使用常量的時間
fib(n):
fib={}
for i in range(1,n+1):
if i<=2: f=1
else: f=fib[i-1]+fib[i-2]
fib[i]=f
return fib[n]
這種方式的執行時間為$\theta(n)$,空間可以只用o(1)
它可以看做是一種拓撲排序(針對dag),對於使用空間其實只需要記住前兩個即可要求s到t的最短路徑,那麼必定會經過與t相鄰的一條邊,如圖示的u,那麼最短路徑$\delta(s,t)$=$min_(\delta(s,u)+w(u,t))$
$\delta(s,u)$就是需要遞迴呼叫處理的部分對於dag:$\delta(s,t)$每個子問題的處理時間為 indegree(t)+o(1)
indegree(t):入度數也就是類似(u,t)邊的數量,需要去遍歷所有t的入邊總共的執行時間為o(1):判斷是不是有入邊
要求s到v的最短路徑 $\delta(s,v)$,首選需要去求 $\delta(s,a)$,然後是$\delta(s,b)$,到b節點有兩條路徑:$\delta(s,s)$和$\delta(s,v)$,此時去memo中查$\delta(s,v)$是不存在的,又會這回查詢,導致了乙個死迴圈
方式是去環,將原來的圖一層一層的展開。
假設從s到v需要的路徑為k步,那麼可以得到 $\delta_k(s,v)$=$min_(\delta_(s,b)+w(b,v))$,當k遞減到0的時候,其實也就是從s到s本身
所需要的展開層數為:|v|-1
對於求最短路徑來講,最長不能超過|v|-1,否則就是成環,會造成迴圈的情況(從0開始的計數),這就是為什麼bellman-ford的外層迴圈是 |v|-1每層的節點數為所有的節點。那麼總共的節點數為|v'|=|v|(|v|-1)+1=o($v^2$),邊數是|e'|=|e|(|v|-2)+1=o(ve)。轉換後的圖是dag圖,那麼實際上的時間為o(v'+e')=o(ve)。這也就是
從動態規劃的角度去看bellman-ford演算法
節點的數目是1個源點,邊的數目是每多一層實際上就多了加了一遍所有的邊。例子
斐波那契數列
最短路徑
1:定義子問題
$f_k$ 其中$1\leq k \leq n$
$\delta_k(s,v)$ 其中 $v\in v, 0\leq k < v $
子問題數量
n$v^2$
2:猜測
什麼都沒做,完全是定義
節點v的入邊(如果存在的話)
選擇的數量
1v的入邊數+1
3:關聯所有的子問題
$f_k=f_+f_$
$\delta_k(s,v) =min_(\delta_(s,u)+w(u,v))$
子問題的時間
$\theta(1)$
$\theta(1+入度(v))$
4:重用子問題結果並記下新的結果
for k=1,..,n
for k=0,1,..,v-1
總共耗時
$\theta(n)$
$\theta(ve)+\theta(v^2)$ (如果存在入度,就有後項)
5:解決原有的問題
$f_n$
$\delta_(s,v) ,v \in v$
額外耗時
$\theta(1)$
$\theta(v)$(bellman-ford最後的遍歷)
架構之路 從管理者的角度看問題
同步發布在知乎,也不知道在裡這算不算水文,能不能上首頁。但園子裡還有一千多粉絲,我主要是想通知下面這件事 這個系列寫得很坎坷啊!實在是沒時間。本來是計畫一周一篇的,這都多少周了?野生程式設計師 優先招聘 裡,這大話都說出去了,打臉不能打得太狠啊。有好些同學想跟我混,但我目前確實沒這個實力 當然,也不...
架構之路 從管理者的角度看問題
同步發布在知乎,也不知道在裡這算不算水文,能不能上首頁。但園子裡還有一千多粉絲,我主要是想通知下面這件事 這個系列寫得很坎坷啊!實在是沒時間。本來是計畫一周一篇的,這都多少周了?野生程式設計師 優先招聘 裡,這大話都說出去了,打臉不能打得太狠啊。有好些同學想跟我混,但我目前確實沒這個實力 當然,也不...
動態規劃 如何求解金礦問題
漫畫演算法 小灰的演算法之旅 5.11 假設現在有5座金礦,每座金礦的 儲存量不同,需要參入挖掘的工人人數也不同。要求 參入挖礦的工人的總數是10.每座金礦要麼全挖,要麼不挖,不能派出一半人挖取一般 要求用程式求出,要想得到盡可能多的 應該選取那幾座金礦?金礦內容 400,500,200,300,3...