算法 Hw5

本文详细解释了分治策略在匹配螺丝螺母问题、复数乘法算法以及解决最近邻问题(ClosestPairProblem)中的应用,涉及递归、Kd-Tree算法及时间复杂度分析。
摘要由CSDN通过智能技术生成

1 Nuts and Bolts

边界条件:当只有一个螺丝和一个螺母时,匹配螺丝和螺母。

Divide
将螺丝集合记为 A = {   a 1 , a 2 , a 3 . . .   } A=\set{a_1,a_2,a_3...} A={a1,a2,a3...}
将螺母集合记为 B = {   b 1 , b 2 , b 3 . . .   } B=\set{b_1,b_2,b_3...} B={b1,b2,b3...}

  • 先在螺丝集合 A A A 中,随机选中一个螺丝 a 1 a_1 a1,将 a 1 a_1 a1 与所有螺母 B B B 进行匹配,并将螺母分为 3 3 3 类:螺丝 > > > 螺母的放入集合 B 1 B_1 B1;螺母 > > > 螺丝的放入集合 B 2 B_2 B2;和 a 1 a_1 a1 匹配的螺母 b 1 b_1 b1
  • 再将 b 1 b_1 b1 与 除去螺丝 a 1 a_1 a1外的所有螺丝 A − {   a 1   } A-\set{a_1} A{a1} 相匹配,可将螺丝分为 2 2 2 类:螺母 > > > 螺丝的集合 A 1 A_1 A1;螺丝 > > > 螺母的集合 A 2 A_2 A2

至此,即将螺丝螺母分为以下几部分:

相匹配
螺丝 A A A A 1 A_1 A1 {   a 1   } \set{a_1} {a1} A 2 A_2 A2
螺母 B B B B 1 B_1 B1 {   b 1   } \set{b_1} {b1} B 2 B_2 B2

Conquer:递归地对 A 1 A_1 A1 B 1 B_1 B1 A 2 A_2 A2 B 2 B_2 B2 进行匹配。

Merge:返回 A 1 A_1 A1 B 1 B_1 B1 A 2 A_2 A2 B 2 B_2 B2的匹配结果以及匹配对 ( a 1 , b 1 ) (a_1, b_1) (a1,b1)

复杂度

  • Divide 代价 O ( n ) O(n) O(n)
    • a 1 a_1 a1 与所有螺母 B B B 进行匹配 代价为: O ( n ) O(n) O(n)
    • b 1 b_1 b1 与 除去螺丝 a 1 a_1 a1外的所有螺丝 A − {   a 1   } A-\set{a_1} A{a1} 相匹配 代价为: O ( n ) O(n) O(n)
  • Conquer 代价 T ( ∣ A 1 ∣ ) + T ( n − 1 − ∣ A 1 ∣ ) T(|A_1|)+T(n-1-|A_1|) T(A1)+T(n1A1),其中 ∣ A 1 ∣ |A_1| A1 0 , 1 , … , n − 1 0,1,…,n-1 0,1,,n1 的概率均为 1 n \frac{1}{n} n1
  • Merge 代价:不计算

所以,总体代价为 O ( n l o g n ) O(nlogn) O(nlogn)


2 Complex Number Multiplication

已知:
( a + b i ) ( c + d i ) = ( a c − b d ) + ( a d + b c ) i (a+bi)(c+di)=(ac-bd)+(ad+bc)i (a+bi)(c+di)=(acbd)+(ad+bc)i

三次实数乘法为:
M 1 = ( a + b ) ⋅ c = a c + b c M_1=(a+b)\cdot c=ac+bc M1=(a+b)c=ac+bc
M 2 = b ⋅ ( c + d ) = b c + b d M_2=b\cdot (c+d)=bc+bd M2=b(c+d)=bc+bd
M 3 = ( a − b ) ⋅ d = a d − b d M_3=(a-b)\cdot d=ad-bd M3=(ab)d=adbd

有:
实部: M 1 − M 2 M_1-M_2 M1M2
虚部: M 2 + M 3 M_2+M_3 M2+M3


Closest-Pair Problem

1

蛮力解决:遍历 n n n 个点与剩余 n − 1 n-1 n1 个点,计算点对距离,并更新最短距离,遍历完所有点对后即可求得最短点对距离。

复杂度 O ( n 2 ) O(n^2) O(n2)


2

边界条件:点集合 P P P 中仅含有 3 3 3 个点,返回最近点对。

Divide

  • 先找到 P P P x x x坐标的中位数 x m x_m xm
  • 用直线 l : x = x m l:x=x_m l:x=xm 将集合 P P P 分为左右两部分: P 1 P_1 P1 P 2 P_2 P2

Conquer

  • 递归地找到 P 1 P_1 P1 P 2 P_2 P2 中的最近点对:两个点对之间的距离为 d 1 d_1 d1 d 2 d_2 d2
  • d = min ⁡ {   d 1 , d 2   } d=\min\set{d_1,d_2} d=min{d1,d2}

Merge

在点横坐标 x i x_i xi 满足 x m − d < x i < x m + d x_m-d<x_i<x_m+d xmd<xi<xm+d 的临界区内(将满足要求的点集合记作 Q Q Q

  • 将点按照纵坐标 y i y_i yi 排序
  • 对于 Q Q Q 中每一个点 q i q_i qi,寻找 Q Q Q 中:点纵坐标 y j y_j yj 满足 y i − d < y j ≤ y i y_i-d<y_j\leq y_i yid<yjyi 的点,集合记作 R i R_i Ri
  • 计算 q i q_i qi R i R_i Ri 中所有点的距离,并更新最短距离,直至 Q Q Q 中每一个点均被遍历

复杂度

  • Divide 代价 O ( n ) O(n) O(n)
  • Conquer 代价 2 T ( n 2 ) 2T(\frac{n}{2}) 2T(2n)
  • Merge 代价 O ( n ) O(n) O(n)

所以根据主定理求解有:总代价 T ( n ) = O ( n l o g n ) T(n)=O(nlogn) T(n)=O(nlogn)


3

Kd-Tree算法

构建Kd-Tree

  • 在选择维度进行划分时,选择具有最大方差的维度,因为这意味着数据的分布较为分散,更容易划分。再选择该维度上所有数据的中值,将元素与中值进行比较,即可划分为两个子集合。同时创建一个树结点,用于存储划分维度和划分值。
  • 对两个子集不断重复上述步骤直至不能再划分,将子集合中的数据保存到叶子结点。

查找最近邻

  • 找到每个叶子结点上保存的数据中距离最小值,并不断更新遍历。
  • 再根据不同分支之间的距离与其比较,判断是否有不同分支的两点距离更近。
  • 从下往上逐层进行回溯。

  • 25
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值