」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 使用分治法找出最近的點對

使用分治法找出最近的點對

發佈於2024-07-30
瀏覽:850

本節介紹使用分治法找出最接近的點對的有效演算法。給定一組點,最近對問題是找到彼此最接近的兩個點。如下圖所示,繪製一條線來連接最近對動畫中兩個最近的點。

Image description

案例研究:找出最近的對,提出了一種用於尋找最近的點對的強力演算法。此演算法計算所有點對之間的距離並找到距離最小的點。顯然,該演算法需要 O(n^2) 時間。我們能否設計出更有效率的演算法?

我們將使用一種稱為分而治之的方法來解決這個問題。此方法將問題分成子問題,求解子問題,然後組合子問題的解以獲得整個問題的解。與動態規劃法不同,分而治之方法中的子問題不重疊。子問題就像原問題一樣,但規模較小,因此可以應用遞歸來解決問題。事實上,所有遞歸問題的解決方案都遵循分而治之的方法。

以下步驟說明如何使用分而治之的方法來解決最近配對問題。

  • 第 1 步:依 x 座標升序對點進行排序。對於具有相同 x 座標的點,按 y 座標排序。這會產生一個排序的點列表 S。
  • 步驟2:使用排序清單中的中點將S分成兩個大小相等的子集S1和S2。令中點位於 S1 處。遞歸地找到 S1 和 S2 中最接近的對。令 d1 和 d2 分別表示兩個子集中最近對的距離。
  • 步驟3:找出S1中的點和S2中的點之間最接近的對,並將它們的距離表示為d3。最接近的一對是距離為 min(d1, d2, d3).

選擇排序需要 O(n^2) 時間。步驟 1 可以在 O(n log n) 時間內完成。步驟 3 可以在 O(n) 時間內完成。設 d = min(d1, d2)。我們已經知道最近的對距離不能大於 d。為了讓S1中的點和S2中的點形成S中最接近的對,左邊的點必須在stripL中,右邊的點在stripR中,如下圖所示( A)。

對於stripL中的點p,只需考慮d X 2d矩形內的右點,如下(b)所示。矩形外的任何右點都不能與 p 形成最接近的對。由於S2中最近對的距離大於或等於d,因此最多可以有六個
矩形內的點。因此,對於stripL中的每個點,最多需要考慮stripR中的六個點。

對於stripL中的每個點p,如何定位stripR中對應的d X 2d矩形區域中的點?如果 stripLstripR 中的點按其 y 座標的升序排序,則可以有效地完成此操作。令 pointsOrderedOnY 為按 y 座標升序排序的點列表。 pointsOrderedOnY可以在演算法中預先取得。 stripLstripR 可以從步驟 3 中的 pointsOrderedOnY 取得,如下面的程式碼所示。

Image description

對於pointsOrderedOnY 中的每個點p
if (p 在 S1 且 mid.x – p.x 將 p 附加到 stripL;
else if (p 在 S2 且 p.x - mid.x 將 p 附加到 stripR;

stripLstripR中的點為{p0, p1, ... , pk}和{q0, q1, ... , qt},如圖上圖(c)。 stripL 中的點與 stripR 中的點之間最接近的對可以使用下面程式​​碼中描述的演算法找到。

d = min(d1, d2);
 r = 0; // r is the index of a point in stripR
 for (each point p in stripL) {
 // Skip the points in stripR below p.y - d
  while (r 



stripL中的點依 p0, p1, ... , pk 的順序考慮。對於 stripL 中的點 p,跳過 stripRp.y – d 下方的點(第 5-6 行)。一旦跳過某個點,就不再考慮該點。 while 循環(第 9-17 行)檢查 (p, q[r1]) 是否是可能最接近的對。這樣的 q[r1] 對最多有 6 個,因為 stripR 中兩點之間的距離不能小於 d。因此,在步驟 3 中找到最接近的對的複雜度是 O(n).

請注意,上述步驟中的步驟 1 僅執行一次以對點進行預先排序。假設所有點都已預先排序。令 T(n) 表示該演算法的時間複雜度。因此,

Image description

因此,可以在 O(n log n) 時間內找到最接近的點對。

版本聲明 本文轉載於:https://dev.to/paulike/finding-the-closest-pair-of-points-using-divide-and-conquer-2deb?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • PHP啟動錯誤:為什麼可以加載動態庫?
    PHP啟動錯誤:為什麼可以加載動態庫?
    [2遇到錯誤消息,表明未能加載動態庫。這些錯誤可能會顯著影響PHP功能,這對於迅速解決和解決這些錯誤至關重要。 此問題的一個常見原因是試圖加載未安裝的PHP擴展程序。要確定相關擴展名,請搜索PHP配置文件中包含擴展名=的行。利用GREP命令在PHP配置目錄中遞歸搜索:修改適當的配置文件,然後重新啟動...
    程式設計 發佈於2025-02-06
  • 潛入系統編程:C的初學者指南
    潛入系統編程:C的初學者指南
    探索系統編程:C 語言初學者指南系統編程涉及與計算機底層硬件和軟件交互。 C 語言是系統編程的首選語言之一,因為它能夠直接訪問硬件資源。這篇指南將帶你踏上系統編程之旅,從 C 語言基礎到實際應用案例。 C 語言基礎變量和數據類型:變量用於存儲數據。在C 中,變量必須聲明其數據類型,例如:int ag...
    程式設計 發佈於2025-02-06
  • 現代遊戲開發人員的高級JavaScript遊戲開發技術
    現代遊戲開發人員的高級JavaScript遊戲開發技術
    使用JavaScript構建遊戲比以往任何時候都更令人興奮。無論您是在編碼經典平台遊戲還是複雜的模擬,都知道如何充分利用工具,可以改變遊戲規則。本指南深入研究了JavaScript遊戲開發的基本策略和高級技術,這些技術可以幫助您提高自己的技巧。 1。遊戲開發中的網絡工作者 為什麼要使...
    程式設計 發佈於2025-02-06
  • 我可以將加密從McRypt遷移到OpenSSL,並使用OpenSSL遷移MCRYPT加密數據?
    我可以將加密從McRypt遷移到OpenSSL,並使用OpenSSL遷移MCRYPT加密數據?
    將我的加密庫從mcrypt升級到openssl 問題:是否可以將我的加密庫從McRypt升級到OpenSSL?如果是這樣?使用openssl? 答案:可以使用mcrypt數據加密數據,可以使用openssl。關於如何使用openssl對McRypt進行加密的數據: openssl_decryp...
    程式設計 發佈於2025-02-06
  • 插入資料時如何修復「常規錯誤:2006 MySQL 伺服器已消失」?
    插入資料時如何修復「常規錯誤:2006 MySQL 伺服器已消失」?
    插入記錄時如何解決“一般錯誤:2006 MySQL 服務器已消失”介紹:將數據插入MySQL 數據庫有時會導致錯誤“一般錯誤:2006 MySQL 服務器已消失”。當與服務器的連接丟失時會出現此錯誤,通常是由於 MySQL 配置中的兩個變量之一所致。 解決方案:解決此錯誤的關鍵是調整wait_tim...
    程式設計 發佈於2025-02-06
  • 在映射到MySQL枚舉列時,如何確保冬眠保留值?
    在映射到MySQL枚舉列時,如何確保冬眠保留值?
    在hibernate中保存枚舉值:故障排除錯誤的列type ,他們各自的映射至關重要。在Java中使用枚舉類型時,至關重要的是,建立冬眠的方式如何映射到基礎數據庫。 在您的情況下,您已將MySQL列定義為枚舉,並在Java中創建了相應的枚舉代碼。但是,您遇到以下錯誤:“ MyApp中的錯誤列類型...
    程式設計 發佈於2025-02-06
  • 如何使用PHP將斑點(圖像)正確插入MySQL?
    如何使用PHP將斑點(圖像)正確插入MySQL?
    在嘗試將image存儲在mysql數據庫中時,您可能會遇到一個可能會遇到問題。本指南將提供成功存儲您的圖像數據的解決方案。 easudy values('$ this-> ; image_id','file_get_contents($ tmp_imag...
    程式設計 發佈於2025-02-06
  • 如何在JavaScript對像中動態設置鍵?
    如何在JavaScript對像中動態設置鍵?
    如何為JavaScript對像變量創建動態鍵,嘗試為JavaScript對象創建動態鍵,使用此Syntax jsObj['key' i] = 'example' 1;將不起作用。正確的方法採用方括號:他們維持一個長度屬性,該屬性反映了數字屬性(索引)和一個數字屬性的數量。標準對像沒有模仿這...
    程式設計 發佈於2025-02-06
  • 我可以在CSS中使用SVG作為偽元素嗎?
    我可以在CSS中使用SVG作為偽元素嗎?
    使用svgs用作pseudo-element content css content properts允許在使用元素之前或之後使用元素插入各種類型的內容偽元素,例如::之前和::之後。但是,對可以包括哪些內容有限制。 可以將svgs用作pseudo-element Content? ,現在可以使...
    程式設計 發佈於2025-02-06
  • 對象擬合:IE和Edge中的封面失敗,如何修復?
    對象擬合:IE和Edge中的封面失敗,如何修復?
    解決此問題,我們採用了一個巧妙的CSS解決方案來解決問題:高度:100%; 高度:auto ; 寬度:100%; //對於水平塊 ,使用絕對定位將圖像定位在中心,以object-fit:object-fit :cover in IE和edge消除了問題。現在,圖像將按比例擴展,保持所需的效果而不...
    程式設計 發佈於2025-02-06
  • 可以僅使用CSS3創建六角形嗎?
    可以僅使用CSS3創建六角形嗎?
    使用純CSS3 [hexagon的圖像] 答案:是的,可以使用這樣的六邊形來創建這樣的hexagon純CSS3。為了實現這一目標,您可以使用HTML字符代碼為六角形,如下所示:& amp; amp; amp; amp; 此代碼代表Hexagon的Unicode字符。另外,您可以使用以下...
    程式設計 發佈於2025-02-06
  • 如何干淨地刪除匿名JavaScript事件處理程序?
    如何干淨地刪除匿名JavaScript事件處理程序?
    在這里工作/},false); 不幸的是,答案是否。除非在Creation中存儲對處理程序的引用。 要解決此問題,請考慮將事件處理程序存儲在中心位置,例如頁面的主要對象,請考慮將事件處理程序存儲在中心位置,否則無法清理匿名事件處理程序。 。這允許在需要時輕鬆迭代和清潔處理程序。
    程式設計 發佈於2025-02-06
  • 如何在不阻止用戶界面的情況下執行PHP中的背景過程?
    如何在不阻止用戶界面的情況下執行PHP中的背景過程?
    在php 中執行背景進程,許多Web應用程序需要執行耗時的任務,例如目錄複製。為了增強用戶體驗,希望在背景中執行這些任務,而不會破壞用戶界面。 背景過程在php中執行: exec(sprintf(“%s>%s 2>&1&1&echo $!>>%s”,$ cmd,$ utputfilefile ,...
    程式設計 發佈於2025-02-06
  • 如何克服PHP的功能重新定義限制?
    如何克服PHP的功能重新定義限制?
    克服PHP的函數重新定義限制在PHP中,多次定義一個相同名稱的函數是一個no-no。嘗試這樣做,如提供的代碼段所示,將導致可怕的“不能重新列出”錯誤。 // error:“ coss redeclare foo()” 但是,php工具腰帶中有一個隱藏的寶石:runkit擴展。它使您能夠靈活...
    程式設計 發佈於2025-02-06
  • 為什麼使用固定定位時,為什麼具有100%網格板柱的網格超越身體?
    為什麼使用固定定位時,為什麼具有100%網格板柱的網格超越身體?
    網格超過身體,用100%grid-template-columns 問題:考慮以下CSS和HTML: position:fixed ; grid-template-columns:40%60%; grid-gap:5px; 背景: #eee; 當位置未固定時,網格將正確顯示。但是...
    程式設計 發佈於2025-02-06

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3