《python算法教程》Day10 - 平面最近點對問題

今天是《python算法教程》的第10篇讀書筆記秽五。筆記的主要內(nèi)容是使用python實現(xiàn)求最小點對的時間復(fù)雜度為O(nlogn)的算法。

平面最小點對問題介紹

在幾何學(xué)中檩小,有一個基本問題:在一個平面的n個點中浅妆,求距離最近的兩個點穿仪。
最直接的思路是遍歷所有的點對,通過比較所有點對的距離找出距離最近的兩點框舔,即暴力算法蹦玫。但是,這個思路的時間復(fù)雜度為O(n^2)刘绣。顯然樱溉,這種算法的時間復(fù)雜度是不能接受的。
因此纬凤,是否可以考慮通過分治法的思路福贞,將上述問題的解法的時間復(fù)雜度控制在O(nlog2n)?答案是可以的。具體的算法講解可參考下述博文:

https://blog.csdn.net/liufeng_king/article/details/8484284

但運用分治法求解上述問題時停士,需要注意一點挖帘,距離最小的兩個點可能不在于同一個分組的點集中,而是分別來自于不同的點集中恋技。

代碼演示

暴力算法

#計算兩點的距離
import math
def calDis(seq):
    dis=math.sqrt((seq[0][0]-seq[1][0])**2+(seq[0][1]-seq[1][1])**2)
    return dis

#暴力算法主體函數(shù)
def calDirect(seq):
    minDis=float('inf')
    pair=[]
    for i in range(len(seq)):
        for j in range(i+1,len(seq)):
            dis=calDis([seq[i],seq[j]])
            if dis <minDis:
                minDis=dis
                pair=[seq[i],seq[j]]
    return [pair,minDis]

分治法求解

#求出平面中距離最近的點對(若存在多對拇舀,僅需求出一對)
import random
import math

#計算兩點的距離
def calDis(seq):
    dis=math.sqrt((seq[0][0]-seq[1][0])**2+(seq[0][1]-seq[1][1])**2)
    return dis

#生成器:生成橫跨跨兩個點集的候選點
def candidateDot(u,right,dis,med_x):
    cnt=0
    #遍歷right(已按橫坐標升序排序)。若橫坐標小于med_x-dis則進入下一次循環(huán)蜻底;若橫坐標大于med_x+dis則跳出循環(huán)骄崩;若點的縱坐標好是否落在在[u[1]-dis,u[1]+dis],則返回這個點
    for v in right:
        if v[0]<med_x-dis:
            continue
        if v[0]>med_x+dis:
            break
        if v[1]>=u[1]-dis and v[1]<=u[1]+dis:
            yield v
   
#求出橫跨兩個部分的點的最小距離
def combine(left,right,resMin,med_x):
    dis=resMin[1]
    minDis=resMin[1]
    pair=resMin[0]
    for u in left:
        if u[0]<med_x-dis:
            continue
        for v in candidateDot(u,right,dis,med_x):
            dis=calDis([u,v])
            if dis<minDis:
                minDis=dis
                pair=[u,v]
    return [pair,minDis]


#分治求解
def divide(seq):
    #求序列元素數(shù)量
    n=len(seq)
    #按點的縱坐標升序排序
    seq=sorted(seq)
    #遞歸開始進行
    if n<=1:
        return None,float('inf')
    elif n==2:
        return [seq,calDis(seq)]
    else:
        half=int(len(seq)/2)
        med_x=(seq[half][0]+seq[-half-1][0])/2
        left=seq[:half]    
        resLeft=divide(left)
        right=seq[half:]
        resRight=divide(right)
        #獲取兩集合中距離最短的點對
        if resLeft[1]<resRight[1]:
            resMin=combine(left,right,resLeft,med_x)
        else:
            resMin=combine(left,right,resRight,med_x)
        pair=resMin[0]
        minDis=resMin[1]
    return [pair,minDis]    
    
seq=[(random.randint(0,1000000),random.randint(0,1000000)) for x in range(500000)]
print("優(yōu)化算法",divide(seq))
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末播瞳,一起剝皮案震驚了整個濱河市此蜈,隨后出現(xiàn)的幾起案子闷哆,更是在濱河造成了極大的恐慌,老刑警劉巖脱惰,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異源请,居然都是意外死亡枪芒,警方通過查閱死者的電腦和手機彻况,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來舅踪,“玉大人纽甘,你說我怎么就攤上這事〕槁担” “怎么了悍赢?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長货徙。 經(jīng)常有香客問我左权,道長,這世上最難降的妖魔是什么痴颊? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任赏迟,我火速辦了婚禮,結(jié)果婚禮上蠢棱,老公的妹妹穿的比我還像新娘锌杀。我一直安慰自己,他們只是感情好泻仙,可當(dāng)我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布糕再。 她就那樣靜靜地躺著,像睡著了一般玉转。 火紅的嫁衣襯著肌膚如雪突想。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天究抓,我揣著相機與錄音猾担,去河邊找鬼。 笑死漩蟆,一個胖子當(dāng)著我的面吹牛垒探,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播怠李,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼圾叼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了捺癞?” 一聲冷哼從身側(cè)響起夷蚊,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎髓介,沒想到半個月后惕鼓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡唐础,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年箱歧,在試婚紗的時候發(fā)現(xiàn)自己被綠了矾飞。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡呀邢,死狀恐怖洒沦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情价淌,我是刑警寧澤申眼,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站蝉衣,受9級特大地震影響括尸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜病毡,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一濒翻、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧剪验,春花似錦肴焊、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽似嗤。三九已至啸臀,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間烁落,已是汗流浹背乘粒。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留伤塌,地道東北人灯萍。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像每聪,于是被迫代替她去往敵國和親旦棉。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 歸去來兮药薯。 1.1 說明 本篇為《挑戰(zhàn)程序設(shè)計競賽(第2版)》[http://www.ituring.com.cn...
    尤汐Yogy閱讀 14,277評論 0 160
  • 機器學(xué)習(xí)是做NLP和計算機視覺這類應(yīng)用算法的基礎(chǔ)绑洛,雖然現(xiàn)在深度學(xué)習(xí)模型大行其道,但是懂一些傳統(tǒng)算法的原理和它們之間...
    在河之簡閱讀 20,482評論 4 65
  • ‘橘生淮南為橘童本,生于淮北則為枳真屯,葉徒相似,其實味不同’穷娱。環(huán)境的不同绑蔫,會造成生長于其中植物的結(jié)果不同运沦。同樣的,環(huán)境的...
    辰楓設(shè)計閱讀 22,592評論 0 2
  • 不過一棵樹
    夭凪閱讀 138評論 0 0
  • 晝夜聽到風(fēng)在顫抖配深, 依稀想起昨日的面容茶袒; 藍天下飛奔的影子, 唱著歌笑歲月匆匆凉馆。 多少青春鮮亮的畫面薪寓, 留在過去時...
    依然yiran06閱讀 170評論 0 0