999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

求解0-1背包問題的多種算法策略的分析

2023-10-20 15:51:32文曉棠鐘廣玲
現代計算機 2023年15期

陳 艷,文曉棠,鐘廣玲

(廣州華商學院數據科學學院,廣州 510520)

0 引言

0-1 背包問題是一個經典的組合優化問題,它涉及到在一個給定容量的背包中選擇一些物品,使得這些物品的總價值最大。該問題常常被應用于資源分配、物流管理等領域,并且在計算機科學和數學中具有重要的理論價值。本文將采用深入淺出的方式,結合實例詳細介紹如何使用動態規劃、貪心算法以及分支限界法來解決0-1背包問題,并對各種方法的優缺點進行比較。

1 問題概述

0-1 背包問題描述為:有一個容量為C的背包,可以放入背包的物品有n種,每種物品的體積和價值分別為vi和pi。在不超過背包容量的前提下,怎樣選擇放入背包中的物品,以使得放入背包中的物品的價值和最大?需要注意的是,對于每種物品,只有兩種選擇,要么放入背包,要么不放入背包,因此稱為0-1背包問題。

問題的數學模型如下:

輸入:n個物品的集合O,每個物品有兩個屬性vi和pi,分別表示物品的體積和價值;背包容量為C。

輸出:求解一個物品的子集S?O,使得。

2 動態規劃

動態規劃法與分治法類似,其基本思想都是將待求解問題分解成若干個子問題,然后從這些子問題的解得到原問題的解。動態規劃法通過建立狀態轉移方程,也稱遞推式,來反映大問題和子問題之間的依賴關系,通過這種依賴關系來實現子問題的解組合成原問題的解[1]。

用動態規劃法求解的問題一般具有兩個特征:①最優子結構的性質。原問題的解可以通過子問題的解組合而成,這樣的性質就稱為最優子結構性質[2]。比如在分治法中,歸并排序通過合并算法將兩個子問題的解合并為原問題的解,因此分治法具有最優子結構的性質。比如在動態規劃法中,求最大子數組問題的解是通過D[i]=D[i- 1]+X[i]或者D[i]=X[i]得到,即通過狀態轉移方程得到,因此動態規劃法也具有最優子結構的性質。動態規劃法的最優子結構的性質體現在狀態轉移方程上,問題的最優子結構性質的分析也是該問題是否能用動態規劃求解的關鍵步驟。②重疊子問題的性質。一個大問題,通過分解后得到的子問題,通常存在公共的子問題,這樣的性質稱為重疊子問題的性質。比如斐波那契數列,求第5項需要通過第4 項和第3 項來得到,求第4 項需要通過第3 項和第2 項來得到,則求第5 項和求第4項都包含求第3項這個公共的子問題,故斐波那契數列具有重疊子問題性質。解決求解重疊子問題的效率問題,是動態規劃算法的關鍵。

動態規劃算法的基本思想的核心,就是解決重疊子問題重復計算的問題[3]。動態規劃算法對分解出的每個子問題只計算一次,不管該子問題是否以后被用到,都將其結果保存到一張表中,從而避免每次遇到各個子問題時重新計算答案。基于這樣的一種思想,相對于遞歸算法而言,動態規劃法大大提高了問題的求解效率。應用動態規劃算法的求解過程,實際上就是填表的過程,把相關表填完,問題的最優解就在表中的某個位置,可能是最后一個位置,也可能是中間的某個位置。動態規劃算法求解問題的順序去掉了遞歸算法的自頂向下分解的過程,只保留了自底向上不斷求解子問題的過程,每個子問題的解都對應地存儲在表中的某個單元格中。所以,動態規劃法求解問題的基本步驟就是圍繞著填什么表,怎么填,填完之后怎么在表中找最優解的過程來分析的。

動態規劃法求解問題的基本步驟分為四步:

第一步:子問題的定義和表示。

通過分析問題的結構特點來定義子問題,找到合適的狀態來描述子問題,并通過定義的狀態來表示原問題。主要任務是確定用來存放子問題解的表的樣式,如一維表還是二維表或者三維表,等等,并確定原問題的表示。

第二步:狀態轉移方程(遞推式)的建立。

分析子問題之間解的依賴關系,以此來建立狀態轉移方程。因此此步的關鍵問題是證明問題的最優子結構性質,問題的最優子結構性質得以證明,則問題解之間的依賴關系也就隨之得到了。動態規劃法求解問題,最關鍵的就是建立狀態轉移方程,這一步驟解決了,后面的問題水到渠成。

第三步:填表順序的確定。

在狀態轉移方程中,根據問題和子問題之間的依賴關系來確定填表順序,即子問題的求解順序。具體的確定方法可以將相關的子問題在表中的位置標識出來,通過待求解的子問題和求解依賴的子問題在表中的位置關系來分析填表的順序。有的問題填表的順序為從左到右,有的為從右到左,有的從上到下,不同的問題根據其特征不同填表順序也不同。填表順序確定后,就能在此步確定原問題的解在表中的位置,可能填的最后一個元素即為原問題的解,也可能解存在于表中的某一個需要通過一定策略得到的位置,比如表中元素的最大值即為原問題的解。

第四步:最優方案的追蹤。

在第三步進行的填表過程中,通常是需要通過一定的決策來填表,比如選最大值或最小值等。做的決策是最優解對應的最優方案獲取的直接依據,因此,在對子問題的解填表的過程中,可以順便把相應的決策記錄下來,如也用一張表來記錄。根據決策表,采用回溯的方式來尋找最優解對應的最優方案。這一步,根據問題的具體要求,如果只需要求解最優解,不需要求出最優方案,則可以省略。

動態規劃是解決0-1 背包問題的經典算法,它通過構建問題的狀態轉移方程(遞推式),從而求解出最優解。采用二維數組DP 來存儲每個子問題的最優解,其中第i行j列DP[i,j] 表示:對前i個物品,容量為j的背包能夠裝下的最大價值。對于每個物品,考慮放或者不放兩種情況,即可推導出狀態轉移方程,由此推算出問題的最優解。按照此思路,根據動態規劃算法求解問題的基本步驟,設計如下:

(1)子問題的定義和表示。

原問題的子問題定義為:對前i個物品,當背包容量為j時,在不超過背包容量限制的前提下,使得放入背包中的物品的價值最大。此問題和原問題是性質相同,規模變小的相同問題,故為原問題的子問題。對子問題,表示如下:

定義DP[i,j]:在前i個商品中做出選擇,背包容量為j時放入背包中商品的最大總價值。

(2)狀態轉移方程(遞推式)的建立。

狀態轉移方程意味著,在考慮第i個物品時,我們可以選擇放或者不放,分別求兩種情況的最優解,然后再看哪種情況求得的價值最大,則其就是問題的解。如果選擇放第i個物品,那么此時背包的容量就減少了vi,并且能夠獲得的價值增加了pi,此時只要把前i-1 個物品在背包容量為j-vi時的最優解求出來,加上i件物品的價值貢獻,就可得到此情況的最優解,即求DP[i- 1,j-vi]+pi。如果選擇不放第i個物品,那么此時背包的容量依然是j,則此問題轉換為求解前i-1 個物品,背包容量為j時的子問題的最優解問題,即求DP[i- 1,j]。兩種情況取大值即為原問題的解。

根據遞推關系的分析,DP 實際上是一張二維表,表規模為n+ 1行、C+ 1列。第0行表示沒有物品的情況,第0 列表示沒有背包的情況,這兩類情況能放入背包中的物品的總價值和都為0,故可以都初始化為0,如圖1所示。

圖1 DP表的樣式

(3)填表順序的確定。

根據上述分析,求解0-1背包問題實際上就是要完成上述DP 的計算問題。根據狀態轉移方程,在表中分別表示出DP[i,j]和求解它依賴的兩個子問題DP[i- 1,j]和DP[i- 1,j-vi],如圖2所示。

圖2 子問題之間的位置關系

根據圖中子問題間的位置關系可知,要求DP[i,j],則需先求出其上一行的DP[i- 1,j]和DP[i- 1,j-vi],由此不難看出,DP 的整個計算順序為從左到右,從上到下,一行一行地填,且最后一個元素DP[n,C]為原問題的解,如圖3所示。

圖3 原問題的解的位置

(4)最優方案的追蹤。

根據狀態轉移方程可知,求DP[i,j]的過程實際上就是對i號物品選還是不選進行決策的過程,因此在填每個DP[i,j]時,把做出的決策記錄下來,可以依據此決策推出最優解對應的最優方案,見下式:

在Dec 表中倒敘判斷是否選擇商品,如圖4所示。

圖4 Dec表

假設有個背包,容量C= 7,有5 件可選擇的物品,各物品的價值和體積見表1。

表1 物品清單

上述問題最優解為22,最優方案為S={5,4,1},即選擇5 號、4 號和1 號物品放入背包中,此時放入背包中的物品的總體積為7。

按上述分析過程得到本例子的DP 表如圖5所示,從DP表中可知原問題的最優解為22。

圖5 案例DP

最優方案的追蹤過程如圖6所示,得到最優解22對應的最優方案為{5,4,1},即選擇5號、4號和1號商品放入背包中。

圖6 最優方案的追蹤

根據上述分析,設計算法DPknapsack(n,p,v,C)的偽代碼如下:

該算法用兩層循環來實現,循環的規模分別為n和C,故算法的復雜度為O(n*C)。

3 回溯法

回溯法是一種基于深度優先搜索的算法,也稱為回溯搜索法,它是一種搜索的方式,常用于解決組合問題、子集問題、棋盤問題等。其核心思想是通過試錯的搜索方式,逐步構造可行解,并在發現不符合要求的情況下回溯到上一步,重新選擇其他可能的路徑[4]。

通常,回溯法可以使用遞歸函數來實現,但它不是單純的遞歸算法。遞歸函數中包含兩個關鍵部分:一個是生成可行解的過程,即對當前狀態進行擴展;另一個是判斷該狀態是否滿足條件,對應分支是否有進行下去的意義,即剪枝的過程[5]。具體步驟如下:

第一步:定義解空間,用樹來表示解空間。解空間表示所有可行的解的集合。定義解空間,并確定搜索解空間的結構樹,即解空間樹。

第二步:定義約束函數和限界函數。定義約束函數和限界函數的目的是通過這兩種策略避免無效搜索,提高回溯法的搜索效率。約束函數的作用是在擴展結點處減去不滿足約束的子樹,限界函數的作用是剪去得不到最優解的子樹。因此這兩類函數都稱為剪枝函數。

第三步:以深度優先的方式搜索解空間樹。在搜索的過程中通過兩個剪枝函數來避免無效搜索。對解空間樹的每個節點上的搜索具體過程為:當前節點為活結點,同時也成為當前的擴展結點。在當前擴展結點處,搜索向縱深方向擴展出一個新的結點來,并判斷約束條件或限界函數。如果此處不滿足約束條件或者限界函數,則剪枝,即此結點稱為死結點。此時,應往回移動(回溯)至最近的活結點處,并使這個結點成為當前的擴展結點。回溯法以這種方式遞歸地在解空間樹中搜索,直至找到所要求的解或解空間樹中已無活結點為止。

假設有個背包,容量C= 30,有3件可選擇的物品,各物品的價值和體積以及按照單位體積的價值比排好序,見表2。

表2 物品清單

按照上述求解步驟,對此問題的求解過程如下:

(1)定義解空間,用樹來表示解空間。

該問題解空間為{(0,0,0),(0,1,0),(0,0,1),(1,0,0),(0,1,1),(1,0,1),(1,1,0),(1,1,1)},解空間樹如圖7所示。

圖7 解空間樹

(2)定義約束函數和限界函數。

定義約束函數c(i)=cv(i-1)+vi,cv(i-1)表示前i-1個物品中已經放入背包的物品的體積,則c(i)表示當前放入背包中的物品的體積,任何結點上必須滿足cv(i)≤C的約束條件,否則剪枝。

定義限界函數B(i)=cp(i-1)+r(i),cp(i-1)表示已經放入背包中物品的價值,r(i)表示背包剩余容量可以存放的理想最大價值。r(i)可以通過貪心法的思想來求解,將物品按價值體積比的降序排序,優先選擇比值高的物品,直到把整個背包撐滿的理想狀態可以存放的最大價值,則B(i)表示當前狀態下將背包撐滿能放入物品的理想最大價值,如果用bp表示當前記錄的最大組合的價值和,則如果B(i)≤bp,此分支沒有繼續下去的意義,故而剪枝。

(3)以深度優先的方式搜索解空間樹。

根據上述的分析,定義cv表示當前放入背包中的物品的體積,cp表示當前放入背包中物品的價值和,bp表示當前記錄的最優組合的價值和,r表示還未做出選擇的剩余物品的價值和。得到問題的帶剪枝的以深度優先方式搜索的解空間樹,如圖8所示。

圖8 帶剪枝的解空間樹

從圖8 可知,第3 層結點(1, 1, 0)、結點(0,0,0)和第4層結點(1,0,1)都因為約束條件或者限界函數執行了剪枝,算法在執行的過程中,執行的分支數量大幅下降,由此算法的復雜度也得到大幅提升。完整的搜索過程為A→B→E→K→C→F→L。

算法BTknapsack(n,p,v,C)偽代碼如下:

算法backtrack(i,cv,cp)偽代碼如下:

回溯部分通過調用backtrack(i,cv,cp)函數來實現。該函數包含三個參數:當前考慮到第幾個物品(即狀態),已選擇的物品總體積和總價值。如果所有物品都已經考慮過,或者當前已選物品體積達到背包容量,則更新最大價值并返回。如果cp+r小于等于bp,說明把背包撐滿的理想狀態能裝入的最大價值已經不大于當前的最大價值,則該分支沒有繼續下去的必要,因此直接返回,即剪枝。否則,對于第i個物品,可以有兩種選擇:選或不選。如果不選第i個物品,則直接遞歸調用backtrack(i+1,cv,cp);如果選第i個物品,則需要判斷當前已選物品總體積是否小于等于背包容量,如果是,則遞歸調用backtrack(i+1,cv+v[i],cp+p[i])。

4 分支限界法

分支限界法是一種求解最優化問題的常用算法,它基于將問題空間劃分為一個個子集,每個子集對應一個可行解,通過比較不同可行解的目標函數值來逐步縮小搜索范圍,最終找到全局最優解。分支限界法和回溯法類似,求解策略都是在問題的解空間上搜索問題解。但分支限界法與回溯法有著不同的求解目標。回溯法的求解目標是在約束條件的限制下,把解空間樹中滿足條件的所有解都找出來,而分支限界法的求解目標則是在約束條件的限制下,找到滿足條件的一個解,即在某種意義下的一個最優解[5]。

由于求解目標的差異,導致分支限界法與回溯法在解空間樹中搜索問題解的方式也不相同。由上文可知回溯法以深度優先的方式搜索解空間樹,而分支限界法則以廣度優先或以最小耗費優先的方式搜索解空間樹。按照廣度優先的搜索策略,分支限界法的搜索策略,每個活結點只有一次機會成為擴展結點,一旦成為擴展結點,就一次性生成其所有的兒子結點(分支)。這些兒子結點中,不可行解或者非最優解的兒子結點被舍棄(剪枝),其余兒子結點加入活結點表(隊列)中,然后再從當前的活結點表中選擇下一個擴展結點,并重復上述結點擴展過程。這個過程一直持續到找到所需的解或活結點表為空時為止。為了有效地選擇下一擴展結點,以加速搜索的進程,在每一活結點處,計算一個函數值(限界函數),并根據函數值從當前活結點表中選擇一個最有利的結點作為擴展結點,使搜索朝著解空間上有最優解的分支推進,以便盡快地找出一個最優解。這種方法稱為分支限界法。

從活結點表中選擇下一擴展結點的不同策略導致不同的分支限界法。最常見的有以下兩種方式。

(1)隊列式(FIFO)分支限界法。

隊列式分支限界法將活結點表組織成一個隊列,并按隊列的先進先出原則選取下一個結點為當前擴展結點。

(2)優先隊列式分支限界法。

優先隊列式的分支限界法將活結點表組織成一個優先隊列,并按優先隊列中規定的結點優先級選取優先級最高的下一個結點為當前擴展結點。

優先隊列中的結點優先級常用一個表示該結點耗費或收益的函數來表示,即如果擴展該結點,通過該函數來計算會帶來多大的效益,以此來決定結點的優先級。函數值的確定通常采用堆來實現。

和回溯法類似,分支限界法求解問題的基本步驟如下:

第一步:定義解空間,用樹來表示解空間。解空間表示所有可行的解的集合,集合中一定包含問題的最優解。定義解空間,并確定搜索解空間的結構樹,即解空間樹。

第二步:定義約束函數和限界函數,統稱為剪枝函數。定義約束函數和限界函數的目的是通過這兩種策略來決定在擴展中哪些兒子節點被舍棄(剪枝),不被舍棄的兒子結點加入到隊列中。

第三步:以廣度優先的方式搜索解空間樹。在搜索的過程中和回溯法一樣,通過兩個剪枝函數來避免無效搜索。如果采用隊列式(FIFO)分支限界法,則不被舍棄的兒子結點依次加入隊列,以先進先出的順序對結點進行擴展。如果采用優先隊列式分支限界法,則按照某種策略求解每個兒子結點的優先級對隊列進行排序,每次擴展隊列中優先級最高的結點。

分支限界法也是一種常見的求解0-1背包問題的算法,它通過將問題分解成子問題并逐步減小搜索空間來尋找最優解。具體地,可以先將所有物品按照單位重量的價值從大到小排序,然后從排好序的物品列表中依次選擇物品放入背包中。同時,維護一個上界和一個下界,以便剪枝減少搜索空間。繼續以表2中的物品清單為例來分析分支限界法求解0-1背包問題,具體步驟如下:

(1)定義解空間,用樹來表示解空間。

此步驟和回溯法完全相同,此處不再贅述。

(2)定義約束函數和限界函數,統稱為剪枝函數。

此步驟和回溯法完全相同,此處不再贅述。

(3)以廣度優先的方式搜索解空間樹。

定義約束函數c(i)=cv(i-1)+vi,定義限界函數B(i)=cp(i-1)+r(i),兩個函數的定義同回溯法,此處不再贅述。限界函數B(i)的意義除了作為剪枝的依據,B(i)的值還作為結點的優先級的值來決定在優先隊列中是否下一次擴展該結點。如果優先級最高,則擴展此結點,反之以優先級的降序存放在優先隊列中待擴展。通過隊列中結點優先級的設置,可以使得搜索的過程朝著目標快速地逼近,簡化了搜索過程,提高了效率。搜索過程的總方式是廣度優先,考慮B(i)的值為優先級作為下一次擴展結點選取的依據,因此,搜索的過程是基于廣度優先但又不完全是傳統意義的廣度優先搜索法。在圖8 中,優先隊列的分支限界法的搜索過程為A→B→C→E→K→F→L。優先隊列的搜索算法,以從當前節點出發最理想的價值為優先級,使得搜索過程能以最快的速度找到最優解,后面結點的擴展因當前的bp值而發生剪枝,從而提升了算法的執行效率。

根據上述分析,設計算法BBknapsack(n,p,v,C)的偽代碼如下:

通過wt<=C約束條件來實現左枝的剪枝,通過限界up>=bestp來實現右枝的剪枝,每個活結點擴展出來的新結點,根據其優先級up,加入到優先隊列中,每次都選擇優先級最高的結點來進行擴展。

5 算法對比實驗

為了比較三種算法的性能,先用簡單的測試數據,令v={2,3,4,5},p={3,4,5,6}分別對C的值取8(最差情況)、取10(平均情況)和取12(最好情況)進行測試,測試結果表明,三種情況執行效率最高的為回溯法,執行時間基本都在0.03 ms 左右,其次是動態規劃法,執行時間在0.3 ms 左右,性能最差的為分支限界法,執行時間在1.5 ms左右。

為了比較大數據下三種算法的性能,分兩類數據進行測試。一類固定n的大小為100,隨機生成100 個物品,每個物品的體積和價值在1~100 之間取值。對于從30~3000000 不同規模的背包容量,分別使用動態規劃法、回溯法和分支限界法來求解,并計算求解時間,實驗結果見表3。另一類固定背包容量的大小為300,隨機生成n的規模為10~1000000 個物品,每個物品的體積和價值在1~100 之間取值。對于不同規模的物品數量,分別用三種算法求解,并計算求解時間,實驗結果見表4。

表3 物品規模固定實驗結果

表4 背包容量固定實驗結果

對上述兩表生成對比圖形,如圖9 和圖10所示。

圖9 不同背包容量性能比較

圖10 不同物品數量性能比較

結合上述圖和表可以看出,三種算法在求解0-1 背包問題時的性能差異較大。具體來說,回溯法比較穩定,不論物品數量和背包容量發生什么變化,其求解問題的時間基本都在3 ms 以內?;厮莘ǖ膱绦袝r間對背包容量的增加不敏感,對物品數量的增加執行時間有小幅上漲。而動態規劃法,固定物品的數量,不同的背包容量,求解問題的時間從0.54 ms 增長到1542 ms,隨著背包容量的增加,當增加到30000時,算法性能直線下降。固定背包容量大小,不同的物品數量規模,動態規劃的性能表現和固定物品數量類似。原因是動態規劃的實質是填規模為n×C的表,算法執行時間和填表的規模有關。分支限界法的性能介于動態規劃和回溯法之間,和回溯法類似,算法對背包容量的變化不敏感,對物品數量的增加敏感,且和回溯法相比,隨著物品數量的增加,分支限界法的執行時間增長明顯。分支限界法的性能和回溯法比不具優勢的主要原因在于應用優先隊列存儲結點,優先隊列的應用有較大的時間消耗。

總體而言,性能上回溯法具有絕對優勢,當問題規模(物品數量和背包容量)較小時,動態規劃優于分支限界;當問題規模較大時,分支限界優勢明顯。究其原因,回溯法和分支限界法雖然本質是窮舉,但當物品數量或背包容量很大時,通過剪枝的優化,大大減少了子問題執行的數量,算法性能得到極大提高。但反觀動態規劃算法,不論問題規模和背包容量多大,都要將其所有子問題求解,當問題規模小、背包容量小時,子問題的數量不大,整個問題求解時間短,但當問題規模和背包容量達到一定規模時,待求解的子問題數量也同時達到相當的規模,求解這些子問題所需要的時間自然也就具有較大規模。因此,在實際應用中,對規模較小的問題,推薦使用動態規劃法,當問題規模較大或者背包容量較大時,則推薦使用回溯法來求解。當采用有效的排序算法和優先隊列時,分支限界法也是一個不錯的選擇。

6 結語

綜上所述,動態規劃、回溯法和分支限界法是三種常見的求解0-1背包問題的方法。動態規劃算法具有良好的理論保證,當問題規模不大時可以在較短的時間內求解出全局最優解?;厮莘ê头种藿绶ㄊ且环N基于搜索的高效算法,因其本質是窮舉,且是帶剪枝的優化窮舉,故可以在合理的時間內找到全局最優解。在實際應用中,我們需要根據問題特點和求解需求來靈活選擇算法,并盡可能利用并行化和分布式計算等技術來提高求解效率。

主站蜘蛛池模板: 91九色视频网| 青青青视频免费一区二区| 这里只有精品国产| 97久久超碰极品视觉盛宴| 国产专区综合另类日韩一区| 日本欧美中文字幕精品亚洲| 2020国产在线视精品在| 在线观看国产小视频| 久久6免费视频| 色综合网址| 亚洲人成网站18禁动漫无码| 欧美在线精品怡红院| 国产亚洲美日韩AV中文字幕无码成人| 97国产成人无码精品久久久| www.狠狠| 欧洲日本亚洲中文字幕| 91国内在线视频| 永久免费AⅤ无码网站在线观看| 日本一本在线视频| 国产又爽又黄无遮挡免费观看| 欧美一道本| 99热亚洲精品6码| 日韩欧美视频第一区在线观看| 国产女人在线| 成年av福利永久免费观看| 日韩毛片免费| 亚洲欧美自拍一区| 国产99在线| 日韩av电影一区二区三区四区| 在线看国产精品| 九九免费观看全部免费视频| 国产一线在线| www.精品视频| 国产在线精彩视频二区| 草逼视频国产| 国产亚洲精品97在线观看| 欧美精品综合视频一区二区| 最新国产麻豆aⅴ精品无| 国产综合色在线视频播放线视| 毛片大全免费观看| 亚洲精品视频免费看| 国产成人一二三| a毛片在线免费观看| 在线观看视频99| 色呦呦手机在线精品| 国产一区二区三区免费观看| 67194在线午夜亚洲 | 尤物成AV人片在线观看| 国产精品久线在线观看| 东京热av无码电影一区二区| 在线观看国产黄色| 福利姬国产精品一区在线| 国产欧美日韩在线一区| 国产成人综合网在线观看| 国产人人干| 亚洲无码在线午夜电影| 欧美精品一二三区| 国产哺乳奶水91在线播放| 欧美成人综合在线| 国产女人水多毛片18| 成·人免费午夜无码视频在线观看| 国产欧美精品一区二区| 538国产视频| 国产人成在线视频| www.亚洲一区二区三区| 亚洲香蕉久久| 中文字幕亚洲精品2页| 一级毛片免费播放视频| 国产嫖妓91东北老熟女久久一| 国产精品护士| 国产va在线观看免费| 精品无码一区二区三区在线视频| 特级毛片免费视频| 日韩精品亚洲精品第一页| 日韩无码真实干出血视频| 亚洲国产成人在线| 97在线国产视频| 欧美成人免费一区在线播放| 亚洲国产欧美目韩成人综合| 国产精品亚洲一区二区三区在线观看| 色婷婷亚洲综合五月| 欧美日韩一区二区在线免费观看 |