给定一组线中的平行线数
Posted
技术标签:
【中文标题】给定一组线中的平行线数【英文标题】:Number of parallel lines in a given set of lines 【发布时间】:2015-12-05 19:39:20 【问题描述】:给了我 N 行,也就是说,给了我 N 行的 a,b,c。每条线的形式为 ax + by + c = 0。我需要找出相互平行的线的最大数量。
为此,首先我创建比率 A/B (-slope) 和 C/B (-intercept) 的二维数组,除了 b == 0(我将斜率设为 1/eps ,我已将 eps 定义为一个非常小的正数)。
然后我删除 $O(n^2)$ 复杂度中的重复条目。
我再次进行 $O(N^2)$ 扫描以查找给定斜率存在多少条线并报告最大数量。
事实证明,这是一种较慢的方法。我怎样才能让它更快?
另外,我正在用 C++ 编写代码。
【问题讨论】:
两个部分都不是 O(n^2),而是先使用 O(nlogn) 算法对其进行排序,然后使用线性搜索。 而且,由于浮点数的怪癖,准确的结果不要使用浮点数/双精度数。垂直线的特殊情况,以及其余部分的比率(即 a/b 作为两个数字)...... lcm 等。 【参考方案1】:您可以通过简单地使用散列在线性时间 $O(n)$ 内做您想做的事情。你将为每一行做两个哈希。第一个处理斜坡。因此,您将构建一个散列,将线条分成不同斜率的桶。第二个哈希将具有相同斜率的线与具有不同截距的线分开。
正如 deviantfan 特例 b==0 所建议的那样。让我们先处理那个案例。如果 b==0,则所有线的斜率相同,将它们全部扔到同一个斜率桶中。如果 b!=0,计算您的斜率 A/B 并对其进行散列以获得唯一的斜率桶。请注意,您可能会在坡度桶中遇到一些碰撞,您可以使用任何标准方法来处理它(例如,使用不同函数的坡度二级散列,或者如果您不这样做,则简单地在桶中构建坡度的二叉树心灵冲突是 $O(n*log(n))$)。
好的,此时您的线应该在一个唯一的斜率桶中,现在散列截距 C/A(对于 b=0 和 a!=0)或 C/B(对于 b!=0)和 a (a=0 和 b=0,其中 c=0 是要求的特殊存储桶——做代数向自己证明这一点)。这将允许您找出给定斜率桶内的不同线 - 每条不同的线将在截取时位于不同的哈希桶中。当然,同样,您可能必须处理来自哈希的冲突,并且同样的技术也适用。
如果您跟踪每个唯一斜率存储桶中有多少个唯一截距存储桶,则可以对斜率存储桶进行线性搜索以找到最大的数字。在构建结构并跳过最终搜索时,您也可以简单地保留一对 (max value (of intercept buckets), slope)。这不会改变渐近复杂度,因为所有操作都是线性的。
最后唯一需要注意的是浮点运算的变幻莫测。我不清楚您是否想要对斜率和截距计算的不等式进行真正的比较,或者您是否可能想要进行某种形式的舍入来处理 1.99999 ... =? 2.0。当 A 或 B 非常大或非常小时也可能存在问题。这在很大程度上取决于您的应用程序。
【讨论】:
以上是关于给定一组线中的平行线数的主要内容,如果未能解决你的问题,请参考以下文章
给定一组参数,如何将这些参数发送到 Ruby 中的特定函数?