全變差演算法
㈠ 演算法基礎
謹以此文,感謝我在這個學校最喜歡的兩個老師之一——肖my老師。本文基本為老師上課說講授內容加上一部分自己的感悟拼湊而來,寫作文本的目的是為自己的演算法課程留下一點點東西,站在老師肩膀上形成粗糙的框架,方便以後的復習以及深入。文筆有限,其中包含的錯誤還請多多包容,不吝賜教。
to do list:
時間復雜度中遞歸樹法;動規,分治新的感悟;
點覆蓋:一組點的集合,使得圖中所有邊都至少與該集合中一個點相連。
支配集:一組點的集合,使得圖中所有的點要麼屬於該集合,要麼與該集合相連。
最大團:在一個無向圖中找出點數最多的完全圖。
獨立集:一組點的集合,集合中的頂點兩兩不相鄰。(團轉過來)
SAT問題:也稱布爾可滿足性問題。給一組變
其中Ci被稱為句子。
點覆蓋<->獨立集<->最大團
最小割:割是一組邊集。如s-t割就是如果去掉這些邊,將把原圖劃分為兩個點集,其中一個點集包含s,一個點集包含t。(兩個是指不相連,而不是代表不存在邊相連,如反向邊)
decision problem: 是否存在。
search problem:找到一個解。
(這個還能擴展,比如decision problem在多項式時間內解決,所以他是P問題嗎)
漸進符號:
注意以上三種都是緊的,對應的兩個小寫的符號是不緊的,即如下圖所示:
概念:演算法的時間復雜度是一個函數,用於定性描述演算法的運行時間。注意,這個一個代表演算法輸入字元串長度的函數。
[注]輸入字元串長度是一個比較關鍵的理解,比如在背包問題中,其時間復雜度為O(nW),因為W不定,所以只能是一個偽多項式時間。
比較:c < log2N < n < n * Log2N < n^2 < n^3 < 2^n < 3^n < n! < n^n
大致:常數<對數<冪函數<指數函數<階乘
對於指數是n相關的進行比較,優先比較指數,再比較底數。
記住一個特例:n (logn)<n!<n n
計算:
一般來說,計算採用主方法和遞歸樹法,其中遞歸樹技巧性比較強,主方法其實也是遞歸樹推導歸納而來,且主方法能得到一個比較緊的結果。
主方法:
f(n) = af(n-b)+g(n) =>O( a^(n/b) *g(n) )
P:decision problems有一個多項式演算法。
NP(nondeterministic polynomial-time):decision problems能夠在多項式時間內驗證。
NPC:NP完全問題,首先這個問題是NP的,其次,其他所有問題都可以多項式時間內歸約到它。
NPH:如果所有NP問題都可以多項式時間歸約到某個問題,則稱該問題為NP困難。
因為NP困難問題未必可以在多項式時間內驗證一個解的正確性(即不一定是NP問題),因此即使NP完全問題有多項式時間的解(P=NP),NP困難問題依然可能沒有多項式時間的解。因此NP困難問題「至少與NP完全問題一樣難」。
一些NP問題能在多項式時間內解決,因為 P∈NP
NP難類型問題的證明:
先選好一個已知NP難的問題,然後將已知NP難問題多項式歸約到要證明的問題上。先給出這個歸約,然後再證明這個歸約的正確性。
NPC類型問題的證明:
證明一個問題Y是NPC問題,先說明Y是NP的,然後找到一個NPC問題X,將這個問題X歸約到問題Y上,即證明完成。
常見的NPC問題(重要,規約的時候有用!):
packing problems: set-packing,獨立集
覆蓋問題:集合覆蓋問題,頂點覆蓋問題
嚴格滿足問題(constraint satisfaction problems):SAT,3SAT
序列問題:哈密爾頓迴路,旅行商問題
劃分問題:3D-matching, 3著色問題
數字問題:子集合問題(子集元素之和為t),背包問題
其他:分團問題(是否存在一個規模為k的團)
規約的概念與理解
規約:意味著對問題進行轉換,例如將一個未知的問題轉換成我們能夠解決的問題,轉換的過程可能涉及到對問題的輸入輸出的轉換。
自歸約:search problem <=p decision problem
歸約:A歸約到B,也就是說,我們對A套一個函數f,在f函數的作用下形成一個新的問題,對這個問題運用B的黑盒解法,能夠解決問題A。
(B <=p A)一般說來,B問題如果可以歸約到A問題,也就是說,一個解決A問題的演算法可以被用做子函數(子程序)來解決B問題,也就是說,求解B問題不會比求解A問題更困難。因此,如果B問題是困難的,那麼A問題也就是困難的,因為不存在求解A問題的高效演算法。(最後一句不懂)
我簡單說一下我理解的規約,以X規約到Y為准,大概分成兩個方面:
註:在 三 的一些實例中細品。
概念:在對問題求解時,總是做出在當前看來是最好的選擇。
貪心的證明:先假設貪心演算法得到的解不是最優解,假設S1是貪心演算法得到的解,而S2是所有最優解中和S1具有最多相同元素的解,然後比較S1和S2,觀察S1和S2中第一個(最前面一個)不一樣的元素,然後在貪心解S2中將不一樣的元素換成S1中的那個元素得到另一個最優解S3,這樣S3和S1比S2和S1有更多相同元素,和假設S2是與S1有最多相同元素的最優解矛盾,這樣來推導S1是最優解。
我的理解:假設這個不是最優的,但是一定存在一個最優的解在某一個位置之前和我當前解結構是一樣的,那麼在這個位置,選最優解也可以選當前解,不影響最終答案。
[注]概念很簡單,但是實際操作的時候,貪心的角度很重要,同樣的貪心,方向對了,演算法就是對的。
例子:
給你一系列活動,每個活動有一個起始時間和一個結束時間,要求在活動不沖突的情況下找到一種有最多活動的安排。
對於這個問題,我們有一下幾種貪心的角度:
①將任務按照 開始時間 升序排列。
②將任務按照 結束時間 升序排列。
③將任務按照 任務時長 升序排列。
④對於每一個任務,都記錄與其他任務沖突的數量,按照 沖突數量 的升序排列。
其中1,3,4都是不可以的。
任務結束時間的貪心證明(反證法):
假設貪心不是最最優的,那我們在最優解中找一個與當前解有最相似的解。
由圖可以知道,貪心貪的就是最早結束,所以如果不是最優,那麼最優的結束時間一定晚於貪心的結束時間。
由上圖就可以證明。
最大流通常與最小割相聯系。
f 為任意一個流,cap為容量,對於任意的s-t割出來的點集(A,B),v( f ) <= cap(A, B)。
當流增加到與割的容量相等時候,就不可能再有增長空間了,稱為最大流。
對於割的容量來說,不同的割法會有不同流量,有些割法永遠不會有流達到,比如部分A = {s}, B = {V - s},這種把源點割出來的割法。
綜上,通過這種感性的認識,如果能找到一個最小的割,那麼這個割就一定是最大能跑到的流(如果流能更高的話在這個割上就會超過容量,反證。)
上圖為一條增廣路,一條增廣路即為一條s-t的路徑,在路徑上仍有流可以跑,其曾廣的流就是該條路徑上最小的剩餘容量。(相當於每找一條增廣路,就至少有一條邊達到滿流。)
直到在圖中找不到增廣路,此時已經達到了最大流。
找ST集合:把滿流的邊去掉,從S出發走到能到的點,遍歷的點就是S集合;剩下的點就屬於T集合。注意,如果找到了在找S集合的時候找到了T點,說明還可以繼續找增廣路。
[補]有一個很有趣的延伸,如多源點多終點問題。問:如果我有兩個源點s1,s2,兩個終點t1,t2,我想求一組流,使得s1-t1,s2-t2的流達到最大,是否可以加一個源點S,S與s1,s2相連,邊流無限大;加一個終點T,T與t1,t2相連,邊流無限大,然後這組ST的最大流即可。——答案是No,無法保證是s1-t1,s2-t2,有可能交錯。
例子講的感覺不是特別好,對理解感覺起不到很大作用,希望以後有新的想法後進行補充。
規約是一個重要的概念和思想。
一個圖的 最大獨立集 與 最小點覆蓋 是不相交的兩個點集,它們的並就是整個點集。
個人理解:獨立集和點覆蓋都是從點的角度進行劃分的,如果我們從邊的角度來看,①一個最小的點覆蓋即為我集合中的每一個點都盡可能與更多的邊相連,②同時,一條邊的兩個端點中,只能有一個端點在最小點覆蓋中[下注]
[注]我們假設有一條邊兩個端點(u,v)都在點覆蓋之中,首先顯然u,v都不是端點,因為假設u是端點的話只需要選擇v即可;
給一個集合S和一堆S的子集S1,S2,...,Sm,問是否存在存在k個子集,使它們的並集為S。
構造:
集合為點,集合中的元素為邊,有相同元素的邊相連。(注意如果某一元素只在一個子集中出現,應該怎麼處理呢!)
規約:在構造的圖中找最小的點覆蓋,選中的點能覆蓋所有的邊即為對應集合的並集能包含所有的元素。所以就完成了集合覆蓋到點覆蓋的規約。
構造:每個句子構造一個三角形,把對應變數但是相反取值的點相連。
規約:3SAT的有一個特點就是,每一個句子中至少有一個為真即可,每個句子都必須是真。將相同變數相反取值相連的目的就是,在最大獨立集中,比如選擇x為真,則剩下所有句子中x-ba一定不會被選中,同時由獨立集和構造出來三角形的性質可以知道,每一個句子,有且僅有一個會被選中(為真)。如上圖,x1-ba為真,x2-ba和x3任選一個為真即可滿足。
search problem <=p decision version
比如:如果能在多項式時間內找到一個哈密爾頓圈,那麼就能在多項式時間內找到一個哈密爾頓圈(刪邊)
在此再談P和NP:
我們知道有些問題是可以從搜索問題規約到判斷問題的,也就是所該問題如果能在多項式內判斷,那麼久能在多項式中搜索到,那麼我們只需要說,這個判斷問題能在多項式時間內求解,就叫做P問題,也就是上圖紅字的意思;那NP問題呢,必須要給出一個解的實例,判斷的是這個實例是否滿足求解問題,這個才是上圖中的紅字。比如,我如果能在多項式時間內判斷哈密爾頓圈是否(Yes/No)存在,那這個就是ploy-time algorithm,如果我給出了一系列點,能過多項式時間內判斷這些點能否構成哈密爾頓圈,那這個就是poly-time certifier。
構造:把一個點拆分成三個點。
構造:(下面兩個圖要連在一起看)
從行的角度看,一行代表一個變數;從列的角度來看,每三列代表一個句子。兩邊中一邊是兩個點,一邊是一個點,所以有k個句子的話,每一行有3k+3個節點。從哈密爾頓圈的答案轉到3SAT的答案看這個圈在每一行是從左到右還是從右到左。
子集和問題:給一個集合S,問是否能在集合中選取元素,使得總和為W。
構造:如下圖,按照前六行和前三列進行分割,可以分成4部分,其中1,3,4部分是固定的,即在第一部分,變數v列和 變數為v(包括變數及取反)的行對應的格子為0,其餘為0;第三部分全為0;第四部分按照12依次寫下來。第二部分,如果Ci句子中有變數v,則記為1,因為一個句子只有三個變數,可以簡單通過第二部分每一列和為3進行判定。此時集合已經構造出來,W為111444,與上面的規約相似,可以通過3SAT的簡單性質進行感性的認知。
近似的想法很簡單,要解決一個問題,我們希望能夠做到①求解結果是最優的 ②在多項式時間內解決 ③對於任意的實例都能夠通過該演算法解決。現在對於部分問題,無法完全滿足以上要求,所以就犧牲了①,但是我們希望結果不是盲目的,所以就引入了近似的概念。
近似演算法。比如2-近似,認為W為近似解,W 為最優解,在求最小值的情況下W<=2W ;在求最大值的情況下,W>=1/2W*
給m個機器和n個任務,每個任務有一個ti的執行時間,我們認為完成最後一個任務所需的時間為負載時間,希望能夠讓這個負載時間最短。
第一種:將任務依次放在機器上,當某個機器空閑時立即放入新任務。此時是2近似的。
證明:
引理1.最短時間安排是大於等於任務中時間最長的任務,L* >= max tj
我們在考慮放入最後一個任務前,根據我們放置的規則,該機器是耗時最短,也就是說,該機器此時的用時是低於除掉最後一個任務後的平均時長,更低於所有任務的平均時長(引理2);再根據引理1,最後一個任務應該是小於最優解的。
補充:
在這里,我還想討論一下這個近似演算法的中等於符號,先上結論:等號不一定能夠找到一個實例,但是可以構造出一種結構,通過取極限求得,我們認為這樣 也算是緊的。
構造實例:有m個機器,其中m(m-1)個任務的用時為1,1個任務的用時為m。肯定有一種任務集合,可以按照以下方式進行安排,此時的貪心解為19。
此時最佳的解為10,如下圖:
通過推廣可以知道此時的比為(2m-1)/m,當m取極限,能夠達到2倍。
第二種:將任務從大到小排序,然後依次放在機器上,當某個機器空閑時立即放入新任務。此時是2近似的。
引理3:如果有大於m個任務,那麼L*>=2t(m-1)。證明:t(m+1)是目前最短的任務,且目前所有機器上都有任務了,所以該任務加入時最優的情況不過是加入設備的原有任務剛好和t(m+1)相等,即等號。
(2近似)在n個點中,選取k個中心點,使得這些中心點能夠以半徑R的圓包含所有的點,讓其中最大的半徑最小,如下圖所示:
基礎:距離需要滿足的三個定理①(同一性)dist(x, x) = 0 ②(自反)dist(x, y) = dist(y, x) ③(三角不等式)dist(x, y) <=dist(x, z)+dist(z, y)
r(C)為C集合中所有點的最大覆蓋半徑。(需要求min r(C))
演算法:在點集中任選一個作為中心點,然後重復以下步驟k-1次:選取距離已選點集中最遠的點,加入點集。
證明:先假設r(C )< 1/2 * r(C)以選好的點畫半徑為1/2 * r(C)的圓,顯然可知[注],這個圓里有且僅有一個r(C )中的點。那麼根據在下圖中,根據三角不等式可以得出:
[注]在每個點上r(c )一定會包含到c點,而r(C )<1/2 * r(C),相當於大圓套小圓,所以c*一定在c的圓中。
(2近似)問題還是很好理解的,在點上加權值,要找一個點覆蓋,使得權值最小。如下圖左邊就是一個帶權的最小點覆蓋。
演算法: 任選一條邊(i, j)加上代價,這個代價從零開始,且這個代價的最大值低於i和j節點的權值。顯然,這個邊權值的最大值取決於兩個端點權值的最小值,我們認為當邊權值與點權值相等時,對應的那個點是緊的。把所有緊的點找出來即為點覆蓋。
流程:
證明:
引理:邊權之和小於等於點覆蓋的點權之和。這主要是由於涉及到一條邊上兩個點都被選(緊的)的情況,感性認知可以看上圖,縮放證明如下:
w(S)是等於所選的節點的權值之和的,等於所選節點節點所對應的邊權之和,可以把它放大到所有節點對應邊權之和,這樣因為一條邊(u, v)在u上算過一次後還要在v上算一次,所以等於邊權和的兩倍。再由上面引理可得。
主要為了線性規劃和整數規劃。
(2近似)沒啥好說的,只需要把方程構造出來就行了。
由於求解出來結果不一定是整數,所以我們認為某一點的值大於1/2,就選入點集。
證明:
因為xi+xj >=1,且都是正數,那必至少一個點是大於1/2的(反證,兩個都小於1/2則和小於1)。
給你n個物品和一個背包,每個物品有一個價值v和一個大小w,背包的容量是W,要求讓背包裝下盡可能大價值。
背包的時間復雜度:O(nW)
注意其中n表示物品的個數,無論是1個還是999個,他都是多項式的,這個很好理解。但是W就不一樣了,這是一個數字。我理解的是這個數字會很奇特,比如1.00001,比如99999,這些有可能看起來不大但是實際在處理的時候很難處理的數字,統一的來說,如果我們把這些數字放在電腦上,都會以二進制的方式存儲起來,有些數字用十進製表示很小,但是放在二進制上面就會很大,由W導致不能在多項式時間內解決(找不到一個范圍/上界來框它)。
演算法: 為了處理這個問題,我們改動了dp的狀態轉移方程,要讓這個轉移方程和W無關[注]。
此時還不是多項式的,然後我們再對value進行約。[注]
[注]這兩步中,我們把w改成v,並對v進行近似處理。OPT的含義變成了,在面對是否選擇第i個物品時,要想讓價值達到當前值,最少的weight。理由是更改後的誤差是可以忍受的:對v進行近似,結果只會出現最大價值的上下誤差,如果對w進行近似,則有可能出現該物品不能放入背包中,導致整個物品直接放棄的情況。
㈡ 簡評三個基於VRF的共識演算法
上交所技術公司 朱立
Algorand、Dfinity和Ouroboros Praos三個共識演算法(Dfinity雖然是項目名,這里用來稱呼其共識演算法也應無不妥)近期較受關注,而且都是基於VRF(Verifiable Random Function) 設計,可以對照學習。Algorand的版本很多,以下單指 1607.01341v9 ,暫稱其為Algorand'(筆者手中另有Algorand的 最新版本 ,其中已對下文提及的幾處問題完成了修正,可與本文參看)。
一、VRF的共性
VRF的意義很好理解——用以完成出塊人(群)的隨機選擇。為此,VRF的返回值應盡力難以預測。先看Algorand'和Dfinity的套路是怎麼做的:大體上是先將前一個隨機數(最初的隨機數卻是協議給定的)和某種代表高度、輪次的變數進行組合,用某種私鑰對之進行簽名(或者是先簽名再組合),最後哈希一下得出最新的隨機數。這樣產生的隨機數旁人很容易驗證其合乎演算法,"V"就這樣得到了;而哈希返回值又是隨機分布的,「R」也因此得到保證。在此過程中,為降低操縱結果的可能性,有兩個注意事項: A) 簽名演算法應當具有唯一性,也就是用同一把私鑰對同樣的信息進行簽名,只有一個合法簽名可以通過驗證——普通的非對稱加解密演算法一般不具備這個屬性,如SM2。如果用的簽名演算法沒有這種uniqueness屬性,那在生成新隨機數的時候就存在通過反復多次嘗試簽名以挑出最有利者的餘地,會降低安全性。 B) 避免在生成新隨機數時將當前塊的數據作為隨機性來源之一,比如引用本塊交易列表的merkle root值等等,因為這樣做會給出塊人嘗試變更打包交易順序、嘗試打包不同交易以產生最有利的新隨機數的餘地。在設計和檢視新的共識演算法時,以上兩個注意事項是要特別留意的。
考察一下VRF的返回結果應該如何運用。目前所見用法中,VRF的返回結果可以用來公開完成節點或節點群體的選擇,也可以私密地完成選擇。以Dfinity為例,它是利用mod操作來唯一、公開地確定一個Group。Algorand'、Ouroboros Praos是私密選擇的範例,大致套路是對VRF的最新返回值,配上輪次等變數後用私鑰進行簽名並哈希,如果哈希值小於某個閾值,節點就可以私密地知道自己被選中。這種方法很可能在網路節點數較多時的表現會更穩定,否則幸運兒個數上下波動會較大,進而影響協議表現,包括空塊和分叉。
二、簡評強同步假設版本的Algorand'
私密選擇提供了較強的抗擊定點攻擊的能力,但由於幸運兒的總數對於任何一個幸運兒都是不能預知的,也因此給後續共識演算法的設計和區塊鏈的優化帶來了困難。Algorand『採用了很強的同步網路假設(同步網路假設下的共識演算法當然容易做一些),要求預先知道網路消息傳播時間的上限:在固定時間內完成對固定比例的用戶的網路傳播。比如要知道,1KB消息,在1秒鍾內完成全網95%的傳播,而1MB消息需要1.5分鍾完成全網95%的傳播。但這個傳輸上限應該如何選擇? 通過一段時間的統計結果再乘以一個系數這種經驗統計?只能說「感覺上可以」,但如果要嚴謹和安全,Algorand『演算法應該補充證明即使在遭遇DDOS或互聯網擁堵的情況下消息傳播嚴重超限後演算法仍然能夠保證安全——然而這個證明是缺失的。作為對照,Ouroboros Praos公開承認之前在同步網路假設下設計的Ouroboros協議在非同步網路條件下會出錯,所以才又做了Ouroboros Praos;新版本的Algorand承認在弱同步網路時會在不同的塊上達成共識(後續網路恢復強同步時分叉可以得到解決)雲雲,這些都可資參考。
即使我們暫且認可Algorand'演算法可以通過設定一個很大的傳播時間上限來回應上述問題,但隨之而來的是此時可以看出此演算法缺乏一個非常好的特性:Responsiveness。這個特性指的是:若一個協議被設計為在一個較大的傳播時間上限DELTA下工作,但若實際傳播時間是較小的delta,則協議的實際推進步調將只和delta有關,這種協議被稱為Responsive的。具有Responsive特性的共識演算法再配以同步網路假設會非常理想——出於安全,上限可以設置很大,然而協議執行速度只和當時網路條件有關。Algorand'並不具有這種特性。平均而言,Algorand'完成共識所需的消息傳送次數是11輪,每輪如果要確保安全,完成共識的時間就會很長,單個分區的吞吐量就不會太高。當然,架構設計涉及很多取捨,最終評價一個演算法好還是不好還是要回到初心——准備拿來實現的目標是什麼。上述分析只是嘗試客觀地指出Algorand'演算法的幾個少為人知的固有特徵,供讀者自行評估。
三、簡評Dfinity的可擴展性問題
私密選擇並且立即上任的做法,也給系統分片帶來了極大挑戰。Dfinity是明確要做分片(Sharding)的,所以必須直面挑戰。可擴展性問題非常復雜,完整解決這個問題需要通盤考慮網路、存儲、計算三方面的可擴展性——時下大多數區塊鏈3.0項目只注意到計算的分片和可擴展性,忽略了其餘二者,從而不可能真正實現理想的擴展。由於公鏈節點網路帶寬的制約,計算合約所需的數據通常很難迅速地從一個節點拷貝到另一節點,所以就算用VRF實現了飄忽來去的出塊節點選擇,存儲節點是沒法同樣飄逸如風的。明顯的選擇有那麼幾個:全部節點存儲全部數據,不同節點靜態地分配用來存儲不同分區。前者的可擴展性很差,對於後者而言,如果出塊節點漂浮不定且出塊節點還需要完成合約運算,就意味著基於P2P網路來回遠程訪問存儲,性能多半急劇下降;動態決定的出塊節點只完成排序共識,計算能力和存儲捆綁,通過靜態分區提供可擴展性,可能是合理的應對。然而,最可恨的就是「然而」二字——即使如此,系統還存在一處對存儲和網路構成壓力的所在:最終用戶提交的待打包交易。普通公鏈(先不考慮EOS那種)的帶寬有限,如果用戶提交的待打包交易必須粗放型地全網泛濫傳播,那現有網路帶寬可以提供多少TPS?如果出塊節點是靜態分區或者至少提前一段時間公開知曉,事情尚有迴旋餘地;如果出塊節點是如此飄忽不定,而且直到最後一刻也只有這些節點自己知道,那無論是用戶還是出塊節點候選人看起來最直接的應對之道就是全網泛濫傳播全部待打包交易、保存全部待打包交易,這樣帶寬和存儲仍然成為系統瓶頸。
所以這里碰到的,本質上還是安全、可擴展性、去中心化的不可能三角。
四、簡評Ouroboros Praos
BM懟 Ouroboros的文字已經流傳廣泛。BM的話當然有些明顯是不對的,比如Ouroboros的DPOS是指"Dynamic [stake distribution] POS"而不是BM的Delegate POS,但其關於Pareto分布的評論則值得玩味。如果我們仔細瀏覽後出的Ouroboros Praos,可以發現協議的安全假設和安全證明完全沒有考慮經濟博弈因素,因此洋洋灑灑的證明很可能會不得要領而錯過真正需要防護的方向——畢竟一直以來POS/DPOS這些協議的血管裡面流淌的就是基於經濟博弈和人性進行設計的血液。最明顯的例子是在forward secure signature的實現方法上,協議目前的設計是要求每個好的節點自覺主動地安全刪除用過的私鑰,而完全沒有考慮近乎零的私鑰保存成本如何面對bribe attack的誘惑,然而這卻是值得考慮的。除了形式化證明之外,Ouroboros Praos本身並沒有太多值得關注的協議特徵,總體上就是用VRF抽簽結合POS演算法並針對某些安全假設進行了形式化證明,其做事的態度是非常值得贊賞的。
五、總結
這幾個演算法本身頗有創意,也很值得學習。與此同時,在看過以太坊CASPER目前披露的分區技術後,筆者的體會是:區塊鏈3.0的競爭才剛剛開始,從以太坊團隊的技術路線看,他們的技術考量和選擇要比很多宣稱要超越以太坊的團隊來得深刻和全面。如果當真要超越以太坊,還是應該先從理解以太坊開始。
順便感謝趣鏈邱煒偉博士對本文的貢獻!
㈢ GIS 學科都是有哪些重要的演算法謝謝
一 空間數據壓縮演算法
1 基於矢量的壓縮演算法
2 基於柵格的壓縮演算法
二 空間數據內插演算法
1 點的內插演算法
2 區域內插演算法
3 采樣點曲線擬合
三 空間數據轉換演算法
1 矢量數據向柵格數據轉換
2 柵格數據向矢量數據轉換
3 TIN向規則格網DEM轉換
四 空間數據誤差分析演算法
1 屬性誤差的分析演算法
2 位置誤差分析演算法
五 多邊形自動生成與裁剪演算法
1 多邊形性質及有關處理
2 弧-弧拓撲生成演算法
3 多邊形自動生成演算法
4 多邊形圖裁剪演算法
六 TIN的構建演算法
1 基於離散點的構TIN演算法
2 基於等高線的構TIN演算法
七 Voronoi圖構建演算法
1 平面點集Voronoi圖構建演算法
2 線/面集Voronoi圖構建演算法
3 球面Voronoi圖構建演算法
八 空間變換演算法
1 地圖坐標變換演算法
2 地圖投影變換演算法
3 透視投影變換演算法
九 空間度量演算法
1 空間距離與方向度量演算法
2 面向度量演算法
3 體積度量演算法
4 坡度坡向度量演算法
十 數字地形分析演算法
1 基本地形因子分析演算法
2 地形特徵提取演算法
3 數字地形典型應用演算法
十一 空間統計分析演算法
1 多變數統計分析演算法
2 空間分類統計演算法
3 層次分析演算法
十二 空間分析演算法
1 路徑分析演算法
2 資源分配演算法
3 緩沖區分析演算法
4 疊置分析演算法
十三 GIS可視化操縱演算法
1 地形簡化演算法
2 多解析度紋理生成演算法
3 紋理映射演算法
4 光相關演算法
十四 空間數據挖掘與知識發現演算法
㈣ 深入淺出BP神經網路演算法的原理
深入淺出BP神經網路演算法的原理
相信每位剛接觸神經網路的時候都會先碰到BP演算法的問題,如何形象快速地理解BP神經網路就是我們學習的高級樂趣了(畫外音:樂趣?你在跟我談樂趣?)
本篇博文就是要簡單粗暴地幫助各位童鞋快速入門採取BP演算法的神經網路。
BP神經網路是怎樣的一種定義?看這句話:一種按「誤差逆傳播演算法訓練」的多層前饋網路。
BP的思想就是:利用輸出後的誤差來估計輸出層前一層的誤差,再用這層誤差來估計更前一層誤差,如此獲取所有各層誤差估計。這里的誤差估計可以理解為某種偏導數,我們就是根據這種偏導數來調整各層的連接權值,再用調整後的連接權值重新計算輸出誤差。直到輸出的誤差達到符合的要求或者迭代次數溢出設定值。
說來說去,「誤差」這個詞說的很多嘛,說明這個演算法是不是跟誤差有很大的關系?
沒錯,BP的傳播對象就是「誤差」,傳播目的就是得到所有層的估計誤差。
它的學習規則是:使用最速下降法,通過反向傳播(就是一層一層往前傳)不斷調整網路的權值和閾值,最後使全局誤差系數最小。
它的學習本質就是:對各連接權值的動態調整。
拓撲結構如上圖:輸入層(input),隱藏層(hide layer),輸出層(output)
BP網路的優勢就是能學習和儲存大量的輸入輸出的關系,而不用事先指出這種數學關系。那麼它是如何學習的?
BP利用處處可導的激活函數來描述該層輸入與該層輸出的關系,常用S型函數δ來當作激活函數。
我們現在開始有監督的BP神經網路學習演算法:
1、正向傳播得到輸出層誤差e
=>輸入層輸入樣本=>各隱藏層=>輸出層
2、判斷是否反向傳播
=>若輸出層誤差與期望不符=>反向傳播
3、誤差反向傳播
=>誤差在各層顯示=>修正各層單元的權值,直到誤差減少到可接受程度。
演算法闡述起來比較簡單,接下來通過數學公式來認識BP的真實面目。
假設我們的網路結構是一個含有N個神經元的輸入層,含有P個神經元的隱層,含有Q個神經元的輸出層。
這些變數分別如下:
認識好以上變數後,開始計算:
一、用(-1,1)內的隨機數初始化誤差函數,並設定精度ε,最多迭代次數M
二、隨機選取第k個輸入樣本及對應的期望輸出
重復以下步驟至誤差達到要求:
三、計算隱含層各神經元的輸入和輸出
四、計算誤差函數e對輸出層各神經元的偏導數,根據輸出層期望輸出和實際輸出以及輸出層輸入等參數計算。
五、計算誤差函數對隱藏層各神經元的偏導數,根據後一層(這里即輸出層)的靈敏度(稍後介紹靈敏度)δo(k),後一層連接權值w,以及該層的輸入值等參數計算
六、利用第四步中的偏導數來修正輸出層連接權值
七、利用第五步中的偏導數來修正隱藏層連接權值
八、計算全局誤差(m個樣本,q個類別)
比較具體的計算方法介紹好了,接下來用比較簡潔的數學公式來大致地概括這個過程,相信看完上述的詳細步驟都會有些了解和領悟。
假設我們的神經網路是這樣的,此時有兩個隱藏層。
我們先來理解靈敏度是什麼?
看下面一個公式:
這個公式是誤差對b的一個偏導數,這個b是怎麼?它是一個基,靈敏度δ就是誤差對基的變化率,也就是導數。
因為?u/?b=1,所以?E/?b=?E/?u=δ,也就是說bias基的靈敏度?E/?b=δ等於誤差E對一個節點全部輸入u的導數?E/?u。
也可以認為這里的靈敏度等於誤差E對該層輸入的導數,注意了,這里的輸入是上圖U級別的輸入,即已經完成層與層權值計算後的輸入。
每一個隱藏層第l層的靈敏度為:
這里的「?」表示每個元素相乘,不懂的可與上面詳細公式對比理解
而輸出層的靈敏度計算方法不同,為:
而最後的修正權值為靈敏度乘以該層的輸入值,注意了,這里的輸入可是未曾乘以權值的輸入,即上圖的Xi級別。
對於每一個權值(W)ij都有一個特定的學習率ηIj,由演算法學習完成。
㈤ SAM演算法理解
SAM演算法過程基於數據的噪音分析。一般的,信噪比會隨著信號的降低而減小。然而當人們針對每一個基因進行分析時,發現即使他們的信號在同一水平,每一個基因的表達噪音都不一樣。所以無法籠統地給出一個具體地線性方程來分析全部基因,必須一個一個基因單獨分析。假設有對照實驗I和U兩組局拆,I和U實驗各有平行實驗w組,對於某個指定的基因i,定義相對差異值 (relative difference(d(i)))為基因i在實驗組I和U當中的平均值之差除以I和U的總體標准誤差均值。因為當標准誤差均值過低時,會產生一個較高的d(i)值,所以總體的標准誤差均值增加了一個較正項。具體公式如下:
其中上劃線表示平均值 ,å m 和å n 表示實驗組I和U的基因i表達的樣本標准差,n1和n2表示實驗組I和U當中基因i參與統計的探針的個數。S0為較正談臘陸項,它可以由計算機自動給出,也可以由人手動指定。S0的取值標準是:將所有的d(i)值排序後100等分,每一等分先求得中位數絕對離差,然後計算這些中位數絕對離差值的變異系數。取s0分別等於100等分當中的s(i)的最小值,依次計算。最終s0的值就是在這些計算中,使變異系數最小的s0。
我們來比較一下它和t-test的異同:
[圖片上傳失敗...(image-92c592-1597045517277)]
比較之下,我們就會發現兩者十分的相同。左邊是兩組具有不同探針數和不同標准差的非平行實驗t-test計算公式,右邊就是具有不同探針數和不同標准差的非平行實驗的SAM公式,我們可以看到,它們的最終差別,只在那個s0附加項上。由此我們可以知道,實際上SAM就是t-test的一個具體應用。
在計算得到所有的d(i)值之後,重排樣含頃品計算d(i)期待值d E (i)。然後用期待值d E (i)對實測值d(i)做圖。如果期待值和實測值相同,那麼作圖點就應該落在斜率為1的直線上,如果不同,作圖點就落在其外。差別越大,距離該直線就越遠。給定一個D值(默認的話,可以設置為1.2),當期待值和實測值差別比D大時,就認為有顯著差異。這就是SAM演算法。
下面我們就來使用R來實踐一下SAM演算法。
<pre style="box-sizing: border-box; font-family: "Roboto Slab", Georgia, Times, serif; font-size: 1em; font-weight: 300; font-style: inherit; margin: -2px 0px 27px; padding: 0px; vertical-align: baseline; border: 0px; outline: 0px; line-height: 27px; overflow: auto; max-width: 100%; background: transparent; color: rgb(102, 102, 102);">##安裝SAM庫
--- Please select a CRAN mirror for use in this session ---
also installing the dependency 『impute』
trying URL ' http://software.rc.fas.harvard.e/mirrors/R/bin/windows/contrib/2.11/impute_1.24.0.zip'
Content type 'application/zip' length 1205991 bytes (1.2 Mb)
opened URL
downloaded 1.2 Mb
trying URL ' http://software.rc.fas.harvard.e/mirrors/R/bin/windows/contrib/2.11/samr_1.28.zip'
Content type 'application/zip' length 80418 bytes (78 Kb)
opened URL
downloaded 78 Kb
package 'impute' successfully unpacked and MD5 sums checked
package 'samr' successfully unpacked and MD5 sums checked
The downloaded packages are in
Loading required package: impute
Background correcting
Normalizing
Calculating Expression
</pre>
SAM分析。我們首先來了解一下samr函數。
我們注意到其參數resp.type有以下幾種類型:"quantitative" 定量反應,其中data參數當中的y必須是數值型數組; "Two class unpaired" 比較兩種不同條件下的結果,其中data參數當中的y必須是1或者2數組,即要麼值屬於其中一種條件,要麼屬於另外一種條件; "Survival" for censored survival outcome; "Multiclass" : 兩組以上實驗條件,其中data參數當中的y是自然數數組,指定實驗條件編號; "One class" 單組實驗,y是1的數組; "Two class paired" 比較兩種不同條件下的結果,並且實驗是成對進行的,其中data參數當中的y是-1,1,-2,2……-k,k這樣成對出現的數組; "Two class unpaired timecourse", "One class time course", "Two class.paired timecourse" or "Pattern discovery"與時間相關的比較,y值必須是kTimet這種形式,其中k是組編號,t是時間,Time就是字元Time,起始的時間點要為kTimetStart格式,結束的點要為kTimetEnd格式。
Table 1 Resp.type取值范圍
| Resp.type | 取值 |
| Quantitative | 實數,例:27.4 或者-45.34 |
| Two class (unpaired) | 整數1,2 |
| Multiclass | 整數1,2,3,…… |
| Paired | 整數-1,1,-2,2等等成對出現,通常認為負號代表未處理的對照組,正號代表實驗組;-1總是與1配對,-2與2配對直至-k與k |
| Survival data | (Time, status)這種成對的數字,比如(50,1),(120,0)。第一個數字代表時間,第二個數字代表狀態(1=死亡,0=存活) |
| One class | 整數1 |
在示例的數據中,實驗設計為estrogen存在與不存在,及作用10及48小時的比較。因為時間點過少,不足以形成timecourse,所以我們用多組來比較吧。
<pre style="box-sizing: border-box; font-family: "Roboto Slab", Georgia, Times, serif; font-size: 1em; font-weight: 300; font-style: inherit; margin: -2px 0px 27px; padding: 0px; vertical-align: baseline; border: 0px; outline: 0px; line-height: 27px; overflow: auto; max-width: 100%; background: transparent; color: rgb(102, 102, 102);">> gp=rep(1:4,each=2)
</pre>
SAM演算法因為其提供有 Microsoft Excel插件,所以使用非常廣泛,相反,其在R當中的應用卻顯得相對較少。有研究表明,SAM對FDR的控制並不是很好,這是它最主要的不足。
㈥ 什麼是H-K演算法
其實HK演算法思想很朴實,就是在最小均方誤差准則下求得權矢量.
他相對於感知器演算法的優點在於,他適用於線性可分和非線性可分得情況,對於線性可分的情況,給出最優權矢量,對於非線性可分得情況,能夠判別出來,以退出迭代過程.
2.在程序編制過程中,我所受的最大困擾是:關於收斂條件的判決.
對於誤差矢量:e=x*w-b
若e>0 則繼續迭代
若e=0 則停止迭代,得到權矢量
若e〈0 則停止迭代,樣本是非線性可分得,
若e有的分量大於0,有的分量小於0 ,則在各分量都變成零,或者停止由負值轉變成正值時,停機.
3.在程序編制中的注意點:
1)關於0的判斷,由於計算機的精度原因,嚴格等於零是很不容易的,而且在很多情況下也沒有必要,則只要在0的一個可以接受的delta域內就可接受為零
2)關於判斷,迭代前後,變數是否發生變化
在判斷時,顯然也不能直接判斷a(i)==a(i+1)
而應該|a(i)-a(i+1)|〈err
4.HK詳細代碼如下:
unction [w,flag]=HK(data)
Iteration=20;
flag=0;
% [n,p]=size(data);
n=size(data,1);
b=ones(n,1)./10;
c=0.6;
xx=inv(data'*data)*data';
w=xx*b;
e=data*w-b;
t=0;
while (1)
temp=min(e);
temp1=max(e);
if temp>-1e-4 && temp1e-3
deltab=e+abs(e);
b=b+c.*deltab;
w=w+c.*xx*deltab;
e=data*w-b;
else
if temp>=0 && temp1
H-K演算法是求解Xw=b,式中b=( b1, b2, …, bn)T,b的所有分量都是正值。這里要同時計算w和b,我們已知X不是N*N的方陣,通常是行多於列的N*(n+1)階的長方陣,屬於超定方程,因此一般情況下,Xw=b沒有唯一確定解,但可求其線性最小二乘解。
設Xw=b的線性最小二乘解為w*,即使||Xw*-b||=極小 採用梯度法,定義准則函數:
)bXw()bXw(2
1bXw21)bxw(21)b,x,w(JT2
n1i2iiT
當Xw=b的條件滿足時,J達到最小值。由於上式中包括的
n
1
i2iiT
)bxw
(項為兩個數量方差的和,且我們將使其最小化,因此也
稱之為最小均方誤差演算法。
使函數J同時對變數w和b求最小。對於w的梯度為:
)bXw(Xw
J
T 使0w
J
,得XT(Xw-b)=0,從而XTXw=XTb。因為XTX為(n+1)*(n+1)階方陣,因此可求得解:
w = (XTX)-1XTb = X#b
這里X#= (XTX)-1XT稱為X的偽逆,X是N*(n+1)階的長方陣。
由上式可知,只要求出b即可求得w。利用梯度法可求得b的迭代公式為:
)
k(bbbJC)k(b)1k(b
根據上述約束條件,在每次迭代中,b(k)的全部分量只能是正值。由J的准則函數式,J也是正值,因此,當取校正增量C為正值時,為保證每次迭代中的b(k)都是正值,應使)
k(bbbJ
為非正值。在此條件下,准則函數J的微分為:
|bXw|)bXw(bJ2)
k(bb
該式滿足以下條件:
若[Xw(k) – b(k)] > 0,則)k(b)k(XwbJ)
k(bb
若[Xw(k) – b(k)] < 0,則0bJ)
k(bb 由b的迭代式和微分,有:
b(k+1) = b(k) +δb(k)
δb(k) = C[Xw(k) – b(k) + | Xw(k) – b(k)|]
將此式代入w=X#b,有:
w(k+1) = X#b(k+1) = X#[b(k) +δb(k)] = w(k) + X#δb(k)
為簡化起見,令e(k) = Xw(k) – b(k),可得H-K演算法的迭代式。
設初值為b(1),其每一分量均為正值,則:
w(1) = X#b(1) e(k) = Xw(k) – b(k)
w(k+1) = w(k) + X#{C[Xw(k) – b(k) + |Xw(k) – b(k)|]}
= w(k) + CX#[e(k) + |e(k)|]
由於
X#e(k) = X#[Xw(k) – b(k)] = (XTX)-1XT[Xw(k) – b(k)]
= w(k) –X#b(k) = 0
因此
w(k+1) = w(k) + CX#|e(k)|
b(k+1) = b(k) + C[Xw(k) – b(k) + |Xw(k) – b(k)|]
= b(k) + C[e(k) + |e(k)|]
㈦ 演算法與計算公式的區別請舉例說明
演算法是程序執行的一系列步驟和方法。
計算公式是計算的方法。
計算公式也可以用於演算法當中,演算法不僅是數的運算步驟,也是其他非數的執行的步驟和方法,如華羅庚的燒水,做飯的步驟一樣。計算公式就是用來提供給演算法應用的一種而已。
㈧ 基因組序列比對演算法介紹(一)
基因組重測序中序列比對介紹
重測序基因組數據比對,是指將測序儀下機fastq數據(NGS read序列,通常100-150bp),與人類參考基因組(reference)進行匹配,允許錯配(mismatch),插入缺失(indel),目的是在參考基因組找到序列最相似的位置,通常是基因組分析(包括 variation calling,ChIP-seq,RNA-seq,BS-seq)流程的第一步。
常用演算法
圖一
漢明距離(Hamming distance)表示兩個(相同長度)字對應位置不同的數量,我們以d(x,y)表示兩個字x,y之間的漢明距離。對兩個字元串進行異或運算,並統計結果為1的個數,那麼這個數就是漢明距離。圖中read1最佳位置的方法,就是通過查找最小漢明距離的實現的。
編輯距離(Edit distance)是針對二個字元串(例如英文字)的差異程度的量化量測,量測方式是看至少需要多少次的處理才能將一個字元串變成另一個字元串。圖中read3最佳位置,通過查找最我輯距離的方法實現。
圖二
全局比對(Global alignment):全局比對是指將參與比對的兩條序列裡面的所有字元進行比對。全局比對在全局范圍內對兩條序列進行比對打分,找出最佳比對,主要被用來尋找關系密切的序列。其可以用來鑒別或證明新序列與已知序列家族的同源性,是進行分子進化分析的重要前提。其代表是Needleman-Wunsch演算法。圖一中,read3使用全部比對。
局部比對(Local alignment):與全局比對不同,局部比對不必對兩個完整的序列進行比對,而是在每個序列中使用某些局部區域片段進行比對。其產生的需求在於、人們發現有的蛋白序列雖然在序列整體上表現出較大的差異性,但是在某些局部區域能獨立的發揮相同的功能,序列相當保守。這時候依靠全局比對明顯不能得到這些局部相似序列的。其次,在真核生物的基因中,內含子片段表現出了極大變異性,外顯子區域卻較為保守,這時候全局比對表現出了其局限性,無法找出這些局部相似性序列。其代表是Smith-Waterman局部比對演算法。圖一中,read2使用局部比對。
圖三
Smith-Waterman演算法介紹
Smith-Waterman是由Temple F. Smith和Michael S. Waterman於1981年提出的一種進行局部序列比對(相對於全局比對)的演算法,用於找出兩個核苷酸序列或蛋白質序列之間的相似區域。該演算法的目的不是進行全序列的比對,而是找出兩個序列中具有高相似度的片段。S-W演算法基於動態規劃,它接受任意長度、任意位置、任意序列的對齊,並確定是否能找到最優的比對。
簡單地說就是,動態規劃找到問題中較小部分的解,然後把它們放在一起,形成整個問題的一個完整的最優最終解。
它優於BLAST和FASTA演算法,因為它搜索了更大的可能性,具有更高的敏感性。
S-W演算法不是一次查看整個序列,而是對多個長度的片段進行比較,尋找能夠最大化得分的片段。演算法本身本質上是遞歸的:
圖四
演算法步驟如下:
基因組分析***** 微信 公眾號推出 《50篇文章深入理解NGS》系列文章, 第三篇文章 《基因組序列比對演算法介紹(一)》,爭取每周更新一篇高質量生信干貨帖子。
關注 "基因組分析" 微信公眾號,了解最新最全生信分析知識。
㈨ 阿裡面試官:恕我直言,搞懂這10道演算法題,輕松拿20K不是問題
01打怪獸
難度:容易
現在有3隻怪獸,他們的都有自己的血量a,b,c(1<=a,b,c<=100),當Tom打死第一怪獸的時候花費的代價為0,其餘的怪獸的代價為當前的怪獸的血量減去上一個怪獸的血量的絕對值。問Tom打死這些怪獸所需要的最小代價
02數組變換
難度:中等
給出一個長度為 n 的數組,和一個正整數 d。 你每次可以選擇其中任意一個元素 a[i] 將其變為 a[i] + d 或 a[i] - d,這算作一次操作。你需要將所有的元素全部變成相等元素,如果有解,請輸出最小操作次數,如果無解請輸出-1。
01超級區間
難度:中等
Tom現在有一個長度為n的數組,Jerry給Tom定義了一種超級區間,如果區間[l,r]滿足(a[l]+…+a[r])>=k,則區間[l,r]被稱為超級區間,現在Jerry想讓Tom告訴他數組中有多少個超級區間。
02能量半徑
難度:中等
codancer來到了一個能量平面上的中心,坐標為(0,0),接下來巫師Tom會在q個坐標上放置能量點,每個能量點的能量值為1,為了打敗哥斯拉,他需要至少k點的能量,因此他想確定一個最小的整數半徑r使得codancer能夠從這個圓心為(0,0),半徑為r的圓形區域內得到至少k個能量值,請你幫他確定最小的整數半徑r。
01找出二叉搜索樹的第2大的數
難度:容易
給定一個二叉搜索樹,找出其第二大的數。
02字元配對
難度:中等
給你一個字元串,字元串中僅包含"A","B",現在有四種字元串"AA","AB","BA","BB",每種字元串都有他們的權值,問從給出的字元串中能夠得到的最大權值為多少(一個字元只能屬於一個子字元串)?
01斐波那契字元串
難度:中等
Tom發現了一種神奇的字元串-斐波那契字元串,定義f[1]=0,f[2]=1,對於所有的i>2都有f[i]=f[i-2]+f[i-1],其中「+」代表拼接,比如01+10=0110,現在對於字元串f[n],請判斷f[n]的第k項是0,還是1?
01Hikari and Interstellar Experience
難度:容易
在無垠的宇宙中,有 n 個星球,第 i 個星球有權值vi 。由於星球之間距離極遠,因此想在有限的時間內在星際間旅行,就必須要在星球間建立傳送通道。 任意兩個星球之間均可以建立傳送通道,不過花費並不一樣。 第 i 個星球與第 j 個星球的之間建立傳送通道的花費是lowbit(vi ⊕ vj) ,其中⊕為二進制異或,而lowbit(x)為 x 二進制最低位的值,例如lowbit(5) = 1,lowbit(8) = 8 。 特殊地,lowbit(0) = 0。 Hikari 想在這 n 個星球間穿梭,於是――你需要告訴 Hikari,要使這 n 個星球相互可達,需要的花費最少是多少?
02二進制字元串
難度:中等
Tom得到了一個二進制字元串s,即s只由Ɔ'和Ƈ'組成,現在令d(t)代表二進制字元串t在十進制下的值。 那麼d(「011」)=3,d(「0001000」)=4,如果t的長度等於d(t),那麼就稱t是奇妙串,現在Tom想知道s中有多少個子串是奇妙串?
01小明的數學作業
難度:容易
眾所周知,小明是一個數學小能手,有一天數學老師給了小明一個長度為n(2<=n<=5000)的序列,其中第i個數是ai(0<=ai<=1e9),數學老師想知道這個序列排序後,其中最長的等差子序列的長度是多長,聰明的你能幫小明解決這個問題嗎?
02Codancer上樓
codancer來到了一棟大樓前,現在他要上樓。
如果codancer從第x層走樓梯到第y層(y>x),那麼他所花費的時間是a[x]+a[x+1]+…+a[y];
如果他從x層坐電梯到第y層,那麼他所花費的時間是c+(b[x]+b[x+1]+…+b[y]),因為他等電梯的時間為c。
現在codancer想知道從第1層到第n層需要最少需要多長時間?
01變換的秘鑰
難度:中等
Tom最開始有一個密鑰s1,s1是長度為n的由小寫字母組成的字元串。Jerry也有一個長度為n的由小寫字母組成的密鑰s2。現在有m組關系,每組關系由兩個數字[u,v]構成(1<=u,v<=26),表示26個字母表中的第u個小寫字母可以直接轉換為第v個小寫字母。假設u=1,v=2,那麼說明字母'a'可以直接轉換為字母'b'。現在Tom對於s1的每個字母使用無數次轉換,請判斷s1能否轉換為s2?
01最大邊權和
難度:簡單
現在有n個點(1<=n<=1000),每個點都有一個值稱為點權ai(ai為偶數,1<=ai<=1000),現在可以將任意兩個點相連,連起來以後這條邊也有一個值稱為邊權,這個邊的邊權為這兩個點的點權之和的一半。現在需要你添加n-1條邊,問將這n個點連通以後(連通是指任意兩個點都能互相到達)的最大的邊權和是多少?
02錢庄
難度:中等
錢庄每天能夠收到很多散錢,第i個散錢的值2 wi。為了便於管理,錢庄每天都會向中央銀行申請兌換錢幣,假設錢庄有一些散錢使得2 k1+2 k2+...+2 km=2^x(x為非負整數),那麼就可以將這些散錢兌換成一個大錢幣,問在錢庄收到的這些散錢最終最少能變成幾個錢幣?
01codancer的旅行
難度:困難
期末考試終於結束啦,Codancer開始了他的旅行,現在整個地圖上有n個城市,這些城市之間有n-1條道路相連,每條道路都有一個距離,並且保證整個圖是連通的,即這個地圖可以看作是一棵樹,現在假設Codancer要從城市A到城市B,那麼他的路費就是從A-B的路徑上邊權最大的邊的權值wmaxx元。現在Codancer有k元,他想知道他能選擇那些(A,B)並且A<B使得codancer能夠到達?
HashMap是一個用於存儲Key-Value鍵值對的集合,每一個鍵值對也叫做Entry。這些個鍵值對(Entry)分散存儲在一個數組當中,這個數組就是HashMap的主幹。
01全奇數組
難度:中等
codancer現在有n個正整數a[1],a[2]…a[n],Tom告訴codancer他可以進行下列操作,選擇某個偶數x,把這n個數中全部等於x的數字除2,Tom想知道把這n個數字全部變成奇數最少需要幾次這樣的操作?
以上十道演算法題你都能搞定嘛?備戰大廠每日刷一道演算法題來提升自己,堅持堅持再堅持,必然會有收獲。為大家整理一份781頁的高分寶典,知識較為全面,可分享給想要學習提升自己的朋友。
領取方式:私信【面試寶典】或點擊右方鏈接: https://shimo.im/docs/QVy8HrQgPYkx9Ddg/ 即可免費領取,喜歡本文不妨關注+轉發支持一下~~