【问题标题】:Simple algorithm (pseudo-code) for line segment intersection线段相交的简单算法(伪代码)
【发布时间】:2012-06-04 19:17:55
【问题描述】:

我正在尝试解决这个问题,但我被困在如何完成这项工作上。我将发布问题,然后解释我在其中的位置。

给定一组总大小为 n 的水平线段和垂直线,我们要计算每条垂直线相交的水平线段数。该算法的复杂度应该是 O(n*logn),并且应该通过排序来实现,然后是线性扫描。水平线段由两个 x 坐标和一个 y 坐标指定,而垂直线由单个 x 坐标指定。输出是一个数字数组 count[l],每个垂直线 l 一个。

对于排序,我想我会按照最早完成的行(即最小的第二个 x 坐标,或者在垂直线的情况下,只是它的一个 x 坐标)对整个集合进行排序,这样我就有了通过所有线的线性进展。我只是对如何进行排序后的线性扫描感到困惑。如果有人有任何提示、提示或指南,我将不胜感激!

PS:这是期中练习,虽然不一定是作业,但我还是会这样标记。

【问题讨论】:

    标签: algorithm pseudocode


    【解决方案1】:

    问题可以写成其他方式:

    对于每个水平线段 (x1,x2),找到与其相交的所有垂直线。您可以通过对获得一组位置 x 的垂直线进行排序来做到这一点。

    现在,运行二分查找并在 x 的集合中定位 x1,我们称其位置为 p1。对 x2, p2 执行相同的操作。给定段的交点数等于 p2-p1。

    对所有水平段执行此操作。

    对垂直线段进行排序将花费 O(klog(k))。每次搜索都在 O(log(k)) 中完成,并且对每个段进行两次:O(mlog(k))。其中 k 是垂直线的数量,m 是水平线段的数量。 n = m+k > m,k 因此,整体复杂度为 O(nlogn)。

    【讨论】:

    • 嗯,我有点困惑。例如,如果您有一条水平线 (2,6) 和一条垂直线 (5),对 2 和 6 进行二分搜索,您将得到一组 (2,5,6),其中 p1 = 0 和 p2 = 2,对吗?然后使用 p2-p1+1 你会得到 3,而不是答案只有 1。我误解了什么吗?
    • 不,我在这里犯了一个错误。没有想通。不过,正确的值应该不难找到。结果是 p1 = 0,p2 = 1 而不是 2。您需要处理两种情况,一种是 binary_search 找到值时,另一种是 binary_search 返回空槽时。我太困了,无法解决这个问题,但应该不难猜到:)
    • 另外,我相信用这种方法想出每条垂直线穿过的水平线的数量有点困难,这是期望的输出。
    • 当然可以 :) 如果线段与线相交,则线与线段相交。这是一个双射。每当一个线段与一条线相交时,只需增加相应的计数器。在算法结束时,您将获得计数数组。正如我所说,我现在有点累。我明天实现这个并推送到这里。
    • 嗯,我对您的解决方案的设想是,在排序之后,我将有 1 个循环遍历所有水平线段,并且每次迭代执行 2 次二进制搜索并得出垂直数穿过当前水平线段的线。我没有看到一种简单的方法来识别哪些垂直线相交。我认为您可以添加另一个循环来增加所有 n“p1
    【解决方案2】:

    首先,您放置水平线段的所有起点/终点。和垂直线的 x 坐标。

    其次,对它们进行排序。我们将排序列表称为L

    第三,成像有一条垂直扫描线,从你点列表的最左边L开始,向右移动。

    当扫描线碰到一点时,它要么是水平线段的起点,要么是水平线段的终点,要么是垂直线。

    移动扫描线时可以做两件事:

    1) 保留扫描线当前相交的水平线段集合(当它是水平线段的起点/终点时,将其添加到集合中/从集合中删除)

    2) 只要​​它是一条垂直线,您就知道垂直线与您在 1) 中维护的集合中的所有水平线段相交

    所以,排序是 O(nlogn);在排序列表L中移动扫描线是O(n)

    总而言之,它是 O(nlogn)

    【讨论】:

    • 我有点困惑如何在算法中实现这一点,同时保持复杂性要求。每个点只是水平线段的一组 (x1,x2) 和垂直线的 (x)。如果你将所有的点分解并放在一个列表中,你怎么知道哪一个是开始/结束/垂直线?
    • @Tesla 一种直观的方法是创建一个结构,比如Point,它有两个字段,一个字段是坐标,另一个表示它是起点、终点还是垂线。所以你可以根据第一个字段对Point的列表进行排序,然后根据第二个字段检查它是什么。
    猜你喜欢
    • 2010-12-14
    • 2016-08-08
    • 2019-01-07
    • 1970-01-01
    • 1970-01-01
    • 2010-12-05
    • 2011-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多