flow演算法
① 大數據最常用的演算法有哪些
奧地利符號計算研究所(Research Institute for Symbolic Computation,簡稱RISC)的Christoph Koutschan博士在自己的頁面上發布了一篇文章,提到他做了一個調查,參與者大多數是計算機科學家,他請這些科學家投票選出最重要的演算法,以下是這次調查的結果,按照英文名稱字母順序排序。
大數據等最核心的關鍵技術:32個演算法
1、A* 搜索演算法——圖形搜索演算法,從給定起點到給定終點計算出路徑。其中使用了一種啟發式的估算,為每個節點估算通過該節點的最佳路徑,並以之為各個地點排定次序。演算法以得到的次序訪問這些節點。因此,A*搜索演算法是最佳優先搜索的範例。
2、集束搜索(又名定向搜索,Beam Search)——最佳優先搜索演算法的優化。使用啟發式函數評估它檢查的每個節點的能力。不過,集束搜索只能在每個深度中發現最前面的m個最符合條件的節點,m是固定數字——集束的寬度。
3、二分查找(Binary Search)——在線性數組中找特定值的演算法,每個步驟去掉一半不符合要求的數據。
4、分支界定演算法(Branch and Bound)——在多種最優化問題中尋找特定最優化解決方案的演算法,特別是針對離散、組合的最優化。
5、Buchberger演算法——一種數學演算法,可將其視為針對單變數最大公約數求解的歐幾里得演算法和線性系統中高斯消元法的泛化。
6、數據壓縮——採取特定編碼方案,使用更少的位元組數(或是其他信息承載單元)對信息編碼的過程,又叫來源編碼。
7、Diffie-Hellman密鑰交換演算法——一種加密協議,允許雙方在事先不了解對方的情況下,在不安全的通信信道中,共同建立共享密鑰。該密鑰以後可與一個對稱密碼一起,加密後續通訊。
8、Dijkstra演算法——針對沒有負值權重邊的有向圖,計算其中的單一起點最短演算法。
9、離散微分演算法(Discrete differentiation)。
10、動態規劃演算法(Dynamic Programming)——展示互相覆蓋的子問題和最優子架構演算法
11、歐幾里得演算法(Euclidean algorithm)——計算兩個整數的最大公約數。最古老的演算法之一,出現在公元前300前歐幾里得的《幾何原本》。
12、期望-最大演算法(Expectation-maximization algorithm,又名EM-Training)——在統計計算中,期望-最大演算法在概率模型中尋找可能性最大的參數估算值,其中模型依賴於未發現的潛在變數。EM在兩個步驟中交替計算,第一步是計算期望,利用對隱藏變數的現有估計值,計算其最大可能估計值;第二步是最大化,最大化在第一步上求得的最大可能值來計算參數的值。
13、快速傅里葉變換(Fast Fourier transform,FFT)——計算離散的傅里葉變換(DFT)及其反轉。該演算法應用范圍很廣,從數字信號處理到解決偏微分方程,到快速計算大整數乘積。
14、梯度下降(Gradient descent)——一種數學上的最優化演算法。
15、哈希演算法(Hashing)。
16、堆排序(Heaps)。
17、Karatsuba乘法——需要完成上千位整數的乘法的系統中使用,比如計算機代數系統和大數程序庫,如果使用長乘法,速度太慢。該演算法發現於1962年。
18、LLL演算法(Lenstra-Lenstra-Lovasz lattice rection)——以格規約(lattice)基數為輸入,輸出短正交向量基數。LLL演算法在以下公共密鑰加密方法中有大量使用:背包加密系統(knapsack)、有特定設置的RSA加密等等。
19、最大流量演算法(Maximum flow)——該演算法試圖從一個流量網路中找到最大的流。它優勢被定義為找到這樣一個流的值。最大流問題可以看作更復雜的網路流問題的特定情況。最大流與網路中的界面有關,這就是最大流-最小截定理(Max-flow min-cut theorem)。Ford-Fulkerson 能找到一個流網路中的最大流。
20、合並排序(Merge Sort)。
21、牛頓法(Newton』s method)——求非線性方程(組)零點的一種重要的迭代法。
22、Q-learning學習演算法——這是一種通過學習動作值函數(action-value function)完成的強化學習演算法,函數採取在給定狀態的給定動作,並計算出期望的效用價值,在此後遵循固定的策略。Q-leanring的優勢是,在不需要環境模型的情況下,可以對比可採納行動的期望效用。
23、兩次篩法(Quadratic Sieve)——現代整數因子分解演算法,在實踐中,是目前已知第二快的此類演算法(僅次於數域篩法Number Field Sieve)。對於110位以下的十位整數,它仍是最快的,而且都認為它比數域篩法更簡單。
24、RANSAC——是「RANdom SAmple Consensus」的縮寫。該演算法根據一系列觀察得到的數據,數據中包含異常值,估算一個數學模型的參數值。其基本假設是:數據包含非異化值,也就是能夠通過某些模型參數解釋的值,異化值就是那些不符合模型的數據點。
25、RSA——公鑰加密演算法。首個適用於以簽名作為加密的演算法。RSA在電商行業中仍大規模使用,大家也相信它有足夠安全長度的公鑰。
26、Sch?nhage-Strassen演算法——在數學中,Sch?nhage-Strassen演算法是用來完成大整數的乘法的快速漸近演算法。其演算法復雜度為:O(N log(N) log(log(N))),該演算法使用了傅里葉變換。
27、單純型演算法(Simplex Algorithm)——在數學的優化理論中,單純型演算法是常用的技術,用來找到線性規劃問題的數值解。線性規劃問題包括在一組實變數上的一系列線性不等式組,以及一個等待最大化(或最小化)的固定線性函數。
28、奇異值分解(Singular value decomposition,簡稱SVD)——在線性代數中,SVD是重要的實數或復數矩陣的分解方法,在信號處理和統計中有多種應用,比如計算矩陣的偽逆矩陣(以求解最小二乘法問題)、解決超定線性系統(overdetermined linear systems)、矩陣逼近、數值天氣預報等等。
29、求解線性方程組(Solving a system of linear equations)——線性方程組是數學中最古老的問題,它們有很多應用,比如在數字信號處理、線性規劃中的估算和預測、數值分析中的非線性問題逼近等等。求解線性方程組,可以使用高斯—約當消去法(Gauss-Jordan elimination),或是柯列斯基分解( Cholesky decomposition)。
30、Strukturtensor演算法——應用於模式識別領域,為所有像素找出一種計算方法,看看該像素是否處於同質區域( homogenous region),看看它是否屬於邊緣,還是是一個頂點。
31、合並查找演算法(Union-find)——給定一組元素,該演算法常常用來把這些元素分為多個分離的、彼此不重合的組。不相交集(disjoint-set)的數據結構可以跟蹤這樣的切分方法。合並查找演算法可以在此種數據結構上完成兩個有用的操作:
查找:判斷某特定元素屬於哪個組。
合並:聯合或合並兩個組為一個組。
32、維特比演算法(Viterbi algorithm)——尋找隱藏狀態最有可能序列的動態規劃演算法,這種序列被稱為維特比路徑,其結果是一系列可以觀察到的事件,特別是在隱藏的Markov模型中。
以上就是Christoph博士對於最重要的演算法的調查結果。你們熟悉哪些演算法?又有哪些演算法是你們經常使用的?
② c/c++ 最大流演算法ford-fulkerson
你的問題是用C/C++寫最大流演算法ford-fulkerson演算法。頂點就是節點。
void maximum_flow(int n, int s, int t, int *capacity, int *flow)
可以參考:演算法模板-最大流(Ford-fulkerson演算法)
③ 路由演算法主要有哪幾種
靜態路由演算法主要有:
洪泛法(Flooding)
隨機走動法(Random Walk)
最短路徑法(Shortest Path,SP)
基於流量的路由演算法(Flow-based Routing,FR)</ol>動態路由演算法主要有:
距離矢量演算法(RIP)
鏈路狀態演算法(OSPF)
平衡混合演算法(EIGRP)</ol>
④ 高分:網路流問題
一、引言
網路流演算法是一種高效實用的演算法,相對於其它圖論演算法來說,它的模型更加復雜,編程復雜度也更高。但是它綜合了圖論中的其它一些演算法(如最短路徑、寬度搜索演算法),因而適用范圍也更廣,經常能夠很好地解決一些搜索與動態規劃無法解決的非np問題。
網路流在具體問題中的應用,最具挑戰性的部分是模型的構造,它沒用現成的模式可以套用,需要我們對各種網路流的性質了如指掌(比如點有容量、容量有上下限、多重邊等等),根據具體的問題發揮我們的創造性。一道問題經常可以建立多種模型,不同的模型對問題的解決效率的影響也是不同的,本文通過實例探討如何確定適當的模型,提高網路流演算法的效率。
二、網路流演算法時間效率
當我們確定問題可以使用最大流演算法求解後,就根據常用的ford-fulkerson標號法求解;而最小(大)費用最大流問題也可用類似標號法的對偶演算法解題。ford-fulkerson標號法的運行時間為o(ve2),對偶法求最小費用流的運行時間大約為o(v3e2)。
顯然,影響網路流演算法的時間效率的因素主要是網路中頂點的數目與邊的數目。這二個因素之間不是相互獨立的,而是相互聯系,矛盾而統一的。在構造網路模型中,有時,實現了某個因素的優化,另外一個因素也隨之得到了優化;有時,實現某個因素的優化卻要以增大另一因素為代價。因此,我們在具體問題的解決中,要堅持"全局觀",實現二者的平衡。
三、模型的優化與選擇
(一)減少模型的頂點數與邊數,優化模型
如果能根據問題的一些特殊性質,減少網路模型中的頂點的數目和邊的數目,則可以大大提高演算法的效率。
例1:最少皇後控制
在國際象棋中,皇後能向八個方向攻擊(如圖1(a)所示,圖中黑點格子為皇後的位置,標有k的格子為皇後可攻擊到的格子)。現在給定一個m*n(n、m均不大於於50)的棋盤,棋盤上某些格子有障礙。每個皇後被放置在無障礙的格子中,它就控制了這個格子,除此,它可以從它能攻擊到的最多8個格子中選一個格子來控制,如圖1(b)所示,標號為1的格子被一個皇後所控制。
請你編一程序,計算出至少有多少個皇後才能完全控制整個棋盤。
圖1(a) 圖1(b)
輸入格式:
輸入文件的第一行有兩個整數m和n,表示棋盤的行數與列數。接下來m行n列為一個字元矩陣,用''.''號表示空白的格子,''x''表示有障礙的格子。
輸出格式:
輸出文件的第一行僅有一個數s,表示需要皇後的數目。
sample input
3 4
x...
x.x.
.x..
sample ouput
5
問題分析]
如果本問題用簡單的搜索來做,由於題目給的棋盤很大,搜索演算法很難在短時間內出解。由於一個皇後在棋盤最多隻能控制兩個格子,因此最少需要的皇後數目的下界為[n*m/2]。要使得皇後數目最少,必定是盡量多的皇後控制兩個格子。如果我們在每兩個能相互攻擊到的格子之間加上一條有向弧,則問題很類似於二分圖的最大匹配問題。
[模型一]
1. 將每個非障礙的格子按行優先編號(0~m*n-1)。
2. 將上述的每個格子i折成兩個格子i''和i'''',作為網路模型中的頂點。
3. 若格子i可以攻擊到格子j且i<j,則在模型中頂點i''到j''''之間加上一條有向弧,容量為1。
4. 增加一個源點s,從s點向所有頂點i''添上一條弧;增加一個匯點t,從所有頂點j''''到t添上一條弧,容量均為1。
圖1(b)所示的棋盤,對應的模型為:
圖2
顯然,任一解對應於以上模型的一個最大匹配。且最大匹配中,匹配數必定是偶數。因此至少需要的馬匹數為m*n-障礙數-最大匹配數/2。
[模型二]
如果我們將棋盤塗成黑白相間的格子,則某皇後控制的兩個格子一定是一個是黑格,另一個是白格(如圖3),不妨設這兩個格子中皇後在白格子上。於是,我們將n*m個格子分成兩部分白格與黑格。因此我們可以將模型一優化為:
圖3
1.將棋盤中的所有格子分成兩個部分,對所有的格子進行編號,每個白格與它能攻擊到的黑格之間(障礙除外)添上一條從白格到黑格的弧,構成一個二分圖。
2.增加一個源點s,從s點向所有非障礙的白格添上一條弧;增加一個匯點t,從所有非障礙的黑格到t添上一條弧。
3.設置所有的弧的流量為1。
圖1(b)所示的棋盤,對應的模型為:
圖4
[兩種模型的比較]
顯然,模型二的頂點數與邊數大致是模型一的一半。下面是在bp環境下兩種模型的時間效率比較(p166/32m):
模型一 模型二
可擴展性 不易列印出一種解 容易列印出一種解
模型二正是根據問題的特殊性(即馬的走法),將網格中的格點分成白與黑兩類,且規定馬只能從白格跳到黑格,從而避免將每個格點折分成兩個點,減少模型的頂點數,同時也大大減少了邊的數目。達到了很好的優化效果。
(二)綜合各種模型的優點,智能選擇模型
有時,同一問題的各種模型各有特色,各有利弊。這種情況下,我們就要綜合考慮各種模型的優缺點,根據測試數據智能地選擇問題的模型。
例2火星探測器(ioi97)
有一個登陸艙(pod),里邊裝有許多障礙物探測車(mev),將在火星表面著陸。著陸後,探測車離開登陸艙向相距不遠的先期到達的傳送器(transmitter)移動,mev一邊移動,一邊採集岩石(rock)標品,岩石由第一個訪問到它的mev所採集,每塊岩石只能被採集一次。但是這之後,其他mev可以從該處通過。探測車mev不能通過有障礙的地面。
本題限定探測車mev只能沿著格子向南或向東從登陸處向傳送器transmitter移動,允許多個探測車mev在同一時間占據同一位置。
任務:計算出所有探測車的移動途徑,使其送到傳送器的岩石標本的數量最多,且使得所有的探測車都必須到達傳送器。
輸入:
火星表面上的登陸艙pod和傳送器之間的位置用網路p和q表示,登陸艙pod的位置為(1,1)點,傳送器的位置在(p,q)點。
火星上的不同表面用三種不同的數字元號來表示:
0代表平坦無障礙
1代表障礙
2代表石塊。
輸入文件的組成如下:
numberofvehicles
p
q
(x1y1)(x2y1)(x3,y1)…(xp-1y1)(xpy1)
(x1y2)(x2y2)(x3,y2)…(xp-1y1)(xpy2)
(x1y3)(x2y3)(x3,y3)…(xp-1y3)(xpy3)
…
(x1yq-1)(x2yq-1)(x3,yq-1)…(xp-1yq-1)(xpyq-1)
(x1yq)(x2yq)(x3,yq)…(xp-1yq)(xpyq)
p和q是網路的大小;numberofvehicles是小於1000的整數,表示由登陸艙pod所開出的探測車的個數。共有q行數據,每行表示火星表面的一組數據,p和q都不超過128。
[模型一]
很自然我們以登陸艙的位置為源點,傳送器的位置為匯點。同時某塊岩石由第一個訪問到它的mev所採集,每塊岩石只能被採集一次。但是這之後,其他mev可以從該處通過,且允許多個探測車mev在同一時間占據同一位置。因此我們將地圖中的每個點分成兩個點,即(x,y)à(x,y,0)和(x,y,1)。具體的描述一個火星地圖的網路模型構造如下:
1. 將網格中的每個非障礙點分成(x,y)兩個點(x,y,0)和(x,y,1),其中源點s = v(1, 1, 0),匯點t = v(maxx, maxy, 1)。
2. 在以上頂點中添加以下三種類型的邊e1,e2,e3,相應地容量和費用分別記為c1、c2、c3以及w1、w2、w3:
u e1 = v(x, y, 0) -> v(x, y, 1),c1 = maxint,w1 = 0。
u e2 = v(x, y, 0) -> v(x, y, 1),c2 = 1,w2 = -1(這里要求(x, y)必須是礦石)
u e3 = v(x, y, 1) -> v(x'', y'', 0),c3 = maxint,w3 = 0.
其中x''=x+1 y''=y 或x''=x y''=y+1,1 <= x'' <= maxx,1 <= y'' <= maxy,且(x'' y'')非障礙。
從以上模型中可以看出,在構造的過程中,將地圖上的一個點"拆"成了網路的兩個節點。添加e1型邊使得每個點可以被多次訪問,而添加e2型邊使得某點上的礦石對於這個網路,從s到t的一條路徑可以看作是一輛探測車的行動路線。路徑費用就是探測車搜集到的礦石的數目。對於網路g求流量為numberofvehicles的固定最小費用流,可以得到問題的解。
[模型二]
事實上,如果我們只考慮這numberofvehicles輛車中每輛車分別依次裝上哪些礦石。則每輛車經過的礦石就是一條流,因此我們以網格中的礦石為網路的頂點建立以下的網路流模型。
1. 將網格中的每個起點(網格左上角)能到達,且能從它能到達終點(右下角)的礦石 (x,y)點分成左點(x,y,0)和右點(x,y,1)兩個點,並添加源點s和匯點t。
2. 在以上頂點中添加以下五種類型的邊e1,e2,e3,相應地容量和費用分別記為c1、c2、c3以及w1、w2、w3:
u e1 = v(x, y, 0) -> v(x, y, 1),c1 = 1,w1 = -1。
u e2 = v(x, y, 1) -> v(x'', y'', 0),c2 = 1,w2 = 0(礦石點(x, y)可到達礦石點(x'',y''))。
u e3 = s -> v(x, y, 0),c3 = 1,w3 = 0。
u e4 = v(x, y, 1)->t,c4 = 1,w4 = 0。
u e5=s->t,c5=maxint,w5=0。
由於每個石塊被折成兩個點,且容量為1,就保證了每個石塊只被取走一次,同時取走一塊石塊就得到-1的費用。因此對以上模型,我們求流量為numberofvehicles的最小費用流,就可得到解。
[兩種模型的比較]
1.模型一以網格為頂點,模型二以礦石為頂點,因此在頂點個數上模型二明顯優於模型一,對於一些礦石比較稀疏,而網格又比較大的數據,模型二的效率要比模型一來得高。且只要礦石的個數不超過一定數目,模型二可以處理p,q很大的數據,而模型一卻不行。
2.模型一中邊的數目最多為3*p*q,而模型二中邊的數目最壞情況下大約為p*q*(p+1)*(q+1)/4-p*q。因此在這個問題中,若對於一些礦石比較密集且網格又比較大的數據,模型二的邊數將大大超過模型一,從而使得時間效率大大低於模型一。
下面是網格中都是礦石的情況比較(piii700/128m ,bp7.0保護模式):
numberofvehicles=10 模型一 模型二
通過以上數據,可知對於p,q不超過60的情況,模型一都能在10秒內出解。而模型二則對於p、q=30的最壞情況下速度就很慢了,且p、q超過30後就出現內存溢出情況,而無法解決。
因此,對於本題,以上兩種模型各有利弊,我們可根據測試數據中礦石稀疏程度來決定建立什麼樣的模型。若礦石比較稀疏,則可以考慮用建立如模型二的網路模型;若礦石比較密集則建立模型一所示網路模型。然後,再應用求最小費用最大流演算法求解。對於p,q>60,且礦石比較多情況下,兩種模型的網路流演算法都無法求解。在實際的應用中問題經常都只要求近似解,此時還可用綜合一些其它演算法來求解。
四、結束語
綜上所述,網路流演算法中模型的優化是網路流演算法提高效率的根本。我們要根據實際問題,從減少頂點及邊的角度綜合考慮如何對模型進行優化,選擇適當的模型,以提高演算法的效率。對於有些題目,解題的各種模型各有優劣時,還可通過程序自動分析測試數據,以決定何種情況下採用何種模型,充分發揮各種模型的優點,以達到優化程序效率的目的。
⑤ 程序員必須掌握哪些演算法
集束搜索(又名定向搜索,BeamSearch)——最佳優先搜索演算法的優化。
A*搜尋演算法——圖形搜索演算法,是最佳優先搜索的範例,從給定起點到給定終點計算出路徑。
數據壓縮——採取特定編碼方案,使用更少的位元組數(或是其他信息承載單元)對信息編碼的過程,又叫來源編碼。
離散微分演算法(Discretedifferentiation)
哈希演算法(Hashing)
堆排序(Heaps)
合並排序(MergeSort)
梯度下降(Gradientdescent)——一種數學上的最優化演算法。
牛頓法(Newton'smethod)——求非線性方程(組)零點的一種重要的迭代法。
歐幾里得演算法(Euclideanalgorithm)——計算兩個整數的最大公約數。最古老的演算法之一,出現在公元前300前歐幾里得的《幾何原本》。
Buchberger演算法——一種數學演算法,可將其視為針對單變數最大公約數求解的歐幾里得演算法和線性系統中高斯消元法的泛化。
動態規劃演算法(DynamicProgramming)——展示互相覆蓋的子問題和最優子架構演算法。
Diffie-Hellman密鑰交換演算法——一種加密協議,允許雙方在事先不了解對方的情況下,在不安全的通信信道中,共同建立共享密鑰。該密鑰以後可與一個對稱密碼一起,加密後續通訊。
Dijkstra演算法——針對沒有負值權重邊的有向圖,計算其中的單一起點最短演算法。
二分查找(BinarySearch)——在線性數組中找特定值的演算法,每個步驟去掉一半不符合要求的數據。
合並查找演算法(Union-find)——給定一組元素,該演算法常常用來把這些元素分為多個分離的、彼此不重合的組。
期望-最大演算法(Expectation-maximizationalgorithm,又名EM-Training)——在統計計算中,期望-最大演算法在概率模型中尋找可能性最大的參數估算值,其中模型依賴於未發現的潛在變數。
快速傅里葉變換(FastFouriertransform,FFT)——計算離散的傅里葉變換(DFT)及其反轉。
最大流量演算法(Maximumflow)——該演算法試圖從一個流量網路中找到最大的流。
LLL演算法(Lenstra-Lenstra-Lovaszlatticerection)——以格規約(lattice)基數為輸入,輸出短正交向量基數。
兩次篩法(QuadraticSieve)——現代整數因子分解演算法,在實踐中,是目前已知第二快的此類演算法(僅次於數域篩法NumberFieldSieve)。
RANSAC——是「RANdomSAmpleConsensus」的縮寫。該演算法根據一系列觀察得到的數據,數據中包含異常值,估算一個數學模型的參數值。
求解線性方程組()——線性方程組是數學中最古老的問題,它們有很多應用,比如在數字信號處理、線性規劃中的估算和預測、數值分析中的非線性問題逼近等等。求解線性方程組,可以使用高斯—約當消去法(Gauss-Jordanelimination),或是柯列斯基分解(Choleskydecomposition)。
Q-learning學習演算法——這是一種通過學習動作值函數(action-valuefunction)完成的強化學習演算法,函數採取在給定狀態的給定動作,並計算出期望的效用價值,在此後遵循固定的策略。
Schönhage-Strassen演算法——在數學中,Schönhage-Strassen演算法是用來完成大整數的乘法的快速漸近演算法。其演算法復雜度為:O(Nlog(N)log(log(N))),該演算法使用了傅里葉變換。
RSA——公鑰加密演算法。首個適用於以簽名作為加密的演算法。RSA在電商行業中仍大規模使用,大家也相信它有足夠安全長度的公鑰。
Strukturtensor演算法——應用於模式識別領域,為所有像素找出一種計算方法,看看該像素是否處於同質區域(homogenousregion),看看它是否屬於邊緣,還是是一個頂點。
單純型演算法(SimplexAlgorithm)——在數學的優化理論中,單純型演算法是常用的技術,用來找到線性規劃問題的數值解。
奇異值分解(Singularvaluedecomposition,簡稱SVD)——在線性代數中,SVD是重要的實數或復數矩陣的分解方法,在信號處理和統計中有多種應用,比如計算矩陣的偽逆矩陣(以求解最小二乘法問題)、解決超定線性系統(overdeterminedlinearsystems)、矩陣逼近、數值天氣預報等等。
維特比演算法(Viterbialgorithm)——尋找隱藏狀態最有可能序列的動態規劃演算法,這種序列被稱為維特比路徑,其結果是一系列可以觀察到的事件,特別是在隱藏的Markov模型中。
⑥ 網路流的最大流演算法
1、augment path,直譯為「增廣路徑」,其思想大致如下:
原有網路為G,設有一輔助圖G',其定義為V(G') = V(G),E(G')初始值(也就是容量)與E(G)相同。每次操作時從Source點搜索出一條到Sink點的路徑,然後將該路徑上所有的容量減去該路徑上容量的最小值,然後對路徑上每一條邊<u,v>添加或擴大反方向的容量,大小就是剛才減去的容量。一直到沒有路為止。此時輔助圖上的正向流就是最大流。
我們很容易覺得這個演算法會陷入死循環,但事實上不是這樣的。我們只需要注意到每次網路中由Source到Sink的流都增加了,若容量都是整數,則這個演算法必然會結束。
尋找通路的時候可以用DFS,BFS最短路等演算法。就這兩者來說,BFS要比DFS快得多,但是編碼量也會相應上一個數量級。
增廣路方法可以解決最大流問題,然而它有一個不可避免的缺陷,就是在極端情況下每次只能將流擴大1(假設容量、流為整數),這樣會造成性能上的很大問題,解決這個問題有一個復雜得多的演算法,就是預推進演算法。
2、push label,直譯為「預推進」演算法。
3、壓入與重標記(Push-Relabel)演算法
除了用各種方法在剩餘網路中不斷找增廣路(augmenting)的Ford-Fulkerson系的演算法外,還有一種求最大流的演算法被稱為壓入與重標記(Push-Relabel)演算法。它的基本操作有:壓入,作用於一條邊,將邊的始點的預流盡可能多的壓向終點;重標記,作用於一個點,將它的高度(也就是label)設為所有鄰接點的高度的最小值加一。Push-Relabel系的演算法普遍要比Ford-Fulkerson系的演算法快,但是缺點是相對難以理解。
Relabel-to-Front使用一個鏈表保存溢出頂點,用Discharge操作不斷使溢出頂點不再溢出。Discharge的操作過程是:若找不到可被壓入的臨邊,則重標記,否則對臨邊壓入,直至點不再溢出。演算法的主過程是:首先將源點出發的所有邊充滿,然後將除源和匯外的所有頂點保存在一個鏈表裡,從鏈表頭開始進行Discharge,如果完成後頂點的高度有所增加,則將這個頂點置於鏈表的頭部,對下一個頂點開始Discharge。
Relabel-to-Front演算法的時間復雜度是O(V^3),還有一個叫Highest Label Preflow Push的演算法復雜度據說是O(V^2*E^0.5)。我研究了一下HLPP,感覺它和Relabel-to-Front本質上沒有區別,因為Relabel-to-Front每次前移的都是高度最高的頂點,所以也相當於每次選擇最高的標號進行更新。還有一個感覺也會很好實現的演算法是使用隊列維護溢出頂點,每次對pop出來的頂點discharge,出現了新的溢出頂點時入隊。
Push-Relabel類的演算法有一個名為gap heuristic的優化,就是當存在一個整數0<k<V,沒有任何頂點滿足h[v]=k時,對所有h[v]>k的頂點v做更新,若它小於V+1就置為V+1。
cpp程序: #include<cstdio>#include<cstring>#include<algorithm>#include<queue>#;inttt,kase;intnn,m;intH[45],X[1004],P[1004],flow[1004],tot,cap[1005];intd[45];intS,T;voidadd(intx,inty,intz){P[++tot]=y;X[tot]=H[x];H[x]=tot;flow[tot]=z;cap[tot]=flow[tot];}queue<int>q;boolbfs(){memset(d,0,sizeof(d));d[S]=1;intx;q.push(S);while(!q.empty()){x=q.front();q.pop();for(inti=H[x];i;i=X[i]){if(flow[i]>0&&!d[P[i]]){d[P[i]]=d[x]+1;q.push(P[i]);}}}returnd[T];}intdfs(intx,inta){if(x==T||a==0)returna;intf=a,tmp;for(inti=H[x];i;i=X[i]){if(flow[i]>0&&d[P[i]]==d[x]+1){tmp=dfs(P[i],min(flow[i],a));flow[i]-=tmp;a-=tmp;flow[i^1]+=tmp;if(!a)break;}}if(f==a)d[x]=-1;returnf-a;}intDinic(){intf=0;while(bfs())f+=dfs(S,inf);returnf;}intmain(){/**輸入過程省略**/intmaxflow=Dinic();printf(%d
,maxflow);return0;}
⑦ 靜態路由演算法有哪些
http://cache..com/c?word=%BE%B2%CC%AC%3B%C2%B7%D3%C9%3B%CB%E3%B7%A8&url=http%3A//homepage%2Escau%2Ee%2Ecn/club/sugh/ReadNews%2Easp%3FNewsID%3D284&b=57&a=16&user=
靜態路由演算法
靜態路由演算法主要有洪泛法,隨機走動法,最短路徑法,基於流量的路由演算法
1.洪泛法(Flooding)
節點收到一個報文分組後,向所有可能的方向復制轉發。每個節點不接受重復分組,網路局部故障也不影響通信,但大量重復分組加重了網路負擔。這種方法適宜於網路規模小,通信負載輕,可靠性要求極高的通信場合——如軍用通信中常用。
其改進方法是選擇前進方向的擴散法,可大大減少重復分組的數量。
2.隨機走動法(Random Walk)
節點收到分組後,向所有與之相鄰的節點中為分組隨機選擇出一個節點轉發出去;分組在網路中亂竄,總有可能到達。這種方法雖然簡單,但不是最佳路由,通信效率低,分組傳輸延遲也不可預測,實用價值低。
3.最短路徑法(Shortest Path,SP)
一般來講,網路節點直接相連,傳輸時延也不是絕對最小,這與線路質量、網路節點「忙」與「閑」狀態,節點處理能力等很多因素有關。定量分析中,常用「費用最小」作為網路節點之間選擇依據,節點間的傳輸時延是決定費用的主要因素。
最短路徑法,是由Dijkstra提出的,其基本思想是:將源節點到網路中所有節點的最短通路都找出來,作為這個節點的路由表,當網路的拓撲結構不變、通信量平穩時,該點到網路內任何其它節點的最佳路徑都在它的路由表中。如果每一個節點都生成和保存這樣一張路由表,則整個網路通信都在最佳路徑下進行。每個節點收到分組後,查表決定向哪個後繼節點轉發。
4.基於流量的路由演算法(Flow-based Routing,FR)
SP演算法只考慮網路拓撲結構、尋找最短路徑,沒有考慮網路流量、負載對路由選擇的影響,而FR演算法就結合了網路拓撲結構和通信流量兩方面的因素進行路由選擇。
FR演算法需要知道網路拓撲結構、節點之間的平均流量、各條線路的容量,然後在此基礎上採用適當的選擇演算法,從而找出最佳路由。
FR演算法的基本原理是根據知道一條線路的負荷和平均流量,用排隊計算出該線路的分組平均時延,再由所有線路的平均時延直接計算出流量加權平均值,從而得到整個網路的平均分組時延。此方法可使網路通信量更加平衡,得到較小的平均分組時延。
⑧ 網路流的最大流和最小流是什麼演算法
首先是網路流中的一些定義:
V表示整個圖中的所有結點的集合.
E表示整個圖中所有邊的集合.
G = (V,E) ,表示整個圖.
s表示網路的源點,t表示網路的匯點.
對於每條邊(u,v),有一個容量c(u,v) (c(u,v)>=0),如果c(u,v)=0,則表示(u,v)不存在在網路中。相反,如果原網路中不存在邊(u,v),則令c(u,v)=0.
對於每條邊(u,v),有一個流量f(u,v).
一個簡單的例子.網路可以被想像成一些輸水的管道.括弧內右邊的數字表示管道的容量c,左邊的數字表示這條管道的當前流量f.
網路流的三個性質:
1、容量限制: f[u,v]<=c[u,v]
2、反對稱性:f[u,v] = - f[v,u]
3、流量平衡: 對於不是源點也不是匯點的任意結點,流入該結點的流量和等於流出該結點的流量和。
只要滿足這三個性質,就是一個合法的網路流.
最大流問題,就是求在滿足網路流性質的情況下,源點 s 到匯點 t 的最大流量。
求一個網路流的最大流有很多演算法 這里首先介紹 增廣路演算法(EK)
學習演算法之前首先看了解這個演算法中涉及到的幾個圖中的定義:
**殘量網路
為了更方便演算法的實現,一般根據原網路定義一個殘量網路。其中r(u,v)為殘量網路的容量。
r(u,v) = c(u,v) – f(u,v)
通俗地講:就是對於某一條邊(也稱弧),還能再有多少流量經過。
Gf 殘量網路,Ef 表示殘量網路的邊集.
這是上面圖的一個殘量網路。殘量網路(如果網路中一條邊的容量為0,則認為這條邊不在殘量網路中。
r(s,v1)=0,所以就不畫出來了。另外舉個例子:r(v1,s) = c(v1,s) – f(v1,s) = 0 – (-f(s,v1)) = f(s,v1) = 4.
其中像(v1,s)這樣的邊稱為後向弧,它表示從v1到s還可以增加4單位的流量。
但是從v1到s不是和原網路中的弧的方向相反嗎?顯然「從v1到s還可以增加4單位流量」這條信息毫無意義。那麼,有必要建立這些後向弧嗎?
顯然,第1個圖中的畫出來的不是一個最大流。
但是,如果我們把s -> v2 -> v1 -> t這條路徑經過的弧的流量都增加2,就得到了該網路的最大流。
注意到這條路徑經過了一條後向弧:(v2,v1)。
如果不設立後向弧,演算法就不能發現這條路徑。
**從本質上說,後向弧為演算法糾正自己所犯的錯誤提供了可能性,它允許演算法取消先前的錯誤的行為(讓2單位的流從v1流到v2)
注意,後向弧只是概念上的,在程序中後向弧與前向弧並無區別.
**增廣路
增廣路定義:在殘量網路中的一條從s通往t的路徑,其中任意一條弧(u,v),都有r[u,v]>0。
如圖綠色的即為一條增廣路。
看了這么多概念相信大家對增廣路演算法已經有大概的思路了吧。
**增廣路演算法
增廣路演算法:每次用BFS找一條最短的增廣路徑,然後沿著這條路徑修改流量值(實際修改的是殘量網路的邊權)。當沒有增廣路時,演算法停止,此時的流就是最大流。
**增廣路演算法的效率
設n = |V|, m = |E|
每次增廣都是一次BFS,效率為O(m),而在最壞的情況下需要(n-2增廣。(即除源點和匯點外其他點都沒有連通,所有點都只和s與t連通)
所以,總共的時間復雜度為O(m*n),所以在稀疏圖中效率還是比較高的。
hdoj 1532是一道可以作為模板題目練手。
模板代碼:
[cpp] view plain print?
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <algorithm>
#include <map>
#include <vector>
using namespace std;
const int N = 1100;
const int INF = 0x3f3f3f3f;
struct Node
{
int to;//終點
int cap; //容量
int rev; //反向邊
};
vector<Node> v[N];
bool used[N];
void add_Node(int from,int to,int cap) //重邊情況不影響
{
v[from].push_back((Node){to,cap,v[to].size()});
v[to].push_back((Node){from,0,v[from].size()-1});
}
int dfs(int s,int t,int f)
{
if(s==t)
return f;
used[s]=true;
for(int i=0;i<v[s].size();i++)
{
Node &tmp = v[s][i]; //注意
if(used[tmp.to]==false && tmp.cap>0)
{
int d=dfs(tmp.to,t,min(f,tmp.cap));
if(d>0)
{
tmp.cap-=d;
v[tmp.to][tmp.rev].cap+=d;
return d;
}
}
}
return 0;
}
int max_flow(int s,int t)
{
int flow=0;
for(;;){
memset(used,false,sizeof(used));
int f=dfs(s,t,INF);
if(f==0)
return flow;
flow+=f;
}
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
memset(v,0,sizeof(v));
for(int i=0;i<n;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add_Node(x,y,z);
}
printf("%d\n",max_flow(1,m));
}
}
⑨ 大數據常用的各種演算法
我們經常談到的所謂的 數據挖掘 是通過大量的數據集進行排序,自動化識別趨勢和模式並且建立相關性的過程。那現在市面的數據公司都是通過各種各樣的途徑來收集海量的信息,這些信息來自於網站、公司應用、社交媒體、移動設備和不斷增長的物聯網。
比如我們現在每天都在使用的搜索引擎。在自然語言處理領域,有一種非常流行的演算法模型,叫做詞袋模型,即把一段文字看成一袋水果,這個模型就是要算出這袋水果里,有幾個蘋果、幾個香蕉和幾個梨。搜索引擎會把這些數字記下來,如果你想要蘋果,它就會把有蘋果的這些袋子給你。
當我們在網上買東西或是看電影時,網站會推薦一些可能符合我們偏好的商品或是電影,這個推薦有時候還挺准。事實上,這背後的演算法,是在數你喜歡的電影和其他人喜歡的電影有多少個是一樣的,如果你們同時喜歡的電影超過一定個數,就把其他人喜歡、但你還沒看過的電影推薦給你。 搜索引擎和推薦系統 在實際生產環境中還要做很多額外的工作,但是從本質上來說,它們都是在數數。
當數據量比較小的時候,可以通過人工查閱數據。而到了大數據時代,幾百TB甚至上PB的數據在分析師或者老闆的報告中,就只是幾個數字結論而已。 在數數的過程中,數據中存在的信息也隨之被丟棄,留下的那幾個數字所能代表的信息價值,不抵其真實價值之萬一。 過去十年,許多公司花了大價錢,用上了物聯網和雲計算,收集了大量的數據,但是到頭來卻發現得到的收益並沒有想像中那麼多。
所以說我們現在正處於「 數字化一切 」的時代。人們的所有行為,都將以某種數字化手段轉換成數據並保存下來。每到新年,各大網站、App就會給用戶推送上一年的回顧報告,比如支付寶會告訴用戶在過去一年裡花了多少錢、在淘寶上買了多少東西、去什麼地方吃過飯、花費金額超過了百分之多少的小夥伴;航旅縱橫會告訴用戶去年做了多少次飛機、總飛行里程是多少、去的最多的城市是哪裡;同樣的,最後讓用戶知道他的行程超過了多少小夥伴。 這些報告看起來非常酷炫,又冠以「大數據」之名,讓用戶以為是多麼了不起的技術。
實際上,企業對於數據的使用和分析,並不比我們每年收到的年度報告更復雜。已經有30多年歷史的商業智能,看起來非常酷炫,其本質依然是數數,並把數出來的結果畫成圖給管理者看。只是在不同的行業、場景下,同樣的數字和圖表會有不同的名字。即使是最近幾年炙手可熱的大數據處理技術,也不過是可以數更多的數,並且數的更快一些而已。
在大數據處理過程中會用到那些演算法呢?
1、A* 搜索演算法——圖形搜索演算法,從給定起點到給定終點計算出路徑。其中使用了一種啟發式的估算,為每個節點估算通過該節點的較佳路徑,並以之為各個地點排定次序。演算法以得到的次序訪問這些節點。因此,A*搜索演算法是較佳優先搜索的範例。
2、集束搜索(又名定向搜索,Beam Search)——較佳優先搜索演算法的優化。使用啟發式函數評估它檢查的每個節點的能力。不過,集束搜索只能在每個深度中發現最前面的m個最符合條件的節點,m是固定數字——集束的寬度。
3、二分查找(Binary Search)——在線性數組中找特定值的演算法,每個步驟去掉一半不符合要求的數據。
4、分支界定演算法(Branch and Bound)——在多種最優化問題中尋找特定最優化解決方案的演算法,特別是針對離散、組合的最優化。
5、Buchberger演算法——一種數學演算法,可將其視為針對單變數較大公約數求解的歐幾里得演算法和線性系統中高斯消元法的泛化。
6、數據壓縮——採取特定編碼方案,使用更少的位元組數(或是其他信息承載單元)對信息編碼的過程,又叫來源編碼。
7、Diffie-Hellman密鑰交換演算法——一種加密協議,允許雙方在事先不了解對方的情況下,在不安全的通信信道中,共同建立共享密鑰。該密鑰以後可與一個對稱密碼一起,加密後續通訊。
8、Dijkstra演算法——針對沒有負值權重邊的有向圖,計算其中的單一起點最短演算法。
9、離散微分演算法(Discrete differentiation)。
10、動態規劃演算法(Dynamic Programming)——展示互相覆蓋的子問題和最優子架構演算法
11、歐幾里得演算法(Euclidean algorithm)——計算兩個整數的較大公約數。最古老的演算法之一,出現在公元前300前歐幾里得的《幾何原本》。
12、期望-較大演算法(Expectation-maximization algorithm,又名EM-Training)——在統計計算中,期望-較大演算法在概率模型中尋找可能性較大的參數估算值,其中模型依賴於未發現的潛在變數。EM在兩個步驟中交替計算,第一步是計算期望,利用對隱藏變數的現有估計值,計算其較大可能估計值;第二步是較大化,較大化在第一步上求得的較大可能值來計算參數的值。
13、快速傅里葉變換(Fast Fourier transform,FFT)——計算離散的傅里葉變換(DFT)及其反轉。該演算法應用范圍很廣,從數字信號處理到解決偏微分方程,到快速計算大整數乘積。
14、梯度下降(Gradient descent)——一種數學上的最優化演算法。
15、哈希演算法(Hashing)。
16、堆排序(Heaps)。
17、Karatsuba乘法——需要完成上千位整數的乘法的系統中使用,比如計算機代數系統和大數程序庫,如果使用長乘法,速度太慢。該演算法發現於1962年。
18、LLL演算法(Lenstra-Lenstra-Lovasz lattice rection)——以格規約(lattice)基數為輸入,輸出短正交向量基數。LLL演算法在以下公共密鑰加密方法中有大量使用:背包加密系統(knapsack)、有特定設置的RSA加密等等。
19、較大流量演算法(Maximum flow)——該演算法試圖從一個流量網路中找到較大的流。它優勢被定義為找到這樣一個流的值。較大流問題可以看作更復雜的網路流問題的特定情況。較大流與網路中的界面有關,這就是較大流-最小截定理(Max-flow min-cut theorem)。Ford-Fulkerson 能找到一個流網路中的較大流。
20、合並排序(Merge Sort)。
21、牛頓法(Newton's method)——求非線性方程(組)零點的一種重要的迭代法。
22、Q-learning學習演算法——這是一種通過學習動作值函數(action-value function)完成的強化學習演算法,函數採取在給定狀態的給定動作,並計算出期望的效用價值,在此後遵循固定的策略。Q-leanring的優勢是,在不需要環境模型的情況下,可以對比可採納行動的期望效用。
23、兩次篩法(Quadratic Sieve)——現代整數因子分解演算法,在實踐中,是目前已知第二快的此類演算法(僅次於數域篩法Number Field Sieve)。對於110位以下的十位整數,它仍是最快的,而且都認為它比數域篩法更簡單。
24、RANSAC——是「RANdom SAmple Consensus」的縮寫。該演算法根據一系列觀察得到的數據,數據中包含異常值,估算一個數學模型的參數值。其基本假設是:數據包含非異化值,也就是能夠通過某些模型參數解釋的值,異化值就是那些不符合模型的數據點。
25、RSA——公鑰加密演算法。較早的適用於以簽名作為加密的演算法。RSA在電商行業中仍大規模使用,大家也相信它有足夠安全長度的公鑰。
26、Schönhage-Strassen演算法——在數學中,Schönhage-Strassen演算法是用來完成大整數的乘法的快速漸近演算法。其演算法復雜度為:O(N log(N) log(log(N))),該演算法使用了傅里葉變換。
27、單純型演算法(Simplex Algorithm)——在數學的優化理論中,單純型演算法是常用的技術,用來找到線性規劃問題的數值解。線性規劃問題包括在一組實變數上的一系列線性不等式組,以及一個等待較大化(或最小化)的固定線性函數。
28、奇異值分解(Singular value decomposition,簡稱SVD)——在線性代數中,SVD是重要的實數或復數矩陣的分解方法,在信號處理和統計中有多種應用,比如計算矩陣的偽逆矩陣(以求解最小二乘法問題)、解決超定線性系統(overdetermined linear systems)、矩陣逼近、數值天氣預報等等。
29、求解線性方程組(Solving a system of linear equations)——線性方程組是數學中最古老的問題,它們有很多應用,比如在數字信號處理、線性規劃中的估算和預測、數值分析中的非線性問題逼近等等。求解線性方程組,可以使用高斯—約當消去法(Gauss-Jordan elimination),或是柯列斯基分解( Cholesky decomposition)。
30、Strukturtensor演算法——應用於模式識別領域,為所有像素找出一種計算方法,看看該像素是否處於同質區域( homogenous region),看看它是否屬於邊緣,還是是一個頂點。
31、合並查找演算法(Union-find)——給定一組元素,該演算法常常用來把這些元素分為多個分離的、彼此不重合的組。不相交集(disjoint-set)的數據結構可以跟蹤這樣的切分方法。合並查找演算法可以在此種數據結構上完成兩個有用的操作:
查找:判斷某特定元素屬於哪個組。
合並:聯合或合並兩個組為一個組。
32、維特比演算法(Viterbi algorithm)——尋找隱藏狀態最有可能序列的動態規劃演算法,這種序列被稱為維特比路徑,其結果是一系列可以觀察到的事件,特別是在隱藏的Markov模型中。