青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

  C++博客 :: 首頁 :: 新隨筆 ::  ::  :: 管理

pku1077

Posted on 2010-08-21 19:57 Kevin_Zhang 閱讀(212) 評論(0)  編輯 收藏 引用 所屬分類: 搜索
http://blog.163.com/sentimental_man/blog/static/73001618200881405851176/
簡介:
         所謂八數碼問題是指這樣一種游戲:將分別標有數字1,2,3,…,8的八塊正方形數碼牌任意地放在一塊3×3的數碼盤上。放牌時要求不能重疊。于是,在3×3的數碼盤上出現了一個空格。現在要求按照每次只能將與空格相鄰的數碼牌與空格交換的原則,將任意擺放的數碼盤逐步擺成某種特殊的排列。如下圖表示了一個具體的八數碼問題求解。

問題分析:
         首先,八數碼問題包括一個初始狀態(START) 和目標狀態(END),所謂解八數碼問題就是在兩個狀態間尋找一系列可過渡狀態(START->STATE1->STATE2->...->END)。這個狀態是否存在就是我們要解決的第一個問題:

Q1:每一個狀態及每一次操作的表示方法?
         有許多表示方法,比如一個3*3的八數碼盤可以壓縮成一個int值表示,但不適用于15 puzzle或大于8 的puzzle問題。如果對空間要求很高,應該還可以再壓縮。本文采用一個int表示的方法。
         表示方法如下:由于int的表示范圍大于1e9,所以我們取一個int的低9位,為了方便尋找空格的位置,int的個位我們用來放空格的位置(1-9)。而前8位,按照行從上到下,列從左到右的順序依次記錄對應位置上的數字。例如:
         可以表示成 2 3 1 5 8 4 6 7 5 ,個位的5表示空格在第5位,前八位數按順序記錄。坐標轉換公式為:
     num(壓縮后的int) x y(求x行y列,1記起)1e(n)為 1乘10的n次
     int temp=(x-1)*3+y
     if   temp > num%10 then return (num / 1e(9-temp+1)) %10
     else return (num / 1e(9-temp) )%10

     為了方便本文介紹,取目標狀態為:1 2 3 4 5 6 7 8 9 即-->

         操作本文用 u r d l 分別表示 空格的向上 向右 向下向左四個操作。比如,在簡介中的圖包括兩步操作 l d ,可能與平時玩這類游戲的習慣不符合,但這是為了和ACM例題相統一。

     對應地,每種操作引起的狀態變化如下:
     r :num值++              l :num值--
     u :有點復雜
     int t0 = 9-num%10 + 1
     int t1 = num / 1e(t0)
     int t2 = t1%1000
     t1= t1- t2 + (t2 % 100) * 10 + t2 / 100
     t1*= 1e(t0)
     return (t1 + ( (num % t0) - 3))
     d :return前面同u操作, return返回   (t1 + ( (num % t0) + 3))

Q2:判斷是否存在中間狀態使START 到達END?
         用組合數學的方法可以快速地進行判斷,例如SOJ 2061題 2360題中都是關于此類的問題。但八數碼的判斷方法比他們簡單多了。

         本文用的方法是計算排列的逆序數值,以2 3 1 5 8 4 6 7 5 為例子,5表示的是空格,不計算,那么求23158467 的逆序值為
         0 + 0 + 2 (1<2 1<3 ) + 0 + 0 + 1 ( 4<5 ) + 1 ( 6<8 ) + 1 ( 7<8 ) = 5
目標狀態1 2 3 4 5 6 7 8 9 的逆序自然就是0。

兩個狀態之間是否可達,可以通過計算兩者的逆序值,若兩者奇偶性相同則可達,不然兩個狀態不可達。

簡單證明一下:
         l 和 r 操作,不會影響狀態的逆序值,因為只會改變個位數(空格的位置)。
         u和d操作是使某個位置的數字 右/左移兩位。由于數字序列的每一次移動會使逆序值奇偶性改變,所以             移動兩次后奇偶性不變。
         所以四個操作均不會影響序列的奇偶性。

Q3:如何尋找一系列的中間狀態及遇到的問題?
         要尋找這一系列中間狀態的方法是搜索,但搜索很容易遇到時間和空間上的問題。以下就是搜索的基本原理:

         由1 3 7 2 4 6 8 5 2 狀態可以衍生三個狀態,假如選擇了1 2 3 7 4 6 8 5 5 ,則又衍生三個狀態,繼續按某策略進行選擇,一直到衍生出的新狀態為目標狀態END 為止。
容易看出,這樣的搜索類似于從樹根開始向莖再向葉搜索目標葉子一樣的樹型狀。由于其規模的不斷擴大,其葉子也愈加茂密,最終的規模會大到無法控制。這樣在空間上會大大加大搜索難度,在時間上也要消耗許多。

在普通搜索中遇到以下問題:
        a   搜索中易出現循環,即訪問某一個狀態后又來訪問該狀態。
        b 搜索路徑不佳便無法得到較好的中間狀態集(即中間狀態集的元素數量過大)。
        c 搜索過程中訪問了過多的無用狀態,這些狀態對最后的結果無幫助。


         以上三個問題中,a為致命問題,應該它可能導致程序死循環;b和c是非致命的,但若不處理好可能導致性能急劇下降。


Q4:怎樣避免重復訪問一個狀態?
         最直接的方法是記錄每一個狀態訪問否,然后再衍生狀態時不衍生那些已經訪問的狀態了。思想是,給每個狀態標記一個flag,若該狀態flag = true則不衍生,若為false則衍生并修改flag為true。
在某些算法描述里,稱有兩個鏈表,一個為活鏈表(待訪問),一個為死鏈表(訪問完)。每一次衍生狀態時,先判斷它是否已在兩個鏈表中,若存在,則不衍生;若不存在,將其放入活鏈表。對于被衍生的那個狀態,放入死鏈表。

         為了記錄每一個狀態是否被訪問過,我們需要有足夠的空間。八數碼問題一共有9!,這個數字并不是很大,但迎面而來的另一個問題是我們如何快速訪問這些狀態,如果是單純用鏈表的話,那么在規模相當大,查找的狀態數目十分多的時候就不能快速找到狀態,其復雜度為O(n),為了解決這個問題,本文將采用哈希函數的方法,使復雜度減為O(1)。
         這里的哈希函數是用能對許多全排列問題適用的方法。取n!為基數,狀態第n位的逆序值為哈希值第n位數。對于空格,取其(9-位置)再乘以8!。例如,1 3 7 2 4 6 8 5 8 的哈希值等于:
0*0! + 0*1! + 0*2! + 2*3! + 1*4! + 1*5! + 0*6! + 3*7! + (9-8)*8! = 55596 <9!

         具體的原因可以去查查一些數學書,其中1 2 3 4 5 6 7 8 9 的哈希值是0 最小,8 7 6 5 4 3 2 1 0 的哈希值是(9!-1)最大,而其他值都在0 到(9!-1) 中,且均唯一。

Q5:如何使搜索只求得最佳的解?
         普通的搜索稱為DFS(深度優先搜索)。除了DFS,還有BFS,從概念上講,兩者只是在擴展時的方向不同,DFS向深擴張,而BFS向廣擴張。在八數碼問題的解集樹中,樹的深度就表示了從初始態到目標態的步數,DFS一味向深,所以很容易找出深度較大的解。
         BFS可以保證解的深度最少,因為在未將同一深度的狀態全部訪問完前,BFS不會去訪問更深的狀態,因此比較適合八數碼問題,至少能解決求最佳解的難題。

         但是BFS和DFS一樣不能解決問題c ,因為每個狀態都需要擴張,所以廣搜很容易使待搜狀態的數目膨脹。最終影響效率。


Q6:該如何減少因廣搜所擴張的與目標狀態及解無關的狀態?
         前面所說的都是從START狀態向END狀態搜索,那么,將END狀態與START狀態倒一下,其實會有另一條搜索路徑(Q8策略三討論),但簡單的交換END與START并不能縮小狀態膨脹的規模。我們可以將正向與反向的搜索結合起來,這就是雙向廣度搜索。
         雙向廣搜是指同時從START和END兩端搜,當某一端所要訪問的一個狀態是被另一端訪問過的時候,即找到解,搜索結束。它的好處是可以避免廣搜后期狀態的膨脹。
采用雙向廣度搜索可以將空間和時間節省一半!


Q7:決定一個快的檢索策略?
         雙向廣搜能大大減少時間和空間,但在有的情況下我們并不需要空間的節省,比如在Q4中已經決定了我們需要使用的空間是9!,所以不需要節省。這樣我們可以把重點放在時間的縮短上。
         啟發式搜索是在路徑搜索問題中很實用的搜索方式,通過設計一個好的啟發式函數來計算狀態的優先級,優先考慮優先級高的狀態,可以提早搜索到達目標態的時間。A*是一種啟發式搜索的,他的啟發式函數f ' ()=g' () + h' () 能夠應用到八數碼問題中來。
         g' () ----- 從起始狀態到當前狀態的實際代價g*()的估計值,g' () >= g*()
         h' () ----- 從當前狀態到目標狀態的實際代價h*()的估計值,h' () <= h*()
注意兩個限制條件:
         (1)h' () <= h*()   (2)任意狀態的f '()值必須大于其父狀態的f '()值,即f '()單調遞增。

         其中,g' () 是搜索的深度, h' () 則是一個估計函數,用以估計當前態到目標態可能的步數。解八數碼問題時一般有兩種估計函數。比較簡單的是difference ( Status a,   Status b ), 其返回值是a 和b狀態各位置上數字不同的次數。另一種比較經典的是曼哈頓距離    manhattan ( Status a, Status b ),其返回的是各個數字從a的位置到b的位置的距離(見例子)。

例如狀態 1 3 7 2 4 6 8 5 2 和狀態 1 2 3 4 5 6 7 8 9 的difference 是5(不含空格)。而他的manhattan 距離是:
1 (7d一次) + 1 (2u一次) + 2 (4l兩次) + 3 (6r兩次u一次) + 2 (5u一次l一次) = 9
單個數字的manhattan應該小于5,因為對角的距離才4,若大于4則說明計算有誤。

         無論是difference還是manhattan,估計為越小越接近END,所以優先級高。
         在計算difference和manhattan時,推薦都將空格忽略,因為在difference中空格可有可無,對整體搜索影響不大。

         本文后面的實現將使用manhattan 不計空格的方法。其實,每移動一步,不計空格,相當于移動一個數字。如果每次移動都是完美的,即把一個數字歸位,那么START態到END態的距離就是manhattan。反過來說,manhattan是START到END態的至少走的步數。
         回到f '()=g' ()+ h' (),其實廣度搜索是h' ()=0的一種啟發式搜索的特例,而深度搜索是    f ' ()=0 的一般搜索。h' ()對于優化搜索速度有很重要的作用。

Q8:能否進一步優化檢索策略?
         答案是肯定的。
         A*搜索策略的優劣就是看h' ()的決定好壞。前面列舉了兩個h' ()的函數,但光有這兩個是不夠的。經過實驗分析,在f '()中,g '()決定的是START態到END態中求得的解距離最優解的距離。 而h' () 能影響搜索的速度。
         所以優化的第一條策略是,放大h' (),比如,讓h '()= 10* manhattan(),那么f '()= g' ()+10*manhattan(),可能提高搜索速度。可惜的是所得的解將不再會是最優的了。
         為什么放大h'()能加快搜索速度,我們可以想象一下,h'()描述的是本狀態到END態的估計距離,估計距離越短自然快一點到達END態。而 g' ()描述的是目前的深度,放大h' ()的目的是盡量忽略深度的因素,是一種帶策略的深搜,自然速度會比廣搜和深搜都快,而因為減少考慮了深度因素,所以離最優解就越來越遠了。關于h' ()放大多少,是很有趣的問題,有興趣可以做些實驗試試。

         第二條是更新待檢查的狀態,由于A*搜索會需要一個待檢查的序列。首先,在Q4已經提到用哈希避免重復訪問同一狀態。而在待檢查隊列中的狀態是未完成擴張的狀態,如果出現了狀態相同但其g '()比原g '()出色的情況,那么我們更希望的是搜索新狀態,而不是原狀態。這樣,在待檢查隊列中出現重復狀態時,只需更新其g'() 就可以了。

         第三條是注意實現程序的方法,在起初我用sort排序f '()后再找出權值最大的狀態,而后發現用make_heap要更快。想一想,由于需要訪問的接點較多,待訪問隊列一大那么自然反復排序對速度會有影響,而堆操作則比排序更好。另一點是,實現更新待檢查隊列時的搜索也要用比較好的方法實現。我在JAVA的演示程序中用的PriorityQueue,可是結果不是很令人滿意。

         第四條優化策略是使用IDA*的算法,這是A*算法的一種,ID名為Iterative deepening是迭代加深的意思。思想是如下:
順便準備一個記錄一次循環最小值的temp=MAX, h' 取 manhattan距離
     先估算從START態到END態的h'() 記錄為MIN,將START放入待訪問隊列
     讀取隊列下一個狀態,到隊列尾則GOTO⑦
     若g'() > MIN GOTO ⑥
     若g'() + h'()   > MIN 是否為真,真GOTO ⑥,否 GOTO ⑤
     擴展該狀態,并標記此狀態已訪問。找到END態的話就結束該算法。GOTO ②
     temp = min(manhattan , temp),GOTO ③
     若無擴展過狀態,MIN=temp (ID的意思在這里體現)從頭開始循環GOTO ②

         第五條優化策略本身與搜索無關,在做題時也沒能幫上忙,不過從理論上講是有參考價值的。記得Q6中介紹的從END開始搜起嗎?如果我們的任務是對多個START 與END進行搜索,那么我們可以在每搜索完一次后記錄下路徑,這個路徑很重要,因為在以后的搜索中如果存在START和END的路徑已經被記錄過了,那么可以直接調出結果。
         從END搜起,可以方便判斷下一次的START是否已經有路徑到END了。當前一次搜索完時,其已訪問狀態是可以直接使用的,若START不在其中,則從待訪問的狀態鏈表中按搜索策略找下一個狀態,等于接著上一次的搜索結果開始找。
         之所以沒能在速度上幫上忙,是因為這個優化策略需要加大g' ()的比重,否則很容易出現深度相當大的情況,由于前一次搜索的策略與下一次的基本無關,導致前一次的路徑無法預料,所以就會出現深度過大的情況。解決方法是加大g' ()。
策略五類似給程序加一個緩沖區,避免重復計算。如果要做八數碼的應用,緩沖區會幫上忙的。

Q10:怎樣記錄找到的路徑?
         當找到解的時候我們就需要有類似回退的工作來整理一條解路徑,由于使用了不是簡單的DFS,所以不能借助通過函數調用所是使用的程序棧。
         我們可以手工加一個模擬棧。在Q4中解決了哈希的問題,利用哈希表就能快速訪問狀態對應的值,在這里,我們把原來的bool值改為char或其他能表示一次操作(至少需要5種狀態,除了u r l d 外還要能表示狀態已訪問)的值就行了。
         在搜索到解時,記錄下最后一個訪問的狀態值,然后從讀取該狀態對應的操作開始,就像棧操作的退棧一樣,不停往回搜,直到找到搜索起點為止。記錄好棧退出來的操作值,就是一條路徑。
 
 
 
 以前看了劉汝佳的書上的A*算法,一直不知道怎么寫,可以參考下面這個模型。
關于八數碼問題可以有很多種實現,這只是其中一種。
A*算法求八數碼問題{轉}
2008-05-08 09:18

(1) 用A*算法, 估價函數選“Hamilton距離”比選用“在錯誤方各內的數字數目”強很多。
(2)A*算法的關鍵是要能夠使“找到耗費最小的節點”和“判斷是否子節點已經存在”的算法的效率盡可能高,為此,網上不少資料建議采用Binary Heap或Hash table等數據結構,然而單獨使用任何一種數據結構,都有一定的缺陷,將Heap和Hash聯合起來使用,應該可以提高不少效率。具體如下:
1。建一張Hash表,存放沒一個節點的具體信息,如當前狀態、父節點在表中的位置等。
2。open表中存放著一些節點,這些節點不同于Hash表中的節點,可以將它理解為是Hash表中節點的索引,它只包含節點的估價和節點在Hash表中的位置,這些節點按估價排列成堆(Heap)。
3。沒必要再建一個closed表。
這樣,程序的流程就可以寫成:
初始化Hash表和open表;
將根節點放入Hash表和open表;
found = false;
while(open表不空) {
      從open表中得到耗費最低的節點的索引cur; // O(1)
      從open表中刪除耗費最低的節點; // O(logN)
      for 每個cur的子節點now do {
           if ( now 是目標節點 ) {
                   打印輸出;
                   found = true;
                   結束搜索;
           }
           if( now 不在Hashtable中 ) { // O(1)
                將now插入Hashtable中; // O(1)
                將now的索引放入open表中; // O(logN)
           } else if( now比Hashtable中的節點優 ) {
                if( 原節點在open表中 ) { // O(N)
                     用now替代原來節點; // O(1)
                     在open中push_heap來更新open表的順序; // O(logN)
                 }
           }
       }
   }
   if( !found ) 輸出 "無解";
可以看到,雖然查找open表中已存在的節點仍然為O(N), 但是當now已存在時,now比open表中節點優的概率是很小的,事先用O(1)的時間判斷,就可以避免用O(N)的時間來查找,從而提高了效率(這很像是CPU的Cache的工作原理)。
具體程序如下:

#include "stdafx.h"
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
#include <cassert>
using namespace std;
struct OpenNode{
int cost, point;
OpenNode(){}
OpenNode( int cost, int point ){
   this->cost = cost;
   this->point = point;
}
};
bool operator<( const OpenNode& a, const OpenNode& b ){
return a.cost > b.cost;
}
bool operator==(const OpenNode& a, int c){
return a.point == c;
}

struct HashNode{
char state[3][3];
int g, h, par, dir,x,y;
bool used;
HashNode(){
   used=false;
}
};

int dx[] = { -1,0,1,0 },
dy[] = { 0,1,0,-1 }; // u r d l

const int HASH_SIZE = 39999;
HashNode List[HASH_SIZE];
int factorial[] = {1,1,2,6,24,120,720,5040,40320};
/*int hash( char state[3][3] ){
int ret = 0;
char *p, *q;
for(p=&state[0][0];p<=&state[2][2];p++){
int cnt = 0;
for(q=&state[0][0]; q<p; q++) if( *q<*p ) cnt++;
ret += factorial[&state[2][2]-p]*(*p-cnt);
}
return ret;
}*/
bool eq( char a[3][3], char b[3][3] ){
for(int i=0;i<3;i++)
   for(int j=0;j<3;j++) if( a[i][j]!=b[i][j] ) return false;
   return true;
}
int hash( char state[3][3] ){
char* p = &state[0][0];
int ret = p[0] * 7 + p[1] * 17 + p[2] * 47 + p[3] * 117 + p[4] * 217 + p[5]
   * 977 + p[6] * 1299 + p[7] * 5971 + p[8] * 7779;
ret %= HASH_SIZE;
while( List[ret].used && !eq(List[ret].state , state) )
   ret= (ret+1) % HASH_SIZE;
return ret;
}
int h( char state[3][3] ){
int ret = 0;
for(int x=0;x<3;x++)
   for(int y=0;y<3;y++) if( state[x][y]!=0 )
    ret += abs((state[x][y]-1)/3-x) +abs((state[x][y]-1)%3-y);
   return ret;
}
void output( int i ){
string res;
while(List[i].dir>=0){
   res+= List[i].dir==0?'u':List[i].dir==1?'r':List[i].dir==2?'d':'l';
   i = List[i].par;
}
reverse( res.begin(), res.end() );
cout<<res<<endl;
}
bool solvable( char state[3][3] ){
int t = 0;
for(char* i=&state[0][0];i<&state[2][2];i++)
    for(char* j=i+1;j<=&state[2][2];j++)
      if(*i!=0 && *j!=0 && *i>*j) t++;
if(t%2) return false;
return true;
}
vector<OpenNode> open;
int main(){
string init;
getline( cin, init );
HashNode now;
int cnt=0;
for(int i=0;i<init.size();i++) {
   if(init[i] == 'x') {
    now.state[cnt/3][cnt%3] = 0;
    now.x = cnt /3;
    now.y = cnt %3;
    cnt++;
   } else if(init[i]!=' ') {
    now.state[cnt/3][cnt%3] = init[i] - '0';
    cnt++;
   }
}
if( !solvable(now.state) ) {
    cout<<"unsolvable"<<endl;
    return 0;
}
now.g = 0;
now.h = h(now.state);
now.par = -1;
now.dir = -1;
now.used = true;
int i = hash(now.state);
List[i] = now;
open.push_back(OpenNode(now.g+now.h,i));
while(!open.empty()){
   int cur = open.front().point;
   pop_heap( open.begin(), open.end() );
   open.erase( open.end()-1 );
   for(int i=0;i<4;i++){
    now = List[cur];
    int x = now.x+dx[i];
    int y = now.y+dy[i];
    if(x<0||x>2||y<0||y>2) continue;
    swap( now.state[x][y], now.state[now.x][now.y] );
    now.x = x;
    now.y = y;
    now.h = h( now.state );
    now.g++;
    now.par = cur;
    now.dir = i;
   
    int hashcode = hash( now.state );
    if( now.h == 0 ){
     List[hashcode] = now;
     output( hashcode );
     return 0;
    } else if( !List[hashcode].used ){
     List[hashcode] = now;
     open.push_back( OpenNode(now.h+now.g,hashcode) );
     push_heap( open.begin(), open.end() );
    } else if( List[hashcode].g+List[hashcode].h > now.g+now.h ){
     List[hashcode] = now;
     vector<OpenNode>::iterator it = find( open.begin(), open.end(), hashcode );
     if(it==open.end()) continue;
     push_heap( open.begin(), it+1 );
    }
   }
}
cout<<"unsolvable"<<endl;
return 0;
}


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美电影在线观看| 亚洲精品欧美激情| 影音先锋成人资源站| 国产欧美日韩激情| 国产噜噜噜噜噜久久久久久久久| 欧美精品aa| 欧美四级在线观看| 国产精品草莓在线免费观看| 欧美久久99| 欧美日韩一区在线观看视频| 欧美日韩一区二区三区在线| 国产精品久久久一区二区三区 | 亚洲国产综合91精品麻豆| 影音先锋亚洲视频| 亚洲日本一区二区| 在线亚洲自拍| 久久国产综合精品| 麻豆免费精品视频| 亚洲第一免费播放区| 麻豆av一区二区三区| 欧美高清一区二区| 日韩视频在线观看免费| 午夜一区在线| 欧美福利专区| 国产精品女人毛片| 91久久在线| 欧美中文字幕久久| 亚洲精品欧美专区| 久久精品免费看| 欧美三区在线| 一区二区亚洲精品| 午夜视频久久久| 亚洲国产乱码最新视频| 亚洲一区日韩在线| 免费视频一区二区三区在线观看| 亚洲国内精品在线| 亚洲欧美日本国产有色| 欧美大色视频| 国产午夜一区二区三区| 一本色道久久综合狠狠躁的推荐| 久久精品在线免费观看| 亚洲美女视频在线观看| 久久青草久久| 国产日产欧美精品| 一本色道久久99精品综合| 免费成人性网站| 亚洲中字在线| 欧美激情2020午夜免费观看| 亚洲手机在线| 欧美日韩精品久久久| 伊人蜜桃色噜噜激情综合| 午夜欧美视频| 亚洲视频第一页| 欧美日本在线播放| 亚洲精品视频在线观看免费| 美女精品自拍一二三四| 欧美亚洲免费在线| 国产欧美精品xxxx另类| 午夜视频一区二区| 亚洲性图久久| 国产精品视频网站| 亚欧成人在线| 亚洲自拍三区| 国产精品亚洲激情| 亚洲一区二区三区久久| 亚洲精选国产| 欧美日韩精品二区| 亚洲一区自拍| 一区二区三区毛片| 国产精品久久久久91| 午夜精品久久久久久99热软件| 中文欧美在线视频| 国产乱人伦精品一区二区| 午夜精品www| 亚洲午夜精品久久久久久浪潮| 欧美日韩另类丝袜其他| 宅男精品视频| 亚洲网站啪啪| 欧美乱大交xxxxx| 亚洲精品在线一区二区| 亚洲日本中文字幕区| 欧美日韩一区二区免费视频| 亚洲欧美另类国产| 欧美在线高清视频| 亚洲高清久久| 亚洲毛片在线| 国产欧美日韩伦理| 久久久www免费人成黑人精品 | 久久精品国产99国产精品澳门 | 久久精选视频| 亚洲国产精品嫩草影院| 亚洲区中文字幕| 国产精品xnxxcom| 久久久久久精| 欧美成人亚洲| 欧美在线看片| 欧美大片免费观看在线观看网站推荐| 99亚洲视频| 久久成人免费电影| 99精品国产在热久久下载| 亚洲一区二区三区四区在线观看 | 亚洲国产视频a| 亚洲欧洲在线视频| 国产日本欧美一区二区| 亚洲国产二区| 日韩一本二本av| 国内精品久久久久久久影视麻豆 | 亚洲日本在线视频观看| 亚洲综合三区| 99re视频这里只有精品| 午夜国产精品视频| 一区二区日韩精品| 久久婷婷国产综合精品青草| 亚洲一线二线三线久久久| 免费高清在线一区| 99精品欧美| 亚洲乱码精品一二三四区日韩在线 | 欧美精品成人在线| 久久久九九九九| 欧美三区免费完整视频在线观看| 老**午夜毛片一区二区三区| 国产精品嫩草影院av蜜臀| 亚洲欧洲日韩综合二区| 狠狠色2019综合网| 亚洲天堂成人| 一区二区三区国产精华| 蜜臀av性久久久久蜜臀aⅴ四虎| 欧美一级日韩一级| 欧美日本中文字幕| 亚洲大片在线| 亚洲国产天堂久久国产91| 欧美在线视频观看免费网站| 亚洲欧美日韩电影| 欧美日韩美女一区二区| 亚洲国产欧美日韩| 最新国产乱人伦偷精品免费网站| 久久久久亚洲综合| 久久免费黄色| 国产在线一区二区三区四区| 欧美亚洲视频| 欧美一区二区三区在线视频| 国产精品久久久久一区二区| 亚洲午夜一二三区视频| 亚洲欧美国产日韩天堂区| 欧美日本一区二区视频在线观看| 欧美国产一区在线| 亚洲丰满在线| 免费一级欧美片在线观看| 欧美激情自拍| 一本大道久久a久久精二百| 免费在线成人av| 亚洲高清久久| 一区二区三区鲁丝不卡| 欧美三级特黄| 亚洲综合三区| 久久久国产精品一区二区三区| 国内偷自视频区视频综合| 久久激情婷婷| 亚洲电影成人| 亚洲精品乱码久久久久久| 麻豆91精品| 亚洲精选视频在线| 国产精品二区三区四区| 亚洲视频在线一区观看| 亚洲伊人伊色伊影伊综合网| 国产精品久久久久久久久久妞妞| 亚洲欧美一区二区视频| 另类酷文…触手系列精品集v1小说| 韩曰欧美视频免费观看| 免费日韩av电影| 亚洲一级一区| 欧美福利影院| 亚洲免费影视| 在线观看欧美亚洲| 欧美日韩国产免费| 性欧美暴力猛交另类hd| 欧美激情成人在线视频| 亚洲一区久久久| 在线国产精品播放| 欧美调教vk| 久久久蜜桃一区二区人| 亚洲日本欧美日韩高观看| 欧美一区日本一区韩国一区| 伊大人香蕉综合8在线视| 欧美日韩国产色综合一二三四| 欧美亚洲一区| 日韩一级大片在线| 欧美fxxxxxx另类| 欧美一级在线播放| 亚洲精品国产精品国自产观看 | 欧美日本亚洲| 欧美一区二区三区四区在线观看地址 | 欧美freesex交免费视频| 亚洲欧美乱综合| 亚洲欧洲一区二区三区在线观看| 国产精品网站在线播放| 欧美二区乱c少妇| 久久国产视频网站| 亚洲小说春色综合另类电影| 欧美激情亚洲视频|