国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频

為什么算法這么難???

共 9507字,需瀏覽 20分鐘

 ·

2022-04-25 18:52

點擊下方卡片,關注“新機器視覺”公眾號

重磅干貨,第一時間送達

作者:劉末鵬

轉自:算法與數(shù)據(jù)結構

鏈接:http://mindhacks.cn/2011/07/10/the-importance-of-knowing-why-part3/

廣大碼農同學們大多都有個共識,認為算法是個硬骨頭,很難啃,悲劇的是啃完了還未必有用——除了面試的時候。實際工程中一般都是用現(xiàn)成的模塊,一般只需了解算法的目的和時空復雜度即可。

不過話說回來,面試的時候面算法,包括面項目中幾乎不大可能用到的算法,其實并不能說是毫無道理的。算法往往是對學習和理解能力的一塊試金石,難的都能掌握,往往容易的事情不在話下。志于高者得于中。反之則不成立。另一方面,雖說教科書算法大多數(shù)都是那些即便用到也是直接拿模塊用的,但不幸的是,我們這群搬磚頭的有時候還非得做些發(fā)明家的事情:要么是得把算法當白盒加以改進以滿足手頭的特定需求;要么干脆就是要發(fā)明輪子。所以,雖說面試的算法本身未必用得到,但熟悉各種算法的人通常更可能熟悉算法的思想,從而更可能具備這里說的兩種能力。

那么,為什么說算法很難呢?這個問題只有兩種可能的原因:

  1. 算法本身就很難。也就是說,算法這個東西對于人類的大腦來說本身就是個困難的事兒。
  2. 講得太爛。

下面會說明,算法之所以被絕大多數(shù)人認為很難,以上兩個原因兼具。

我們說算法難的時候,有兩種情況:一種是學算法難。第二種是設計算法難。對于前者,大多數(shù)人(至少我當年如此)學習算法幾乎是在背算法,就跟背菜譜似的(“Cookbook”是深受廣大碼農喜愛的一類書),然而算法和菜譜的區(qū)別在于,算法包含的細節(jié)復雜度是菜譜的無數(shù)倍,算法的問題描述千變萬化,邏輯過程百轉千回,往往看得人愁腸百結,而相較之下任何菜譜涉及到的基本元素也就那么些(所以程序員肯定都具有成為好廚師的潛力:D)注意,即便你看了算法的證明,某種程度上還是“背”(為什么這么說,后面會詳述)。我自己遇到新算法基本是會看證明的,但是發(fā)現(xiàn)沒多久還是會忘掉,這是死記硬背的標準癥狀。如果你也啃過算法書,我相信很大可能性你會有同感:為什么當時明明懂了,但沒多久就忘掉了呢?為什么當時明明非常理解其證明,但沒過多久想要自己去證明時卻發(fā)現(xiàn)怎么都沒法補上證明中缺失的一環(huán)呢?

初中學習幾何證明的時候,你會不會傻到去背一個定理的證明?不會。你只會背結論。為什么?一方面,因為證明過程包含大量的細節(jié)。另一方面,證明的過程環(huán)環(huán)相扣,往往只需要注意其中關鍵的一兩步,便能夠自行推導出來。算法邏輯描述就好比定理,算法的證明的過程就好比定理的證明過程。但不幸的是,與數(shù)學里面大量簡潔的基本結論不同,算法這個“結論”可不是那么好背的,許多時候,算法本身的邏輯就幾乎包含了與其證明過程等同的信息量,甚至算法邏輯本身就是證明過程(隨便翻開一本經典的算法書,看幾個經典的教科書算法,你會發(fā)現(xiàn)算法邏輯和算法證明的聯(lián)系有多緊密)。于是我們又回到剛才那個問題:你會去背數(shù)學證明么?既然沒人會傻到去背整個證明,又為什么要生硬地去背算法呢?

那么,不背就不背,去理解算法的證明如何?理解了算法的證明過程,便更有可能記住算法的邏輯細節(jié),理解記憶嘛。然而,仍然不幸的是,絕大多數(shù)算法書在這方面做的實在糟糕,證明倒是給全了,邏輯也倒是挺嚴謹?shù)模墒撬坪鯖]有作者能真正還原算法發(fā)明者本身如何得到算法以及算法證明的思維過程,按理說,證明的過程應該反映了這個思維過程,但是在下文關于霍夫曼編碼的例子中你會看到,其實飽受贊譽的CLRS和《Algorithms》不僅沒能還原這個過程,反而掩蓋了這個過程。

必須說明的是,沒有哪位作者是故意這樣做的,但任何人在講解一個自己已經理解了的東西的時候,往往會無意識地對自己的講解進行“線性化”,例如證明題,如果你回憶一下高中做平面幾何證明題的經歷,就會意識到,其實證明的過程是一個充滿了試錯,聯(lián)想,反推,特例,修改問題條件,窮舉等等一干“非線性”思維的,混亂不堪的過程,而并不像寫在課本上那樣——引理1,引理2,定理1,定理2,一口氣直到最終結論。這樣的證明過程也許容易理解,但絕對不容易記憶。過幾天你就會忘記其中一個或幾個引理,其中的一步或幾步關鍵的手法,然后當你想要回過頭來自己試著去證明的時候,就會發(fā)現(xiàn)卡在某個關鍵的地方,為什么會這樣?因為證明當中并沒有告訴你為什么作者當時會想到證明算法需要那么一個引理或手法,所以,雖說看完證明之后,對算法這個結論而言你是知其所以然了,但對于算法的證明過程你卻還沒知其所以然。在我們大腦的記憶系統(tǒng)當中,新的知識必須要和既有的知識建立聯(lián)系,才容易被回憶起來(《如何有效地學習與記憶》),聯(lián)系越多,越容易回憶,而一個天外飛仙似地引理,和我們既有的知識沒有半毛錢聯(lián)系,沒娘的孩子沒人疼,自然容易被遺忘。(為什么還原思維過程如此困難呢?我曾經在知其所以然(一)里詳述)

正因為絕大多數(shù)算法書上悲劇的算法證明過程,很多人發(fā)現(xiàn)證明本身也不好記,于是寧可選擇直接記結論。當年我在數(shù)學系,考試會考證明過程,但似乎計算機系的考試考算法證明過程就是荒謬的?作為“工程”性質的程序設計,似乎更注重使用和結果。但是如果是你需要在項目中自己設計一個算法呢?這種時候最起碼需要做的就是證明算法的正確性吧。我們面試的時候往往都會遇到一些算法設計問題,我總是會讓應聘者去證明算法的正確性,因為即便是一個“看上去”正確的算法,真正需要證明起來往往發(fā)現(xiàn)并不是那么容易。

所以說,絕大多數(shù)算法書在作為培養(yǎng)算法設計者的角度來說是失敗的,比數(shù)學教育更失敗。大多數(shù)人學完了初中平面幾何都會做證明題(數(shù)學書不會要求你記住幾何所有的定理),但很多人看完了一本算法書還是一團漿糊,不會證明一些起碼的算法,我們背了一坨又一坨結論,非但這些結論許多根本用不上,就連用上的那些也不會證明。為什么會出現(xiàn)這樣的差異?因為數(shù)學教育的理想目的是為了讓你成為能夠發(fā)現(xiàn)新定理的科學家,而碼農系的算法教育的目的卻更現(xiàn)實,是為了讓你成為能夠使用算法做事情的工程師。然而,事情真的如此簡單么?如果真是這樣的話干脆連算法結論都不要背了,只要知道算法做的是什么事情,時空復雜度各是多少即可。

如果說以上提到的算法難度(講解和記憶的難度)屬于Accidental Complexity的話,算法的另一個難處便是Essential Complexity了:算法設計。還是拿數(shù)學證明來類比(如果你看過《Introduction to Algorithms:A Creative Approach》就知道算法和數(shù)學證明是多么類似。),與單單只需證明相比,設計算法的難處在于,定理和證明都需要你去探索,尤其是前者——你需要去自行發(fā)現(xiàn)關鍵的那(幾)個定理,跟證明已知結論相比(已經確定知道結論是正確的了,你只需要用邏輯來連接結論和條件),這件事情的復雜度往往又難上一個數(shù)量級。

一個有趣的事實是,算法的探索過程往往蘊含算法的證明過程,理想的算法書應該通過還原算法的探索過程,從而讓讀者不僅能夠自行推導出證明過程,同時還能夠具備探索新算法的能力。之所以這么說,皆因為我是個懶人,懶人總夢想學點東西能夠實現(xiàn)以下兩個目的:

  1. 一勞永逸:程序員都知道“一次編寫到處運行”的好處,多省事啊。學了就忘,忘了又得學,翻來覆去浪費生命。為什么不能看了一遍就再也不會忘掉呢?到底是教的不好,還是學得不好?
  2. 事半功倍:事實上,程序員不僅講究一次編寫到處運行,更講究“一次編寫到處使用”(也就是俗稱的“復用”)。如果學一個算法所得到的經驗可以到處使用,學一當十,推而廣之,時間的利用效率便會大大提高。究竟怎樣學習,才能夠使得經驗的外推(extrapolate)效率達到最大呢?

想要做到這兩點就必須盡量從知識樹的“根節(jié)點”入手,雖然這是一個美夢,例如數(shù)學界尋找“根節(jié)點”的美夢由來已久(《跟波利亞學解題》的“一點歷史”小節(jié)),但哥德爾一個證明就讓美夢成了泡影(《永恒的金色對角線》));但是,這并不阻止我們去尋找更高層的節(jié)點——更具普適性的解題原則和方法。所以,理想的算法書或者算法講解應該是從最具一般性的思維法則開始,順理成章地推導出算法,這個過程應該盡量還原一個”普通人“思考的過程,而不是讓人看了之后覺得”這怎么可能想到呢?

以本文上篇提到的霍夫曼編碼為例,第一遍看霍夫曼編碼的時候是在本科,只看了算法描述,覺得挺直觀的,過了兩年,忘了,因為不知道為什么要把兩個節(jié)點的頻率加在一起看做單個節(jié)點——一件事情不知道“為什么”就會記不牢,知道了“為什么”的話便給這件事情提供了必然性。不知道“為什么”這件事情便可此可彼,我們的大腦對于可此可彼的事情經常會弄混,它更容易記住有理有據(jù)的事情從信息論的角度來說,一件必然的事情概率為1,信息量為0,而一件可此可彼的事情信息量則是大于0的)。第二遍看是在工作之后,終于知道要看證明了,拿出著名的《Algorithms》來看,邊看邊點頭,覺得講得真好,一看就理解了為什么要那樣來構造最優(yōu)編碼樹??墒菦]多久,又給忘了!這次忘了倒不是忘了要把兩個節(jié)點的頻率加起來算一個,而是忘了為什么要這么做,因為當時沒有弄清霍夫曼為什么能夠想到為什么應該那樣來構造最優(yōu)編碼樹。結果只知其一不知其二。

必須說明的是,如果只關心算法的結論(即算法邏輯),那么理解算法的證明就夠了,光背算法邏輯難記住,理解了證明會容易記憶得多。但如果也想不忘算法的證明,那么不僅要理解證明,還要理解證明背后的思維,也就是為什么背后的為什么。后者一般很難在書和資料上找到,唯有自己多加揣摩。為什么要費這個神?只要不會忘記結論不就結了嗎?取決于你想做什么,如果你想真正弄清算法設計背后的思想,不去揣摩算法原作者是怎么想出來的是不行的。

回到霍夫曼編碼問題,我們首先看一看《Algorithms》上是怎么講的:

首先它給出了一棵編碼樹的cost function:

cost of tree = Σ freq(i) * depth(i)

這個cost function很直白,就是把編碼的定義復述了一遍。但是接下來就說了:

There is another way to write this cost function that is very helpful.?Although we are only given frequencies for the leaves, we can define the frequency of any internal node to be the sum of the frequencies of its descendant leaves; this is, after all, the number of times the internal node is visited during encoding or decoding…

接著就按照這個思路把cost function轉換了一下:

The cost of a tree is the sum of the frequencies of all leaves and internal nodes, except the root.

然后就開始得出算法邏輯了:

The?first formulation?of the cost function tells us that the?two symbols with the smallest frequencies must be at the bottom of the optimal tree, as children of the lowest internal node (this internal node has two children since the tree is full). Otherwise, swapping these two symbols with whatever is lowest in the tree would improve the encoding.

This suggests that we start constructing the tree greedily: find the two symbols with the smallest frequencies, say i and j, and make them children of a new node, which then has frequency fi + fj. To keep the notation simple, let’s just assume these are f1 and f2. By the?second formulation?of the cost function, any tree in which f1 and f2 are sibling-leaves has cost f1 + f2 plus the cost for a tree with n – 1 leaves of frequencies (f1 + f2), f3, f4, .., fn.?The latter problem is just a smaller version of the one we started with.

讀到這里我想大多數(shù)人有兩種反應:

  1. 覺得理所當然。
  2. 覺得恍然大悟。

因為我當時也是這么覺得的??墒呛髞懋斘野l(fā)現(xiàn)自己無法從頭證明一遍的時候,我知道肯定是理解的不夠深刻。如果理解的夠深刻,那么基本上是不會忘掉的。

如果看完霍夫曼編碼這樣一個簡短證明你覺得順理成章,一切都挺顯然,那就壞了,即便是看上去最基本的性質也往往實際上沒那么顯然。“逢山開路,遇水架橋”在我們今天看來是無比顯然的事實,但是試想在沒有橋的遠古時代,一個原始人走到一條湍急的河流前,他會怎么想,他又能有什么法子呢?這是個他從來沒有遇見過的問題。如果后來有一天,他路過另外一條小溪,看到小溪上有一截被閃電劈斷的枯樹,于是他踏著樹干走過了小溪,并意識到“樹橫過河面”可以達到“過河”這個目的,這就將條件和目的建立了直接的聯(lián)系(事實上,是自然界展示了這個聯(lián)系,我們的原始人只是記住了這個聯(lián)系)。后來他又路過那條河流,他尋思如何達到“過河”這個目的的時候,忽然意識到在他的記憶中已經遇到過需要達成同樣目的的時候了,那個時候的條件是“樹橫過河面”,于是問題便歸結為如何滿足這個“樹橫過河面”的條件,而后一個問題就簡單多了。(事實上波利亞在他的著作《How to Solve it》中舉的正是這么個例子)

為什么那么多的算法書,就看不到有一本講得好的?因為我們求解問題過程中的思維步驟太容易被自己當作“顯然”的了,但除了我們天生就會的認知模式(聯(lián)系,類比),沒有什么是應該覺得顯然的,試錯是我們天生就會的思維法則么?是的,但是可供嘗試的方案究竟又是怎么來的呢?就拿上面的例子來說,一個從沒有見過枯樹干架在小溪上的原始人,怎么知道用樹架橋是一種可選的方案呢?俗話說巧婦難為無米之炊啊。我們大腦的神經系統(tǒng)會的是將目的和條件聯(lián)系起來,第一次原始人遇到小溪過不去,大腦中留下了一個未實現(xiàn)的目的,后來見到小溪上的樹干,忽然意識到樹干是實現(xiàn)這個目的的條件,兩者便聯(lián)系起來了,因此問題就規(guī)約為如何架樹干了。

回到《Algorithms》中的證明上,這個看似簡潔明了的證明其實有幾處非常不顯然的地方,甚至不嚴謹?shù)牡胤剑@些地方也正是你過段時間之后試圖自己證明的話會發(fā)現(xiàn)卡住的地方:

  1. 作者輕飄飄地就給出了cost function的另外一種關鍵的描述,而對于如何發(fā)現(xiàn)這種描述卻只是一語帶過:"There is another way to write this cost function that is very helpful..?we can define the frequency of any internal node to be the sum of the frequencies of its descendant leaves“這其實就是我常常痛恨的“我們考慮…”,這里作者其實就是在說”讓我們考慮下面這樣一種奇妙的轉換“,可是怎么來的卻不說。但必須承認,《Algorithms》的作者還是算厚道的,因為后面他又稍微解釋了一下:“this is, after all, the number of times the internal node is visited during encoding or decoding…”這個解釋就有點讓人恍然大悟了,但是千萬別忘了,這種恍然大悟是一種錯覺,你還是沒明白為什么他會想到這一點。這就像是作者對你說“仔細觀察問題條件,我們容易發(fā)現(xiàn)這樣一種奇妙的性質..”,怎么個“仔細”法?憑什么我自己“觀察”半天就是發(fā)現(xiàn)不了呢?霍夫曼本人難道也是死死盯著問題“觀察”了一學期然后就“發(fā)現(xiàn)”了么?我們有理由相信霍夫曼肯定嘗試了各種各樣的方法,作出了各種各樣的努力,否則當年Shannon都沒搞定的這個問題花了他一學期,難道他在這個學期里面大腦就一片空白(或者所有的嘗試全都是完全不相干的徒勞),然后到學期末尾忽然“靈光一現(xiàn)”嗎?
  2. 如果“仔細觀察”:),我們會發(fā)現(xiàn)兩個cost function表達中frequency的概念有微妙的差異,在第一個cost function中,只有葉子節(jié)點有frequency,而這個frequency必須和葉子節(jié)點的深度相乘。而在第二個cost function中,內部節(jié)點也具有了frequency,可是所有節(jié)點的“frequency”忽然全都不跟深度相乘了。frequency的不同含義令人困惑。
  3. 作者提到:第一個cost function告訴我們頻率最低的兩個節(jié)點必然處于最優(yōu)編碼樹的底端,作為最低內部節(jié)點的兩個子節(jié)點。這是一個不嚴謹?shù)恼f法,從前文給出的條件和性質,只能推導出編碼樹的最底層必然能找到頻率最低的兩個節(jié)點,但它們未必一定要是兄弟節(jié)點,如果樹的最底層不止能容納兩個節(jié)點的話它們就可以有不同的父節(jié)點。“我們不妨考慮”這樣一個例子:對A,B,C,D四個字母進行編碼,假設它們的頻率分別是1, 1, 2, 2。這個時候我們可以構造如下圖所示的兩棵樹,兩棵樹的cost都是12,都是最優(yōu)的。但其中一棵樹中,兩個頻率最低的節(jié)點并非兄弟。

為什么要提到上面這幾點不顯然和不嚴謹?shù)牡胤?,因為只要當你看到算法書上出現(xiàn)不顯然和不嚴謹?shù)牡胤?,基本上就意味著作者其實跳過了關鍵的思維步驟。

不幸的是《Algorithms》這本書里面講霍夫曼編碼已經算是講的好的了,如果你翻開著名的CLRS,看一看當中是怎么證明的,你就知道我說的什么意思了。有時候這些證明是如此的企圖追求formal和嚴謹,一上來就定義符號一大摞,讓人看了就想吐。

說了這么多,有沒有可能把霍夫曼編碼講的更好呢?前面說過,霍夫曼編碼我記了又忘,忘了又記,好幾次了,有一次終于煩了,心想如果要自己去證明,會怎么去證,那個時候我已經忘了《Algorithms》里面怎么講的了。所以我得從頭來起,首先,對于算法問題,有一個一般性原則是,先看一看解空間的構成。尤其是對于搜索問題(最優(yōu)化問題可以看做搜索問題的一個特例),這一點尤其重要?;舴蚵幋a的可能的編碼樹是有窮的,如果窮舉所有的編碼樹,然后找到那棵代價最小的,這種方法至少是可行的,有了可行的方法(即便是窮舉)至少讓我們內心感到踏實。

接下來便是提高搜尋效率的問題。而提高搜尋效率的關鍵(同樣也是一個一般性原則),便是盡量去尋找問題條件能夠推導出來的性質,****然后利用這些性質去避免不必要的搜尋,只要你學過二分搜索就應該理解這個一般性原則:二分搜索的效率之所以高于“窮搜”(O(n)),便是因為它利用了問題中的性質(有序)來避免了不必要的搜尋。有時候這個性質甚至可以直接將時間降為O(1),例如在一個有序數(shù)組中尋找出現(xiàn)次數(shù)大于n/2的數(shù)(假設該數(shù)存在),利用“該數(shù)一定出現(xiàn)在數(shù)組正中間”這個性質,我們直接就避免了所有的計算。

不過,話雖如此,有時候這些性質并不是那么“顯然”的,需要對問題進行深入的折騰才能有可能發(fā)現(xiàn)。第三個一般原則:如果你要搜尋的元素是某個滿足特定條件的元素(例如尋找最優(yōu)解的時候,“最優(yōu)”的定義就是這個“特定條件”),那么可以“倒過來推”(數(shù)學證明常用手法,結論當條件使),即假設你已經找到了你要找的元素,那么能得出哪些結論,每一個結論都是最優(yōu)解的一個必要條件,而每一個必要條件都能夠幫助你避免不必要的搜尋,因為你只要發(fā)現(xiàn)某個候選解不滿足某個必要條件,就可以立即將其丟棄,前面提到的尋找出現(xiàn)次數(shù)大于n/2的例子是一個極端情況,我們得出的必要條件導致我們可以直接丟棄除中點元素之外的一切其他元素,再例如如果有人叫你尋找有序數(shù)組中最小元素,你會毫不猶豫地把該數(shù)組頭尾元素中較小的那個給他,因為你知道“如果那個最小元素存在,那么它必然位于頭尾”——這個必要條件直接允許你丟棄掉n-2個候選解。

回到霍夫曼編碼問題,按照這個原則,我們會去假設已經得到了最優(yōu)編碼樹,那么我們能夠發(fā)現(xiàn)關于它的什么性質呢?這里又要提到另一個適用于很多最優(yōu)化問題的原則(前面提到的原則適用于一般性搜索問題),所謂最優(yōu)解,就是說比其他所有解都要更好,雖然這句話聽上去像是廢話,但是它的一個直接推論——比與它鄰近的所有候選解都要好——就是一個非常有用的,不是廢話的性質了。學過微積分的都知道,光滑函數(shù)的最值點必然是大(?。┯谄溧徲騼鹊乃悬c的,然后再根據(jù)這個就自然推出該點的一階導數(shù)(切線斜率)必然為0的性質,這個性質(必要條件)讓我們直接省掉了去整個區(qū)間內搜索的麻煩,從而可以直接鎖定有限幾個候選解。那么,既然我們說最優(yōu)霍夫曼樹一定比它“附近”的樹更好,我們就想看看,怎么來找到它附近的樹。我們知道要從一個點到它附近,往往是對這個點進行一些調整,例如N+1是到達附近的另一個整數(shù)?;舴蚵鼧涫且豢脴?,所以對這棵樹的所有的一次“改動”(或“折騰”)都能夠到達與它的“改動”距離為1的點(是不是想起“編輯距離”這個概念),怎么改動呢?最符合直覺的(雖然并不是唯一的)改動便是把葉子節(jié)點進行互換。

于是我們得到一個重要的推論:

  • 在最優(yōu)霍夫曼樹中,無論互換哪兩個葉子節(jié)點,得到的樹都變得更“差”。(嚴格來說是不會變得更“好”,因為最優(yōu)樹未必唯一)

這個性質看上去有點像廢話,值得費這么多事么?值得。因為雖然前文說了很多,但都是大多數(shù)人大腦里面既有的,一般性的法則,前面說過,如果我們能夠從我們已經掌握的一般法則出發(fā)來推導出問題的解,那么記憶負擔是最小的,因為這里面用到的所有法則我們都很清楚,也知道怎么一步步往下走。

上面這個性質究竟意味著什么呢?如果你假設這兩個葉子節(jié)點的頻率為f1和f2,深度為d1和d2,互換它們的時候,其他葉子節(jié)點的cost保持不變,令為常量C,那么互換前總cost為C+f1d1+f2d2,互換后為C+f1d2+f2d1,既然互換之后的樹一定更”差“那么就是說f1d1+f2d2 < f1d2 + f2d1,簡單變換一下就得到結論:f1(d1-d2)f2,如果d1>d2,那么f1必然葉子節(jié)點的深度越高,頻率必須越低,否則就不可能是最優(yōu)霍夫曼樹。那么,之前我們覺得不那么顯然的結論便呼之欲出了:頻率最低的葉子節(jié)點必然位于樹的最底層,頻率最高的葉子節(jié)點必然位于樹的最高層。

有了這個結論之后,我們便能夠對最優(yōu)霍夫曼樹的構建走出確定性的一步,即,將頻率最低的兩個葉子節(jié)點放在最底層。別小看這一步,這一步已經排除了大量的可能性。這里,我們容易一開始天真地覺得最底層只有這兩個葉子節(jié)點,于是它們擁有共同父節(jié)點,這樣一來霍夫曼樹的整個拼圖便已經拼好了一個小小的角落。

然后我們會發(fā)現(xiàn),要是它們不是兄弟怎么辦呢?這里提到另一個一般原則——歸約。不是兄弟的情況能否歸約為是兄弟的情況?反正我們要求的是一個最優(yōu)解,而不是所有的最優(yōu)解,我們只需證明,如果當這兩個最低頻率的葉子不是兄弟的時候的確存在著某棵最優(yōu)霍夫曼樹,那么通過交換它們各自的兄弟,從而讓這兩個葉子團聚之后,修改后的樹仍然是最優(yōu)的就可以了。事實情況也的確如此,證明非常直接——既然這里涉及到的所有4個節(jié)點都在最底層同一個高度上,那么互相交換的時候不會改變他們任何一個人的深度值,所以總cost不會改變。

但是接下來我們犯了難,整個樹的一個小小的櫻桃狀的局部是確定下來了,接下來怎么辦呢?一個最自然的思路就是考慮第三小的葉子,因為前面說了,元素頻率越低就越位于樹的底部嘛。第三小的葉子有兩種可能的歸屬,一是跟最小的兩個葉子同樣位于最底層(這不會違反我們前面得到的推論),這個時候第三小的葉子的兄弟葉子肯定是第四小的葉子,如下圖:

另一種歸屬就是往上一層去(注意,一旦第三小的葉子往上去了一層,那么剩下的所有葉子都必須至少在這個層以上),往上一層去了之后,它的兄弟是誰呢?不妨將它和剛才第一第二葉子的父節(jié)點結為兄弟(前面證明過,同層之前節(jié)點互換不會改變編碼的cost),如下圖:


可是現(xiàn)在問題出現(xiàn)了:雖然第一步構建(最小的兩個葉子)是確定的,但是到了第二步擺在我們面前的就有兩個選擇了,到底選擇哪個呢?一個辦法就是把兩種選擇都記下來,然后繼續(xù)往下走。可是別小看兩種選擇,接下去每一步都有兩種選擇的話就變成指數(shù)復雜度了。所以現(xiàn)在我們便有了動機回頭看一看,看問題中是否有什么沒有發(fā)現(xiàn)的性質能夠幫助我們再排除掉其中一個選擇。理想情況下如果每一步都是必然的,確定的,那么N步我們就可以構建出整棵樹,這是我們希望看到的,抱著這個良好的愿望,我們仔細觀察上面兩種構型,一個自然而然的問題是:這兩種構型都有潛質成為最優(yōu)解嗎?如果我們能夠證明其中一種構型不能成為最優(yōu)解那該多好?就省事多了嘛。這里引入另一個一般性的解題法則:特例。我們的大腦喜歡具體的東西,在特例中折騰和觀察會方便的多

上面這個{1, 2, 3, 4}的例子就是個很好的特例,如圖(注:圖中節(jié)點旁的數(shù)字一概為頻率值,而非編號):

多加折騰一番也許我們不難發(fā)現(xiàn),如果將1,2及其父節(jié)點跟葉子4進行交換(注意:交換的時候1,2也被一同帶走了,因為反正1,2兩個節(jié)點已確定是好兄弟永遠不會分家了,折騰的時候只能作為一個整體移動,所以這里也可以說是交換子樹),那么樹的編碼將會變得更優(yōu),因為這樣一次交換會將1和2的深度+1,意味著整棵樹的代價+3,而同時會將葉子4的深度-1,也就是說整棵樹的代價-4,總體上整棵樹的代價就是+3-4=-1(注意,在計算的時候我們只需考慮被交換的局部,因為樹的其他部分的代價保持不變)。如下圖:

這個交換啟發(fā)了我們,其實前面一開始說的交換兩個葉子節(jié)點可以推廣為交換內部節(jié)點和葉子節(jié)點,然后很快我們就會意識到其實可以推廣到交換任意兩個節(jié)點。(注意,當我們說交換內部節(jié)點的時候,其實是連同該內部節(jié)點作為局部根節(jié)點的整個子樹都交換過去)于是前面我們的推論就可以推廣為:

  • 在最優(yōu)霍夫曼樹中,無論互換哪兩個節(jié)點,得到的樹都變得更“差”(交換內部節(jié)點則是連同該內部節(jié)點作為局部根的子樹一同帶走)

這個推論很容易理解,只不過是多增加了一種“編輯”最優(yōu)霍夫曼樹的方法罷了(記住最優(yōu)霍夫曼樹無論怎么“編輯”都不會變得更“好”,包括“交換子樹”這種“編輯”),我們前面沒有想到這種“編輯”方法是因為它不那么顯然,而且當時我們已經想到一種最直接的“編輯”方法了,即交換葉子,就容易順著那個思路一直走下去,直到我們發(fā)現(xiàn)必須尋找新的性質,才回過頭來看看有沒有其他法子。

當然,并不排除一開始就想到這種推廣的可能性,問題求解的過程并不是這么線性的,如果我們習慣了推而廣之的思維,也許一下就能想到這個推廣來。類似的,也不排除從另一種思路出發(fā)想到這種推廣的可能性。所以這里只是可能的思維軌跡中的一種,重點在于其中并沒有某處忽然出現(xiàn)一個不知從哪里冒出來的,神啟一般的結論。

剛才提到,構造最優(yōu)樹的第二步是考慮第三小的葉子,但也有另一種常見的思維:考慮到第一步(即選取頻率最小的兩個葉子)所做的事情是從N個葉子中選擇兩個黏在一起作為兄弟,那么也許對于一些人來說自然而然的第二步就是試圖繼續(xù)選取兩個節(jié)點黏在一起作為兄弟(注意這里不僅可以選擇葉子,也可以選擇已經生成的內部節(jié)點),然后依次類推來拼完整棵樹。按照這一思路,第二步的選項仍然還是集中在第三小的葉子上,因為這個選擇要么是讓第三第四小的葉子結拜為兄弟,要么是讓最小兩個葉子的父節(jié)點和第三小的葉子結拜。

回到剛才我們的推論:在最優(yōu)霍夫曼樹中,無論互換哪兩個節(jié)點,得到的樹都變得更“差”(交換內部節(jié)點則是連同該內部節(jié)點作為局部根的子樹一同帶走) 。根據(jù)這個推論我們容易計算出,在最優(yōu)霍夫曼樹當中,兩個內部節(jié)點n1和n2,如果n1比n2更深,那么n1下面的所有葉子的頻率之和必然要小于n2下面所有葉子的頻率之和。如果交換的是一個內部節(jié)點和一個葉子節(jié)點,則道理是類似的。這個性質的證明和上面的類似,就不贅述了。

這個性質暗示了一個重要的推廣結論:如果我們把每個內部節(jié)點的所有葉子的頻率之和標在它旁邊,那么整棵樹的每個節(jié)點便都有了一個數(shù)值,這個數(shù)值遵循統(tǒng)一的規(guī)律:即越往深層越小。這就意味著,我們剛才的二選一困境有辦法了!當我們將最小的兩個葉子f1和f2合并的時候,生成了一個新的節(jié)點M,這個節(jié)點有一個數(shù)字(為兩個葉子的頻率之和f1+f2),根據(jù)上面的推論,這個數(shù)字f1+f2跟所有頻率一同,遵循最小的在最底層的原則,所以我們下一步必須在剩下的那些互相之間關系待確定的節(jié)點(葉子節(jié)點和內部節(jié)點)之中,即{(f1 + f2), f3, f4}里面選擇最小的兩個數(shù)字結合成兄弟(由于f1和f2這兩個節(jié)點已經鐵板釘釘結為整體了,所以從集合里面可以看做移除)。到這里,我們就發(fā)現(xiàn)遞歸已經出現(xiàn)了,接下去的過程對于絕大多數(shù)人應該就真的很顯然了。

以上的解釋,比《Algorithms》更簡短嗎?顯然不是。反而要長得多(其實真正的思維過程比這要更長,因為中間還會涉及各種不成功的嘗試)。但是它比《Algorithms》當中的版本更不容易被忘記,因為其中關鍵的思維拐點并不是毫無來由的,而是從你已經熟知的,或者說雖然不知道,但容易理解的一般性解題法則出發(fā)自然推導出來的,所以你基本上不需要記憶什么東西,因為你需要記的已經在你腦海中了。

在上面的證明過程中,還有一個不像看上去那么顯然的事情:在我們尋找最優(yōu)霍夫曼樹的時候,我們曾經試圖去比較假想的最優(yōu)樹和它的“臨近”的樹,從而去探索最優(yōu)樹的性質。但是,究竟什么是臨近的樹?在前面的講解中,我們說如果交換A和B這兩個葉子節(jié)點,便得到一顆不同的樹,可以看做和原樹的“編輯距離”為1的樹。但是,真的這么顯然么?難道除了交換葉子的位置,就沒有其他辦法去“折騰”這棵樹了?后來我們看到,可以交換子樹而不僅僅是葉子,而交換子樹讓我們得到了至關重要的推論。此外,如果不是交換,而是像AVL樹那樣“旋轉”呢?說到底,二叉樹是一個離散的東西,并不像連續(xù)值那樣,天生就有“距離”這個概念,如果我們離散而孤立地去看待所有的樹,那么沒有什么臨近不臨近的,臨近本是一個距離的概念,除非我們定義樹和樹之間的距離函數(shù),才能說臨近與否,而距離函數(shù)怎么定義才是“顯然”的呢?

還有,其實以上只是試圖給出最優(yōu)霍夫曼樹的證明的一個更自然的過程,而當年霍夫曼面臨這個問題的時候根本還沒有人想到要用二叉樹呢!更不要說在二叉樹的前提之下進行證明了。根據(jù)wikipedia的介紹,霍夫曼同學(當年還在讀Ph.D,所以的確是“同學”,而這個問題是坑爹的導師Robert M. Fano給他們作為大作業(yè)的,F(xiàn)ano自己和Shannon合作給出了一個suboptimal的編碼方案,為得不到optimal的方案而寢食難安,情急之下便死馬當活馬醫(yī)扔給他的學生們了)當年為這個問題憔悴了一個學期,最后就快到deadline的時候“忽然”想到二叉樹這個等價模型,然后在這個模型下三下五除二就搞定了一篇流芳千古的論文,超越了其導師。

最后說兩個有趣的現(xiàn)象:也許很多人會覺得,越是大師來寫入門教科書越是好,其實很多時候并非如此,尤其是在算法設計和數(shù)學領域,往往越是在其中浸淫久了越是難寫出貼近初學者的書,因為大量對初學者來說一點都不顯然的事情在他看來已經是“不假思索”了,成了他的內隱記憶,尤其是當他想要和你解釋一個復雜的東西的時候你就會發(fā)現(xiàn)他會常常邏輯跳躍,滿嘴跑術語,根本沒有意識到別人對有些術語和隱含的邏輯根本沒有像他那樣的理解。

最適合將一個東西講給別人聽的時候并不是等懂了很多年以后,而是剛剛弄懂的時候,這個時候從不懂到懂的差別記憶還非常鮮明,能夠清清楚楚地記得到底是哪些關鍵的地方是最折磨人的,也最能夠站在不懂者的角度來思考問題。像波利亞這樣,成了大師還能夠站在不懂者角度去換位思考的,可以說是鳳毛麟角。所以說前Amazon CAO(首席算法官)的《Introduction to Algorithms: a Creative Approach》絕對是本罕見的好算法書)

知其所以然(一)里面曾經提到,要弄清來龍去脈,最好去看看原始作者是怎么想的,可是正如上文所說,即便是最初的發(fā)明者,在講述的時候也會有意無意地“線性化”,我就去查看了霍夫曼最初的論文,那叫一個費解,不信你可以自己看看(PDF)。

可以歸約為搜索算法的問題(非常多)一般來說相對還是有一些頭緒的,因為搜索空間一般還比較容易界定,難點在于要從問題的條件中推導出用于節(jié)省搜索的性質。而策略設計問題則完全是另一個世界,因為策略的設計空間貌似是可列無窮的,常常讓人感覺無從下手,摸不著頭緒,許多讓人撓頭的智力問題就有這個特點(例如著名的100個囚徒和1個燈泡的房間就讓很多人有這種感覺),策略設計問題也有一些較通用的法則,以后再說。

怎么才能在學算法的時候學到背后的東西呢?有以下幾點很重要:

  1. 不要覺得每個步驟都很顯然,每個nontrivial的算法背后都有一段艱辛的探索經歷,覺得顯然的話必然是一種幻覺。Stay foolish,才能發(fā)現(xiàn)某些環(huán)節(jié)其實并不是那么顯然的。
  2. 檢驗是否真正理解的最佳方法就是過一段時間之后,自己試著證明一次。如果真正理解了的話,你的證明便會比較順暢。如果當時沒有真正理解,那么凡是那些你當時覺得顯然但其實不顯然的地方,都會成為你證明里面缺失的環(huán)節(jié)。
  3. 對于一個算法,多尋找各種來源的資料,也許能夠找到一個講的比較深刻的。我在《數(shù)學之美番外篇:快排為什么那么快》和《知其所以然(一)》里面都舉到了這樣的例子。
  4. 多試著去抽象背后的一般性法則,即便后來發(fā)現(xiàn)抽象得是錯的,也比不去抽象要好。抽象是推廣的基礎。只有抽象出更深層的法則,才能讓你事半功倍,觸類旁通,否則一個蘿卜永遠是一個坑。(注意,其實我們的下意識是會進行一定程度的抽象的,例如前面提到的原始人的例子,小溪和小河(或者小溝)細節(jié)上是不同的,但本質上是一樣的,我們的大腦會自動進行這種簡單抽象,提出事物的共性。正因此,即便你不去有意識地總結一般規(guī)律,只要你看的足夠多,練的足夠多,必然就會越來越諳熟。)

最后留個問題:雖然按照上文的方式來構造霍夫曼樹一定能夠得到一個最優(yōu)樹,但是怎么證明一定能得到呢?乍一看這個問題似乎很多余,因為證明很簡單:我們拼裝整棵樹的每一步都沒得選,而且每一步都必然拼湊出最優(yōu)樹的一個小小局部,如果最終還沒有得到最優(yōu)樹的話,只能說最優(yōu)樹是不存在的了,然而最優(yōu)樹是一定存在的,因為所有樹的集合是有窮的,有窮集必有最值,因此證畢。這個證明固然是沒問題的,但它其實是一個間接證明,換句話說,我們在構建樹的過程中的邏輯是這樣的:“之所以我們選擇粘結n1和n2,是因為其他粘法必然違反最優(yōu)樹的兩個性質。所以我們別無選擇?!钡?,這并沒有說,我們選擇了粘結n1和n2,一定就符合了最優(yōu)樹的性質。(也就是說“其他做法都是錯”并不能推出“這種做法必然對”,這就像是你在一大堆豆子當中尋找一個特殊的豆子,你拿起一個,看看不是,扔掉,又拿起一個,還不是,扔掉,排除到最后只剩一個豆子了,假設你又知道這個特殊的豆子必然存在,那么這個時候你根本不用看就知道這個豆子一定就是你要找的)那么,你能否直接證明,拼裝最優(yōu)樹的過程每一步都符合最優(yōu)樹的性質呢?


本文僅做學術分享,如有侵權,請聯(lián)系刪文。

—THE END—
瀏覽 30
點贊
評論
收藏
分享

手機掃一掃分享

分享
舉報
評論
圖片
表情
推薦
點贊
評論
收藏
分享

手機掃一掃分享

分享
舉報

感谢您访问我们的网站,您可能还对以下资源感兴趣:

国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频 亚洲日韩网站| 国产小视频在线播放| 色色五月丁香| 97精品人妻一区| 极品美女扒开粉嫩小泬高潮一| 蜜桃久久99精品久久久酒店| 国产日韩一区| 激情操逼网| 黄色电影网页| 蜜桃免费网站| 中文字幕www一区| 日韩人妻无码一区二区三区中文 | 豆花视频无码| 97人妻精品一区二区三区软件| 亚洲美女网站在线观看| 国产成人综合自拍| h片在线播放| 狼友视频在线播放| 黄片在线免费观看视频| 青青青国产| 97AV视频| 97超碰成人| 日韩午夜在线观看| 亲子乱婬-一级A片| 日本一区二区网站| 一区二区三区四区五区六区高清无吗视频 | 欧美麻豆| 精品国产香蕉| 99精品一区二区三区| 在线免费人成视频| 国产96在线亚洲| 日韩成人一区二区三区| 91ThePorn国产在线观看| 老婆被黑人杂交呻吟视频| 国产白丝视频| 国产精品久久久久久无人区 | 成年人在线播放| 精品视频日韩| 91精品青青草| 先锋影音资源一区| 中文免费高清在线| 撸撸综合网| 久久久人妻无码精品蜜桃| 国产精品怡红院有限公司| 91在线看| 日韩国产在线| www.亚洲天堂| 人人色人人爱| 毛片一区二区三区| 婷婷在线观看视频| 高清无码在线免费| 一本道在线无码| 久久久精品亚洲| 日皮视频在线看| 婷婷精品免费久久| 在线免费观看视频黄| 成人精品免费无码毛片| 久久视频免费在线观看| 成人无码区亚洲AV久久| 国产乱子伦真实精品!| 国产凹凸视频在线观看| 青青草国产在线视频| 91麻豆精品91久久久久同性| www.色欲av| 字幕一区二区久久人妻网站| 丰满人妻一区二区三区视频在线不卡 | 搡BBBB搡BBB搡我瞎了| 天天添天天干| 成片免费观看视频大全| 久久99精品久久久水蜜桃| 第一福利成人AV导航| JULIA超乳JULIA无码| 你懂的网站在线观看| 国产美女一级真毛片酒店| AV在线免费网站| 日韩激情av| 伊人五月天| 色悠悠国产| 欧美亚洲成人在线观看| www黄色在线观看| 国精产品一二三区| 色撸撸在线视频| 抽插影院| 欧美黄色免费在线观看| 青青草成人AV| 一区二区经典| 高清视频无码| 国产久久在线观看| 精品人妻无码一区二区三区四川人| 色噜噜人妻丝袜无码影院| 东方av在线免费观看| 色色五月天视频| 中文字幕亚洲视频在线观看| 黄色激情五月| 77久久| 男人的天堂色婷婷| 国产熟女| 婷婷九九| 成人亚洲AV日韩AV无码| 人妻无码在线视频| 天堂中文字幕在线| 一道本久久| 东京热一区二区| 天天综合久久| 亚洲中文字幕在线观看视频| 人人妻人人澡人人爽久久con | 六月丁香视频| 欧美亚洲激情| 在线免费看av| 久热精品视频| 欧美无人区码suv| 久色视频福利| 91大神在线资源观看无广告| 国精产品一区二区三区在线观看| 91久久久久久久久| 黄色成人大片| 100国产精品人妻无码| 少妇A片| 天天日,天天干,天天操| 特级婬片A片AAA毛片AA做头| 国产精彩视频| 91久久国产综合| 91成人18| 亚洲操逼网| 操你啦无码日韩| 久久久国产精品人人片| 亚洲三级自拍| 国产精品国产三级国产AⅤ| 一级特黄毛片| 无码秘蜜桃吴梦梦| 黄色免费在线观看| 五月婷中文字幕| 久久久久三级片| 黄色日逼| 青青草东路热vv| 亚洲aV影院| 日逼高清视频| 91理论片| 色婷婷在线影院| 国产乱伦对白| 国产成人av在线| 无码视频一区二区| 黄网站在线观看| 91视频美女内射| 亚洲国产区| 人妻操逼视频| 草逼视频免费看| 精品日韩一区二区三区| 日韩中文在线视频| 色五月婷婷中文字幕| 婷婷丁香六月| 中文字幕淫乱视频欧美| AV电影天堂网| 二区三区视频| 中日毛片| 91视频色| 麻豆AV96熟妇人妻| 青草影视久久| 日韩AV免费网站| 国产乱子伦一区二区三| 日韩免费中文字幕A片| 日韩免费看| 欧美精品一二三区| 午夜福利无码视频| 欧美日韩操逼片| 俺去也AV| 2025中文字幕在线| 91污| 肏屄在线视频| 好想被c秘好爽n网址| 五月天婷婷AV| av影音先锋在线| 无码无卡| 免费无人区一码二码乱码怎么办| 成人性生活免费视频| 欧美中文字幕| 欧美操逼大全| 人与禽一级A片一区二区三区| 蜜臀99久久精品久久久懂爱| 一级黄色电影免费看| 黄色精品视频| 国产男女av| 青青国产在线观看| 2014av天堂网| 专业操老外| 中文字幕亚洲有码| 99日韩无码| 97精品超碰一区二区三区| 99reav| 国产精品无码天天爽视频| 日韩欧美三级| 北条麻妃无码精品AV怎么看| 日韩高清无码免费观看| 久久精品999| 五月伊人激情| 国产无码一区| 午夜成人黄色电影| 国产午夜精品一区二区三区牛牛| 精品探花| 麻豆操逼| www.日韩系列| 中文字幕第一页av| 福利三区| 免费黄色在线视频| 北条麻妃无码在线视频| 肉片无遮挡一区二区三区免费观看视频 | 操B视频免费看| AAA三级片| 97成人视频| 国产精品可站18| 一区二区三区在线视频观看| 国产精品啪啪视频| 成人a毛片| 91视频成人版一区二区| 亚洲精品高清视频| 国产色网站| 外国一级片| 中国一级黄色A片| 欧一美一婬一伦一区二区三区| 可以免费看的AV| 97人人爽人人爽人人人| 午夜福利干B在线免费小视频| AV在线大香蕉| 97超级碰| 色搞搞| 俺来了俺去了www色官网| 免费色色网站| 国产日韩欧美一区| 一区二线视频| 欧美成人精品一级| 91人妻人人澡人人爽人人爽 | 三洞齐开Av在线免费观看| 性爱福利导航| 国产2页| 亚洲黄色电影网站| 一区二区高清无码视频| 蜜桃av无码一区三区| 色婷婷色99国产综合精品| 91性爱视频| 青青青国产在线| 国产精品久久久久久久久久久久久| 婷婷操| 久久久国产精品人人片| 黄色国产网站| 亚洲小说区图片区| 国产激倩都市一区二区三区欧美 | 开心五月激情婷婷| 91在线精品无码秘入口苹果 | 欧美v在线| 亚洲一级免费在线观看| 欧美性爱在线播放| 成人无码区免费A片| 黑人内射人妖| 日韩中文字幕专区| 99国产精品免费视频观看8| 蜜桃91精品秘入口| 91精品国产综合久久久久久久| 中文字幕在线免费看线人| 日韩视频在线免费观看| 成人天天爽| 欧美性少妇| 国产一级内射| 三级片AV在线| 国产无套内射在线观看| 99国产视频| 美女人人操| 精品黄色片| 婷婷综合| 精品一区二区免费视频| 无码av中文字幕| 强伦轩人妻一区二区三区最新版本更新内容| 日韩午夜在线观看| 一曲二曲三曲在线观看中文字| 欧美激情伊人久久五月天| 第一福利导航大全| 午夜成人免费视频| 日产久久久| 欧美日韩在线视频免费观看| 91在线无码精品秘入口动作| 黄色视频在线| 一本色综合亚洲精品| 丁香六月婷婷综合| 91亚洲影院| 黄色a片网站| 激情五月婷婷综合| 成人免费无码婬片在线观看免费| 成人精品永久免费视频99久久精品| 青青草在线免费视频| 日韩视频一区二区| 霸道总裁雷总各种姿势白浆爱情岛论坛| 精品久久电影| 欧美一级片| 日本精品视频一区二区| 女人久久久| 开心色播五月| 成年人视频在线免费观看| 蜜臀久久99精品久久久巴士| 在线播放91灌醉迷J高跟美女| 成人av天堂| JlZZJLZZJlZZ亚洲女人17 | 青青草原免费在线视频| AV在线免费观看网站| 亚洲中文字幕播放| 婷婷五月精品| 婷婷五月天丁香| 91久久婷婷亚洲精品成人| 天天综合天天干| 开心色播五月| 国产插穴| 黑人干亚洲人| 熟女人妻ThePorn| 影音先锋成人资源| 欧美国产在线观看| 高清av在线| 亚洲成a人无码| 91草视频| 在线啪| 俺来也在线视频| 少妇精品无码一区二区免费视频| 国产又粗又黄| 女人毛片| 中文字幕精品视频在线| 专区无日本视频高清8| 撸撸综合网| 国产资源在线观看| 国产成人小视频在线观看| 欧美激情无码一区二区三区张丽| 人人操碰成人网| 嫩草久久99www亚洲红桃| 91成人视频在线观看| 国产麻豆传媒| 学生妹毛片| 久久一级A片| 高清无码三级| 久久免费成人电影| 国产色无码网站www色视频| 亚洲天堂在线观看视频网站 | jizz在线视频| 国产又爽又黄免费视频免费| 伊人久久久影视大全| 婷婷五月丁香花| 中文字幕线观看| 可以免费看AV的网站| 亚洲中文无码第一页| 奇米影视77777| 狼友视频在在观看| 91精品成人电影| 91成人在线观看学生和老师| 日本黄色免费在线观看| 波多野结衣黄色视频| 亚洲AV秘无码不卡在线观看| 中文字幕av久久久久久欧洲尺码 | 日本久久播| 91美女网站| 少妇搡BBBB搡BBB搡18禁| 中文字幕免费高清在线观看| 日韩精品一区二区三区在线观看免费| 欧美午夜福利电影| 亚洲操屄| 亚洲欧美一区二区三区在线| 懂色AV无码中字幕一区| 欧美黄色小视频| 9I成人免费版视频| 亚洲51| 少妇搡BBBB搡BBB搡毛片少妇| 毛片一区二区三区| 国产无码AV成在线| 日韩在线视频免费观看| 人人超碰人人| AAAA毛片视频| 免费在线观看黄色片| 国产精品色婷婷99久久精品| 免费一级a| 久久香视频| 91亚洲精品在线| 99国产高清| 91嫩草久久久天美传媒| 欧美日韩国产成人综合| 国产成人精品AV在线观| 97精品欧美91久久久久久久| 亚洲天堂一级片| 神马午夜秋霞不卡| 91人妻日韩人妻无码专区精品| AAA三级片| 黄色A片网址| 91大鸡巴| 俺也来最新色视频| 欧美黄片网站| 少妇bbb搡bbbb搡bbbb| 日韩图片区小说视频区日| 精品国产欧美一区二区三区成人 | 亚洲日韩在线中文字幕| 亚洲免费清高| 中文字幕欧美视频| 调教人妻视频| 美女黄片| 亚洲免费视频一区| 无码乱伦| 青青草原网址| 欧美成人乱码一区二区三区 | 北条麻妃无码中文| 亚洲字幕AV| 中文字幕在线免费观看视频| 色天天干| 小H片在线观看| av网站免费观看| 一级片在线免费看| 爱爱视频免费看| 在线免费观看黄色视频网站| 午夜亚洲国产一区视频网站| 伊人狠狠蜜桃亚洲综合| 国产看色免费| 无码国产精品一区二区免费式直播| 国产丰满乱子伦无码| 色呦呦一欧美| 国产毛片网| 午夜狠狠操| 亚洲高清无码在线| 小明看台湾成人永久免费视频网站| 91牛视频| 中文字幕人成人乱码亚洲电影| 国产乱叫456在线| 91AV在线播放| 99Re66精品免费视频| 天天干网址| 一级免费黄色片| 豆花视频久久| 国产一区二区久久| 国产成人av在线| 久久婷综合| 加勒比DVD手机在线播放观看视频 日韩精品一区二区三区四区蜜桃视频 | 日韩毛片网| 第一福利导航大全| 成人影视亚洲| 亚洲操逼逼| 年轻女教师高潮2| 麻豆一区二区| 站街大龄熟女x| 人人爱人人干人人操| 五月丁香在线视频| 国产综合网站| 成人高清在线| 精品三级片| 国产三级三级三级| 五月丁香中文| 午夜福利成人| 日逼日逼日逼| 一区二区三区四区成人| 日本黄色片| 91老熟女视频| 变态另类av| 久久大香蕉| 久久久成人免费电影| 真人一级片| AV在线观看黄| 人人色在线| 欧美乱伦内射| 欧美性极品少妇精品网站| www.国产在线观看| 人人澡视频| www五月天com| 日韩A片在线观看| 亚洲中文字幕视频在线| 日韩无码一卡二卡| 水果派AV解说| 男女日逼网站| 视频一区中文字幕| 午夜无码鲁丝片午夜精品| 亚洲免费成人网站| 国产又粗又猛又爽又黄91精品| 污视频在线免费| 色综合久久88色综合天天99| 在线激情网站| 99久久久久久久久久| 婷婷丁香六月| 一区二区三区电影| 四虎人妻| 一级性生活视频| 久久久黄片| 九九在线观看视频| 无码另类| footjobvk| 激情性爱五月天| 久久精品无码视频| www.日本黄色| 午夜一级性爱片| 亚洲免费视频播放| 欧美黄色性爱| 日本少妇高潮喷水XXXXXXX| 日逼视频网站| 久草超碰在线| 国产粉嫩在线观看| 成人一区二区电影| 久久亚洲无码| 人人操在线观看| 91porn在线观看| 中文字幕人成人乱| 免费一区二区三区四区| 97人妻在线视频| 亚洲天堂大香蕉| av日韩在线播放| 伊人中文字幕| 亚洲AV成人精品一区二区三区 | 九九r在线精品观看视频| 日韩人妻精品无码制服| 狠狠插狠狠操| 国产黄片在线视频| 亚洲午夜无码精品专区| 嫩草av| 91探花视频在线观看| 欧美日韩在线视频一区| 日韩美女在线视频| 亚洲激情视频| 婷婷成人电影| 亚洲视频免费在线播放| 91三级片网站| 久久久综合网| 日韩黄色视频| 国产精品成人午夜福利| 先锋影音av资源站| 亚洲AV图片| 嫩草99| 秋霞福利| 日本操逼网站| 三级片中文| 天天躁夜夜躁av| 淫香欲色| 开心激情网站| 少妇搡BBBB搡BBBB毛多多| 超碰在线天天干| 9久9久9久9久女女女女| 黄色小视频免费| 中国免费视频高清观看| 成人久久电影| 激情久久婷婷| 麻豆激情视频| 污视频网站免费观看| 黄色电影毛片| 伊人乱伦| 天天爽天天爽| 四虎综合| 中文字幕99页| 亚洲成人无码高清| 91白浆肆意四溢456| 亚洲无码视频观看| 色性网| 天天插一插| 国产在线播放91| 国产美女被爽到高潮免费A片软件| 五月婷婷六月丁香| 广东BBW搡BBBB搡| 日韩三级在线观看| 日韩精品人妻中文字幕有| 亚洲AV图片| 超碰人人干人人操| 久久久久久三级电影| 嫩BBB槡BBBB槡BBB| 国产区精品| 狠狠色狠狠干| 精品动漫3D一区二区三区免费版| 中文亚洲视频| 中文字幕精品一区久久久久| 国产一级a毛一级a毛片视频黑人 | 91三级在线观看| 九色欧美| 女人BBBB| 日韩欧美中文在线观看| 国产在线观看免费成人视频| 欧美日韩国产精品| 亚洲无码视频网站| 国产精品VA| 日韩日韩日韩日韩| 欧美精品黄| 91精品91久久久中77777| 亚洲性夜夜天天天天天天| 99热1| 国产suv精品一区二区6| 大香伊人中文字幕精品| 思思热在线观看视频| 91成人在线电影| 成人无码区亚洲AV久久| XX熟女HD| 偷窥丶亚洲丶熟女| 丁香六月婷婷久久综合| 午夜成人精品视频| 欧美日韩操逼视频| 免费黄色三级片| 超碰成人AV| a片在线观看视频| 免费看污网站| 欧美国产日韩视频| 麻豆传媒av| 欲撸视频| 热热毛片| 免费看a| 四虎国产| 青青操B| 国产成人无码在线| 91丨九色丨老农村| 真人无码| 69成人天堂无码免费| 四虎综合网| 久久久国产AV| 色五月亚洲| 欧美视频A| 91狠狠爱| gogogo高清在线观看免费直播中国| 黄色成人视频在线观看| 蜜臀91| 安徽妇搡BBB搡BBBB户外老太太| 波多野结衣av在线播放| 亚洲国产无码在线| 韩国三级HD久久精品HD| A级片免费| 一色综合| 日韩欧美一区二区在线观看| 在线观看三级| 麻豆午夜福利视频| 97av视频| 久久99精品久久久久| 99久久精品一区二区成人| 2019中文字幕在线免费观看| 翔田千里无码| 久久三级| 毛片网站在线观看| 国产亚洲视频在线观看| 成人国产在线观看| 一本一道AV| 夜夜操网站| 无码一区二区在线观看| 国产色视频一区二区三区QQ号| 一道本无码在线视频| 成人AV一区二区三区| 91无码人妻一区二区成人aⅴ| 51妺嘿嘿在线电影免费观看 | 97精品人人妻人人| 亚洲国产无码在线| 青草视频在线免费观看| 国产69精品久久久久久| 福利逼站| 大香蕉三级| 日韩无码123| 日韩成人无码免费视频| 欧美激情区| 色婷婷播放| 久久成人网豆花视频| 少妇精品久久久久久久久久 | 婷婷色777777| 国产美女自拍| 韩国精品久久久| 亚洲福利视频电影精| 成人av黄色三级片在线观看| 中文字幕AV在线| 久久一区| 99国产视频| 黄色一区在线| 伊人五月在线| 欧美日韩A片欧美日| 亚洲精品成人片在线观看精品字幕| 午夜啪啪网站| 情趣视频网站| 国产精品无码久久久久成人app| 日韩美女做爱| 三级黄片免费看| 精品日韩在线视频| 久久久久久无码精品亚洲日韩麻豆| 成人性生交片无码免费看人| 无码一区二区三区免费看| 丰满大爆乳波霸奶| 影音先锋男人天堂| 亚洲黄色视频在线观看网站| 伊人成人片| 五月天激情四射| 久久久久久黄色| 亚洲男人的天堂网| 亚洲综合精品| 国产色网站| 69成人无码| www.91n| 白嫩外女BBWBBWBBW| 免费操逼视频网站| 黑人无码视频| 激情丁香五月| 国产AV一区二区三区| 天堂资源地址在线| 免费一级黄色毛片| 欧美日韩h| 成人做爰黄级A片免费看土方| 亚洲日韩在线视频播放| 九九99精品视频| gogogo日本免费观看高清电视剧的注意 | 久久精品视频免费观看| 国产熟妇码视频| 三级片在线观看视频| 欧美日韩久久| 不卡无码中文字幕一区| 麻豆AV电影| 日本色影院| 日本白嫩的BBw| 蜜臀久久精品久久久久| 中文字幕北条麻妃在线| 青娱乐精品在线| 99视频精品全部免费看| 欧美午夜三级| 午夜三级福利| 精品国产国产没封| 一区二区高清无码| 亚洲欧美日韩黑料吃瓜在线观看| 欧美视频色| 欧美三级不卡| 亚洲女同在线| 青青草乱伦视频| 亚洲无吗在线观看| 日韩欧美国产视频| 老熟女-ThePorn| 三级黄色视频| 制服.丝袜.亚洲.中文豆花| 国产顶级理伦| 国产精品女人精品久久久天天| 国产av影音| 黄色一级大片在线免费看产| 在线免费观看黄色视频网站 | 伊人成人电影| 国产欧美在线观看| 欧美老女人操逼群| 黄色视频在线| 日韩国产三级| 欧美亚洲日韩在线观看| 久久福利社| 亚州在线视频| 国产丨熟女丨国产熟女视频| 日日撸| 人人操人人干97| 日日夜夜草| 啊啊啊亚洲| 久久综合在线| 澳门四虎影院| 北京熟妇槡BBBB槡BBBB| 中文黄片| 亚洲免费清高| 五月天婷婷色播| 北条麻妃亚洲无码| 欧美日韩精品一区二区三区视频播放 | 影音先锋国产av| 欧美18禁网站| 国产毛片在线看| 国产一级在线观看| 国产三级国产三级国产普通话| 日本欧美成人片AAAA| 边添小泬边狠狠躁视频| 上海熟妇搡BBBB搡BBBB| 天天夜夜人人| 狠狠操在线视频| 柠檬福利第一导航| 国产亚洲综合无码| 99热国品| 五月天丁香网| 无码一二三四| 欧美精品久久久久久久多人混战| 亚洲AV五月天在线| 成人做爰黄级A片免费看土方| 成人精品一区二区三区无码视频 | 91精品人妻少妇无码影院| 蜜桃91精品秘成人取精库| 91精品久久人妻一区二区夜夜夜| 亚洲精品乱码久久久久久按摩观| 日韩无修正| 亚洲天堂在线观看免费视频| 日本无码在线视频| 91丨人妻丨偷拍| 无码一区二区三区四区| 在线视频三区| 99久久婷婷国产综合| 亚洲AV大片| 久久午夜无码鲁丝片午夜精| 亚洲成人av| 成人黄色在线观看视频| 荫蒂添到高潮免费视频| 中文字幕福利视频| 重庆美女揉BBBB搡BBBB| 欧美日韩视频| 成人在线三级| 免费Av在线| 色综合一区二区| 18XXX亚洲HD护士JD| 日韩免费在线观看一区入口| 在线日韩国产| 亚洲电影AV| 日韩中文字幕久久| 91小电影| 中文在线а√天堂8| 美女做爱视频网站| 国产AV在| 色婷婷亚洲精品天天综合| 色色色999| 狠狠干2024| 久久久久久久无码| jiujiuav| 777免费观看成人电影视频| 97在线资源| 老女人网站| 亚洲香蕉在线观看| 91水蜜桃| 中文字幕精品久久久久人妻红杏Ⅰ| 97国产精品手机| 操逼在线播放| 天天操夜夜爽| 爆菊花综合网| 国产九九九九九九| 久久精品国产99精品国产亚洲性色 | 久久亚洲国产| www.zaixianshipin| 成年视频在线观看| 91无码秘蜜桃一区二区三区-百度 精品人妻一区二区三区在线视频不卡 | 日韩操逼一区| 精品国产AV无码一区二区三区| 国产伦子伦一级A片在线| 91美女网站| 精品人妻一区二区三区四区不卡在 | yw尤物在线| 日韩高清无码网站| 国产十八岁在线观看| 国产欧美激情| 亚洲黄色视频免费观看| 亚洲va中文字幕| 操老女人逼| 撸撸综合网| 蜜桃视频网址| 国产91白丝在一线播放| 久久电影无码| 五月天丁香花| 波多野结衣东京热| 免费观看黄色视频| 水多多成人免费A片| 亚洲精品69| 91亚洲成人| 亚洲无码人妻一区| 欧美热热| 毛片A片| 欧美色色影院| 中文字幕日本成人| 久久艹国产| 久久这里有精品| 波多野结衣在线无码视频| 婷婷三级片| 亚洲人妻视频| 无码中文字| 欧美日逼网| 日日撸夜夜撸| 欧美精品在线免费观看| 中文在线字幕免费观看| 婷婷五月花| 亚欧综合在线| 亚洲人操逼视频| 国产伦精品一区二区三区妓女| 国产高清无码免费视频| 日本a在线免费观看| 九色精品| 九九性视频| 久草久热| 国产靠逼| 91麻豆天美传媒在线| 97久久精品| 99久久久久久久| 国产AV无遮挡| 91天天爽| 日韩精品网| 做aAAAAA免费视频| 免费国产三级片| 青青草原AV| 久射精品| 操逼操逼视频| 欧美在线天堂| 91国产精品在线视频| 国产精品秘久久久久久1-~/\v7-/ 囯产精品一区二区三区线一牛影视1 | 狠狠操狠狠撸| 国产欧美在线不卡| 日韩无码链接| 四虎884| 精品九九九九九九| 福利视频一区二区三区| 亚洲一级av| 日韩免费性爱视频| 日本久久综合| 日韩无码网站| 免费一级AAAAA片在线播放| 69国产精品成人无码| 11孩岁女精品A片BBB| 日本电影一区二区| 97人妻在线| 欧美一级成人片| 在线无码中文| 91精品人妻一区二区| 第一福利导航大全| 亚洲国产精品久久| 激情啪啪网站| 日本大香蕉伊人| 国产三级毛片| 无码国产+白浆| 日本免费a片|