日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

分治算法-02凸包问题

發(fā)布時(shí)間:2024/4/11 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 分治算法-02凸包问题 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

幾何問題之凸包

  • 簡(jiǎn)介
    • 簡(jiǎn)單地說,凸包是正好包含所有點(diǎn)的凸多邊形,可以將它想象為一個(gè)包圍點(diǎn)幾何的橡皮筋。之所以叫凸包是因?yàn)檫@個(gè)凸多邊形包圍所有點(diǎn)。本案例主要講解分治法解決凸包問題,常見的還有Graham掃描法、Jarvis步進(jìn)法、快包法等。
  • 問題描述
    • 給定點(diǎn)集合,輸出凸包的頂點(diǎn)集合。
  • 問題分析
    • 分治法講究分而治之,核心思想很容易理解,難的是想出實(shí)施的具體步驟。怎么把大問題拆分成小問題并且確保兩者的結(jié)構(gòu)相同,是問題的關(guān)鍵。凸包問題的分治解法不唯一,這里使用其中一種。
    • 步驟
      • 首先,連接最左端和最右端的兩點(diǎn),連接線上方的為上包,下方的為下包。同時(shí),將這兩點(diǎn)加入頂點(diǎn)集。
      • 然后,找到直線兩側(cè)距離直線最遠(yuǎn)的兩個(gè)點(diǎn),與上一步的兩個(gè)點(diǎn)相連,此時(shí)加入了四條連線,每條連線再次區(qū)分上包和下包。這里,將問題分解為4個(gè)子問題。新找出的兩點(diǎn)肯定是凸包的頂點(diǎn),將其加入頂點(diǎn)集。
      • 尋找各包中與直線距離最遠(yuǎn)的點(diǎn),連接,劃分子上包和子下包。直到上包與下包為空,終止循環(huán),輸出頂點(diǎn)集合。
    • 總結(jié)一下,首先分出上包與下包,然后找兩個(gè)最遠(yuǎn)點(diǎn)連線,再次分出兩個(gè)上包與兩個(gè)下包。在此之后,上包遞歸分出兩個(gè)子上包,下包分出兩個(gè)子下包,直到包中節(jié)點(diǎn)數(shù)小于等于1.每一次遞歸都是把最遠(yuǎn)點(diǎn)加入頂點(diǎn)集。分治的思路在于每一次遞歸只找一個(gè)頂點(diǎn),并把剩余頂點(diǎn)交給子問題,也就是子包去解決。
  • 代碼
    • # -*-coding:utf-8-*-from math import sqrtsolution = []def convex_hull(points: list):if len(points) <= 3:return pointsglobal solutionpoints.sort(key=lambda x:x[0]) # 按照橫坐標(biāo)排序left_most = points[0]right_most = points[-1]solution.extend([left_most, right_most])helper(points, left_most, right_most, True)helper(points, left_most, right_most, False)return solutiondef helper(points, left_most, right_most, upBool):""":param points::param left_most::param right_most::param upBool: 上包為True:return:"""global solutionif len(points) <= 1:returnl = line_helper(left_most, right_most)if upBool:up = []max_distance = 0max_point = ()for point in points:distance = 0-(l[0]*point[0]+l[1]*point[1]+l[2]) / sqrt(l[0]*l[0]+l[1]*l[1]) # 與直線的距離if distance > 0:up.append(point)if distance > max_distance:max_distance = distancemax_point = pointif max_point != ():solution.append(max_point)helper(up, left_most, max_point, True)helper(up, max_point, right_most, True)else:down = []min_distance = 0min_point = ()for point in points:distance = 0 - (l[0] * point[0] + l[1] * point[1] + l[2]) / sqrt(l[0] * l[0] + l[1] * l[1]) # 與直線的距離if distance < 0:down.append(point)if distance < min_distance:min_distance = distancemin_point = pointif min_point != ():solution.append(min_point)helper(down, left_most, min_point, False)helper(down, min_point, right_most, False)def line_helper(point1, point2):"""計(jì)算距離:param point1::param point2::return:"""if (point1[0]-point2[0]) != 0:m = (point1[1]-point2[1]) / (point1[0]-point2[0])c = point1[1] - m * point1[0]return [m, -1, c]else:return [1, 0, point1[0]]if __name__ == '__main__':input_points = [(0, 0), (0, 4), (-4, 0), (5, 0), (0, -6), (1, 0)]print("Input:", input_points)rst = convex_hull(input_points)print("Output", rst)
  • 運(yùn)行結(jié)果
  • 補(bǔ)充說明
    • 具體代碼可以查看我的Github,歡迎Star或者Fork
    • 對(duì)代碼進(jìn)行了一些修正
    • 參考書《你也能看得懂的Python算法書

總結(jié)

以上是生活随笔為你收集整理的分治算法-02凸包问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。