【问题标题】:How does recursion work in a divide and conquer maxima set algorithm?递归如何在分而治之的最大值集算法中工作?
【发布时间】:2017-08-19 15:12:05
【问题描述】:

这里是来自 Goodrich 的算法教科书的伪代码算法,用于在一组点中找到主要的 2D 点,称为找到最大值集:

Algorithm MaximaSet(S):

Input: A set,S,of n points in the plane

Output: The set, M, of maxima points in S 

if n ≤ 1

then return S  

Let p be the median point in S, by lexicographic (x,y)-coordinates 

Let L be the set of points lexicographically less than p in S 

Let G be the set of points lexicographically greater than or equal to p in S 

 M1 ←MaximaSet(L) 
 M2 ←MaximaSet(G) 

 Let q be the lexicographically smallest point in M2 

  for each point, r, in M1 do 

              if x(r) ≤ x(q) and y(r) ≤ y(q) 

              then Remove r from M1 

 return M1 ∪ M2

我的问题在于第 10,11 行的两个递归调用。我的理解是,第 10 行对 M1 的第一次调用会将 L 侧分成另一个 L 和 G 组,然后将下一个 L 分成另一个 L 和 G 组,直到剩下一组,下一行将运行并执行M2 的 G 侧也是如此,但现在它如何与 q 进行比较?有人可以帮我追踪这个算法的征服部分吗?

给定

(1,4) (2,6), ( 3,1) (4,5) (5,7) (6,9) (7,2), (8,6) (9,3)

我知道最大值集是 (6,9) (8,6) (9,3),但我不知道使用这个算法究竟是如何发现的。我通过蛮力解决了它。这开始是一个硬件问题,从技术上讲,我可以继续前进,因为我确实找到了答案,但我真的需要了解这一点,我已经尝试了 2 本书和谷歌,但我认为这次我需要一个人。提前谢谢你,因为这是我第一次在堆栈上,请不要犹豫(请)给我任何更正我如何提出我的问题或提出我的 p 代码

【问题讨论】:

    标签: algorithm recursion divide-and-conquer


    【解决方案1】:

    征服部分的想法是,你必须假设返回的集合 M1 & M2 满足这个条件:

    同一集合中的任何一对点都可以共存

    也就是说,集合中的任何一对点都必须满足x1 < x2 && y1 > y2

    在你合并M1和M2之后,你也应该返回一个满足这个条件的集合,最后我们得到的集合就是答案。

    需要注意的一点是,我认为合并时,x实际上不需要比较,因为M1中的所有点都应该有xM2中的那些点


    我们使用q,M2 中的第一个点与M1 中的所有点进行比较,因为

    1. 如前所述,q 不需要与M2 中的其他元素进行比较
    2. 视觉上,q是M2中x最小和y最大的点,如前所述,所有M1的x应该小于M2中的所有点,所以这里的要点是q 在M2 中具有最大的y,因此在M1 中覆盖(消除)点的最大“潜力”

    结合1和2,该算法使用q比较M1中的所有点以试图消除无望的候选人,并将剩下的与M2联合形成一个满足上述条件的新集合。


    让我们用你的例子做一个演示:

    除法: (1,4) (2,6) (3,1) (4,5) (5,7) (6,9) (7,2) (8,6) (9,3); L = (1,4) (2,6), (3,1) (4,5) (5,7); R = (6,9) (7,2), (8,6) (9,3)

    除法: (1,4) (2,6) (3,1) (4,5) (5,7); L = (1,4) (2,6), (3,1); R = (4,5) (5,7)

    除法: (1,4) (2,6) (3,1); L = (1,4) (2,6); R = (3,1), 返回 {(3,1})

    除法: (1,4) (2,6); L = (1,4); 返回 {(1,4)}; R = (2,6); 返回 {(2,6)}

    除法: (4,5) (5,7); L = (4,5); 返回 {(4,5)}; R = (5,7); 返回 {(5,7)}

    征服: (1,4) (2,6); M1 = {(1,4)}; M2 = {(2,6)} q = (2,6); 返回合并集 = {(2,6)}

    征服: (1,4) (2,6) (3,1); M1 = {(2,6)}; M2 = {(3,1)}; q = (3,1); 返回合并集 = {(2,6), (3,1)}

    征服: (4,5) (5,7); M1 = {(4,5)}; M2 = {(5,7)}; q = (5,7); 返回合并集 = {(5,7)}

    征服: (1,4) (2,6) (3,1) (4,5) (5,7); M1 = {(2,6), (3,1)}; M2 = {(5,7)}; q = (5,7); 返回合并集 = {(5,7)}

    除法: (6,9) (7,2) (8,6) (9,3); L = (6,9) (7,2); R = (8,6) (9,3)

    除法: (6,9) (7,2); L = (6,9); 返回 {(6,9}); R = (7,2); 返回 {(7,2)}

    除法: (8,6) (9,3); L = (8,6); 返回 {(8,6)}; R = (9,3), 返回 {(9,3)}

    征服: (6,9) (7,2); M1 = {(6,9)}; M2 = {(7,2)}; q = (7,2); 返回合并集 = {(6,9), (7,2)}

    征服: (8,6) (9,3); M1 = {(8,6)}; M2 = {(9,3)}; q = (9,3); 返回合并集 = {(8,6), (9,3)}

    征服: (6,9) (7,2) (8,6) (9,3); M1 = {(6,9), (7,2)}; M2 = {(8,6), (9,3)}; q = (8,6); 返回合并集 = {(6,9), (8,6), (9,3)}

    征服: (1,4) (2,6) (3,1) (4,5) (5,7) (6,9) (7,2) (8,6) (9,3); L = (1,4) (2,6) (3,1) (4,5) (5,7); M1 = {(5,7)}, M2 = {(6,9), (8,6), (9,3)}; q = (6,9); 返回合并集 = {(6,9), (8,6), (9,3)}

    ==> 返回 {(6,9), (8,6), (9,3)}

    【讨论】:

    • 这是一个了不起的答案,shole,我非常感谢你抽出时间来做这个!我现在明白了。非常感谢,我已经接受了你的回答。
    猜你喜欢
    • 2016-05-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-08
    • 2019-05-16
    • 2019-08-08
    • 2020-04-11
    • 1970-01-01
    • 2018-03-25
    相关资源
    最近更新 更多