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

最近點對問題

轉載:這個問題很容易理解,似乎也不難解決。我們只要將每一點與其他n-1個點的距離算出,找出達到最小距離的兩個點即可。然而,這樣做效率太低,需要O(n2)的計算時間。在問題的計算復雜性中我們可以看到,該問題的計算時間下界為Ω(nlogn)。這個下界引導我們去找問題的一個θ(nlogn)算法。

    這個問題顯然滿足分治法的第一個和第二個適用條件,我們考慮將所給的平面上n個點的集合S分成2個子集S1和S2,每個子集中約有n/2個點,·然后在每個子集中遞歸地求其最接近的點對。在這里,一個關鍵的問題是如何實現分治法中的合并步驟,即由S1和S2的最接近點對,如何求得原集合S中的最接近點對,因為S1和S2的最接近點對未必就是S的最接近點對。如果組成S的最接近點對的2個點都在S1中或都在S2中,則問題很容易解決。但是,如果這2個點分別在S1和S2中,則對于S1中任一點p,S2中最多只有n/2個點與它構成最接近點對的候選者,仍需做n2/4次計算和比較才能確定S的最接近點對。因此,依此思路,合并步驟耗時為O(n2)。整個算法所需計算時間T(n)應滿足: 

T(n)=2T(n/2)+O(n2)

    它的解為T(n)=O(n2),即與合并步驟的耗時同階,顯示不出比用窮舉的方法好。從解遞歸方程的套用公式法,我們看到問題出在合并步驟耗時太多。這啟發我們把注意力放在合并步驟上。

    為了使問題易于理解和分析,我們先來考慮一維的情形。此時S中的n個點退化為x軸上的n個實數x1,x2,..,xn。最接近點對即為這n個實數中相差最小的2個實數。我們顯然可以先將x1,x2,..,xn排好序,然后,用一次線性掃描就可以找出最接近點對。這種方法主要計算時間花在排序上,因此如在排序算法中所證明的,耗時為O(nlogn)。然而這種方法無法直接推廣到二維的情形。因此,對這種一維的簡單情形,我們還是嘗試用分治法來求解,并希望能推廣到二維的情形。

    假設我們用x軸上某個點m將S劃分為2個子集S1和S2,使得S1={x∈S|x≤m};S2={x∈S|x>m}。這樣一來,對于所有p∈S1和q∈S2有p<q。

    遞歸地在S1和S2上找出其最接近點對{p1,p2}和{q1,q2},并設δ=min{|p1-p2|,|q1-q2|},S中的最接近點對或者是{p1,p2},或者是{q1,q2},或者是某個{p3,q3},其中p3∈S1且q3∈S2。如圖1所示。

 

圖1 一維情形的分治法

    我們注意到,如果S的最接近點對是{p3,q3},即|p3-q3|<δ,則p3和q3兩者與m的距離不超過δ,即|p3-m|<δ,|q3-m|<δ,也就是說,p3∈(m-δ,m],q3∈(m,m+δ]。由于在S1中,每個長度為δ的半閉區間至多包含一個點(否則必有兩點距離小于δ),并且m是S1和S2的分割點,因此(m-δ,m]中至多包含S中的一個點。同理,(m,m+δ]中也至多包含S中的一個點。由圖1可以看出,如果(m-δ,m]中有S中的點,則此點就是S1中最大點。同理,如果(m,m+δ]中有S中的點,則此點就是S2中最小點。因此,我們用線性時間就能找到區間(m-δ,m]和(m,m+δ]中所有點,即p3和q3。從而我們用線性時間就可以將S1的解和S2的解合并成為S的解。也就是說,按這種分治策略,合并步可在O(n)時間內完成。這樣是否就可以得到一個有效的算法了呢?還有一個問題需要認真考慮,即分割點m的選取,及S1和S2的劃分。選取分割點m的一個基本要求是由此導出集合S的一個線性分割,即S=S1∪S2 ,S1∩S2=Φ,且S1{x|x≤m};S2{x|x>m}。容易看出,如果選取m=[max(S)+min(S)]/2,可以滿足線性分割的要求。選取分割點后,再用O(n)時間即可將S劃分成S1={x∈S|x≤m}和S2={x∈S|x>m}。然而,這樣選取分割點m,有可能造成劃分出的子集S1和S2的不平衡。例如在最壞情況下,|S1|=1,|S2|=n-1,由此產生的分治法在最壞情況下所需的計算時間T(n)應滿足遞歸方程:

   T(n)=T(n-1)+O(n)

    它的解是T(n)=O(n2)。這種效率降低的現象可以通過分治法中“平衡子問題”的方法加以解決。也就是說,我們可以通過適當選擇分割點m,使S1和S2中有大致相等個數的點。自然地,我們會想到用S的n個點的坐標的中位數來作分割點。在選擇算法中介紹的選取中位數的線性時間算法使我們可以在O(n)時間內確定一個平衡的分割點m。

    至此,我們可以設計出一個求一維點集S中最接近點對的距離的算法CPAIR1如下。

function CPAIR1(S);
begin
if |S|=2 then δ=|x[2]-x[1]| // x[1..n]存放的是S中n個點的坐標
else if (|S|=1) then δ:=∞
else begin
m:=S中各點的坐標值的中位數;
構造S1和S2,使S1={x∈S|x≤m},S2={x∈S|x>m};
δ1:=CPAIRI(S1);
δ2:=CPAIRI(S2);
p:=max(S1);
q:=min(S2);
δ:=min(δ1,δ2,q-p);
end;
return(δ);
end;

    由以上的分析可知,該算法的分割步驟和合并步驟總共耗時O(n)。因此,算法耗費的計算時間T(n)滿足遞歸方程:

    解此遞歸方程可得T(n)=O(nlogn)。

    這個算法看上去比用排序加掃描的算法復雜,然而這個算法可以向二維推廣。

    下面我們來考慮二維的情形。此時S中的點為平面上的點,它們都有2個坐標值x和y。為了將平面上點集S線性分割為大小大致相等的2個子集S1和S2,我們選取一垂直線l:x=m來作為分割直線。其中m為S中各點x坐標的中位數。由此將S分割為S1={p∈S|px≤m}和S2={p∈S|px>m}。從而使S1和S2分別位于直線l的左側和右側,且S=S1∪S2 。由于m是S中各點x坐標值的中位數,因此S1和S2中的點數大致相等。

    遞歸地在S1和S2上解最接近點對問題,我們分別得到S1和S2中的最小距離δ1δ2。現設δ=min(δ1,δ1)。若S的最接近點對(p,q)之間的距離d(p,q)<δ則p和q必分屬于S1和S2。不妨設p∈S1,q∈S2。那么p和q距直線l的距離均小于δ。因此,我們若用P1和P2分別表示直線l的左邊和右邊的寬為δ的2個垂直長條,則p∈S1,q∈S2,如圖2所示。

圖2 距直線l的距離小于δ的所有點

    在一維的情形,距分割點距離為δ的2個區間(m-δ,m](m,m+δ]中最多各有S中一個點。因而這2點成為唯一的末檢查過的最接近點對候選者。二維的情形則要復雜些,此時,P1中所有點與P2中所有點構成的點對均為最接近點對的候選者。在最壞情況下有n2/4對這樣的候選者。但是P1和P2中的點具有以下的稀疏性質,它使我們不必檢查所有這n2/4對候選者??紤]P1中任意一點p,它若與P2中的點q構成最接近點對的候選者,則必有d(p,q)<δ。滿足這個條件的P2中的點有多少個呢?容易看出這樣的點一定落在一個δ×2δ的矩形R中,如圖3所示。

圖3 包含點q的δ×2δ的矩形R

δ的意義可知P2中任何2個S中的點的距離都不小于δ。由此可以推出矩形R中最多只有6個S中的點。事實上,我們可以將矩形R的長為2δ的邊3等分,將它的長為δ的邊2等分,由此導出6個(δ/2)×(2δ/3)的矩形。如圖4(a)所示。

圖4 矩形R中點的稀疏性

    若矩形R中有多于6個S中的點,則由鴿舍原理易知至少有一個δ×2δ的小矩形中有2個以上S中的點。設u,v是這樣2個點,它們位于同一小矩形中,則

    因此d(u,v)≤5δ/6<δ 。這與δ的意義相矛盾。也就是說矩形R中最多只有6個S中的點。圖4(b)是矩形R中含有S中的6個點的極端情形。由于這種稀疏性質,對于P1中任一點p,P2中最多只有6個點與它構成最接近點對的候選者。因此,在分治法的合并步驟中,我們最多只需要檢查6×n/2=3n對候選者,而不是n2/4對候選者。這是否就意味著我們可以在O(n)時間內完成分治法的合并步驟呢?現在還不能作出這個結論,因為我們只知道對于P1中每個S1中的點p最多只需要檢查P2中的6個點,但是我們并不確切地知道要檢查哪6個點。為了解決這個問題,我們可以將p和P2中所有S2的點投影到垂直線l上。由于能與p點一起構成最接近點對候選者的S2中點一定在矩形R中,所以它們在直線l上的投影點距p在l上投影點的距離小于δ。由上面的分析可知,這種投影點最多只有6個。因此,若將P1和P2中所有S的點按其y坐標排好序,則對P1中所有點p,對排好序的點列作一次掃描,就可以找出所有最接近點對的候選者,對P1中每一點最多只要檢查P2中排好序的相繼6個點。

    至此,我們可以給出用分治法求二維最接近點對的算法CPAIR2如下:

function CPAIR2(S);
begin
if |S|=2 then δ:=S中這2點的距離
else if |S|=0 then δ:=∞
else begin
1. m:=S中各點x坐標值的中位數;
構造S1和S2,使S1={p∈S|px≤m}和S2={p∈S|px>m}
2. δ1:=CPAIR2(S1);δ2:=CPAIR2(S2);
3. δm:=min(δ1,δ2);
4. 設P1是S1中距垂直分割線l的距離在δm之內的所有點組成的集合,
P2是S2中距分割線l的距離在δm之內所有點組成的集合。將P1和 P2中的點依其y坐標值從小到大排序,并設P1*和P2*是相應的已排 好序的點列;
5. 通過掃描P1*以及對于P1*中每個點檢查P2*中與其距離在δm之內的
所有點(最多6個)可以完成合并。當P1*中的掃描指針逐次向上移動
時,P2*中的掃描指針可在寬為2δm的一個區間內移動。設δl是按
這種掃描方式找到的點對間的最小距離;
6. δ=min(δm,δl);
end;
return(δ);
end;

    下面我們來分析一下算法CPAIR2的計算復雜性。設對于n個點的平面點集S,算法耗時T(n)。算法的第1步和第5步用了O(n)時間,第3步和第6步用了常數時間,第2步用了2T(n/2)時間。若在每次執行第4步時進行排序,則在最壞情況下第4步要用O(nlogn)時間。這不符合我們的要求。因此,在這里我們要作一個技術上的處理。我們采用設計算法時常用的預排序技術,即在使用分治法之前,預先將S中n個點依其y坐標值排好序,設排好序的點列為P*。在執行分治法的第4步時,只要對P*作一次線性掃描,即可抽取出我們所需要的排好序的點列P1*和P2*。然后,在第5步中再對P1*作一次線性掃描,即可求得δl。因此,第4步和第5步的兩遍掃描合在一起只要用O(n)時間。這樣一來,經過預排序處理后的算法CPAIR2所需的計算時間T(n)滿足遞歸方程:

    顯而易見T(n)=O(nlogn),預排序所需的計算時間為O(n1ogn)。因此,整個算法所需的計算時間為O(nlogn)。在漸近的意義下,此算法已是最優的了。

晚上研究了半天,又參考了類似的代碼,終于搞出來了:

#include <cstdio>
#include 
<cstdlib>
#include 
<cstring>
#include 
<cmath>

const int MAXN = 100001;
const double eps = 1e-6;
struct point{
    
int index;
    
double x,y;
}
a[MAXN],b[MAXN],c[MAXN];

inline 
double min(const double p,const double q){
    
return p>? q:p;
}

inline 
double distance(const point &p,const point &q){
    
return sqrt((p.x-q.x)*(p.x-q.x)+(p.y-q.y)*(p.y-q.y));
}

int cmpx(const void *p,const void *q){
    
double t = ((point *)p)->- ((point *)q)->x;
    
if(t>eps) return 1;
    
else if(fabs(t)<=eps) return 0;
    
else return -1;
}

int cmpy(const void *p,const void *q){
    
double t = ((point *)p)->- ((point *)q)->y;
    
if(t>eps) return 1;
    
else if(fabs(t)<=eps) return 0;
    
else return -1;
}

void merge(point p[],point q[],int s,int m,int t){
    
int i=s,j=m+1,k=s;
    
while(i<=&& j<=t){
        
if(q[i].y>q[j].y) p[k++]=q[j++];
        
else p[k++]=q[i++];
    }

    
while(i<=m) p[k++]=q[i++];
    
while(j<=t) p[k++]=q[j++];
}

double closest(point a[],point b[],point c[],int p,int q){
    
if(q==p+1return distance(a[p],a[q]);
    
if(q==p+2){
        
double d1=distance(a[p],a[q]);
        
double d2=distance(a[p],a[p+1]);
        
double d3=distance(a[p+1],a[q]);
        
if(d1<d2 && d1<d3) return d1;
        
else if(d2<d3) return d2;
        
else return d3;
    }

    
int i,j,k,m=(p+q)>>1;
    
double d1,d2,dm;
    
for(i=j=p,k=m+1;i<=q;i++){
        
if(b[i].index<=m) c[j++]=b[i];
        
else c[k++]=b[i];
    }

    d1
=closest(a,c,b,p,m),d2=closest(a,c,b,m+1,q);
    dm
=min(d1,d2);
    merge(b,c,p,m,q);
    
for(i=k=p;i<=q;i++)
        
if(fabs(b[i].x-b[m].x)<dm)
            c[k
++]=b[i];
    
for(i=p;i<k;i++)
        
for(j=i+1;j<&& (c[j].y-c[i].y)<dm;j++){
            
double t=distance(c[i],c[j]);
            
if(t<dm) dm=t;
        }

    
return dm;
}

int main(){
    
int i,n;
    
while(scanf("%d",&n),n){
        
for(i=0;i<n;i++) scanf("%lf %lf",&a[i].x,&a[i].y);
        qsort(a,n,
sizeof(a[0]),cmpx);
        
for(i=0;i<n;i++) a[i].index=i;
        memcpy(b,a,n
*sizeof(a[0]));
        qsort(b,n,
sizeof(b[0]),cmpy);
        printf(
"%.2lf\n",closest(a,b,c,0,n-1));
    }

    
return 0;
}

posted on 2009-05-18 23:28 極限定律 閱讀(2539) 評論(0)  編輯 收藏 引用 所屬分類: ACM/ICPC

<2009年5月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

導航

統計

常用鏈接

留言簿(10)

隨筆分類

隨筆檔案

友情鏈接

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲国产婷婷香蕉久久久久久99 | 一区二区视频免费完整版观看| 亚洲无线观看| 亚洲欧美一区二区三区久久| 国内精品久久久久久久果冻传媒| 免费在线播放第一区高清av| 在线一区二区三区做爰视频网站 | 一本色道久久综合亚洲精品不卡| av成人福利| 日韩亚洲国产精品| 欧美一区二区三区四区视频| 亚洲国产精品高清久久久| 国产美女诱惑一区二区| 免费视频一区| 欧美国产免费| 99精品视频一区| av成人天堂| 亚洲网站在线观看| 亚洲精品一二区| 亚洲午夜高清视频| 午夜精品福利视频| 久久亚洲色图| 亚洲桃花岛网站| 久久久久久久综合| 欧美性jizz18性欧美| 韩日欧美一区二区三区| 亚洲激情视频在线播放| 午夜精品国产| 亚洲韩日在线| 亚洲欧美成人一区二区三区| 另类av导航| 国产精品看片你懂得| 最新日韩在线视频| 久久久不卡网国产精品一区| 日韩亚洲不卡在线| 久久综合国产精品| 国产亚洲在线| 亚洲欧美激情精品一区二区| 欧美成人午夜77777| 国产日韩三区| 亚洲日本理论电影| 久久久精品动漫| 中国成人在线视频| 噜噜噜在线观看免费视频日韩 | 久久蜜桃资源一区二区老牛| 亚洲破处大片| 美女在线一区二区| 在线看欧美视频| 久久激情综合| 亚洲深夜福利网站| 欧美日韩国产成人在线观看| 亚洲成人在线视频播放| 久久久久这里只有精品| 亚洲香蕉伊综合在人在线视看| 男女精品网站| 亚洲国产一区二区精品专区| 老司机aⅴ在线精品导航| 欧美亚洲视频一区二区| 国产精品网站在线播放| 亚洲视频在线观看网站| 亚洲精品欧美一区二区三区| 麻豆国产精品va在线观看不卡| 国内自拍一区| 免费成人av在线| 美女诱惑黄网站一区| 亚洲精品欧美日韩| 亚洲国产你懂的| 欧美a级一区| 99国产一区二区三精品乱码| 亚洲精品视频在线| 国产精品国内视频| 久久gogo国模啪啪人体图| 久久国产精品72免费观看| 亚洲国产日韩在线| 99热免费精品| 国产亚洲成av人片在线观看桃 | 久久精品二区| 久久久久99| 日韩午夜在线视频| 亚洲午夜视频在线观看| 国产一区在线播放| 欧美国产极速在线| 欧美日韩一区在线播放| 亚洲免费影视第一页| 午夜精品久久久久久久久久久久久| 国产色爱av资源综合区| 蜜桃精品一区二区三区| 欧美日本韩国一区二区三区| 午夜久久美女| 免费不卡中文字幕视频| 亚洲小说春色综合另类电影| 午夜伦理片一区| 亚洲久久在线| 欧美一区二区三区四区高清 | 国产精品日本精品| 91久久精品国产| 一区二区三区欧美激情| 国产亚洲一本大道中文在线| 欧美1级日本1级| 欧美日韩中文在线观看| 欧美专区日韩专区| 欧美高清视频一区二区| 午夜亚洲精品| 男女激情视频一区| 午夜精品亚洲| 免费在线亚洲| 久久久久.com| 欧美午夜激情视频| 麻豆久久婷婷| 国产精品一区二区视频| 卡一卡二国产精品| 国产精品美女久久久久av超清 | 久久免费午夜影院| 欧美日韩大片| 毛片av中文字幕一区二区| 国产精品久久久久国产精品日日| 欧美国产1区2区| 国产欧美在线视频| 99精品国产热久久91蜜凸| 红桃av永久久久| 亚洲男同1069视频| 亚洲永久免费av| 欧美激情视频在线免费观看 欧美视频免费一 | 精品91在线| 亚洲欧美在线视频观看| 一区二区三区免费看| 狂野欧美性猛交xxxx巴西| 欧美一区二区三区日韩视频| 欧美日韩爆操| 亚洲国产一区二区三区在线播| 黄色免费成人| 欧美中文在线免费| 久久精品人人爽| 欧美成人免费小视频| 免费观看日韩av| 在线日韩欧美视频| 久久视频一区| 欧美激情一二三区| 亚洲精品资源| 欧美人与禽性xxxxx杂性| 亚洲人妖在线| 亚洲视频大全| 国产精品久久久久久久久免费| 一区二区国产日产| 亚洲欧美网站| 国产综合色一区二区三区| 久久精品视频99| 亚洲第一区色| 99在线|亚洲一区二区| 欧美日韩在线播放| 亚洲在线国产日韩欧美| 久久久久一区二区| 亚洲人成人一区二区在线观看| 欧美国产日韩一区二区在线观看| 亚洲欧洲日本mm| 亚洲欧美国产77777| 国产亚洲欧美另类中文| 久久精品女人| 欧美精品一区二区精品网| 亚洲精品在线电影| 亚洲女女做受ⅹxx高潮| 国产日韩精品视频一区| 久热精品视频在线免费观看| 亚洲国产成人久久| 亚洲视频免费| 国内精品视频一区| 欧美国产精品一区| 亚洲欧美日韩综合一区| 亚洲第一精品电影| 欧美一区二区三区电影在线观看| 黄网动漫久久久| 欧美日韩一区二区三区在线观看免 | 欧美精品久久久久久久免费观看 | 免费永久网站黄欧美| 亚洲日本视频| 国产精品视频网站| 麻豆成人在线观看| 亚洲欧美日韩国产成人| 欧美1级日本1级| 亚洲欧洲av一区二区| 亚洲欧洲日产国码二区| 国产麻豆成人精品| 欧美精品一区二区三区很污很色的| 亚洲午夜精品17c| 亚洲国产三级网| 久久久亚洲高清| 亚洲欧美怡红院| 亚洲精品一区二区三区婷婷月| 国产日韩一级二级三级| 欧美日韩一区二区视频在线 | 国产精品美女在线观看| 美女亚洲精品| 欧美主播一区二区三区| 一区二区精品国产| 亚洲电影毛片| 蜜桃av一区二区| 久久精品视频在线免费观看| 亚洲一区黄色| 99亚洲视频| 日韩网站在线|