【问题标题】:How to find the furthest point from other given points in Java如何在Java中找到距其他给定点最远的点
【发布时间】:2019-05-29 20:10:14
【问题描述】:

我有一个给定的 S 点(图表上的红色)和 n 个其他点(图表上的黑色)。我想找到一个点 P,距离 S 为 1,距离所有黑点最远(在这种情况下 - S 之间的距离总和strong>P,每个点都应该是最高的)。

由于 PS 相差 1,我们可以看出 y = √(1 - x^2)

我个人使用的分析方法是:

  1. 计算距离的总和
    • Q - P = √((Qx - Sx - x)^2 + (Qy - Sy - √(1 - x^2))^2)(重复所有n个点并总结),
  2. 计算得到的表达式的导数,
  3. 计算导数的根并找到最大值(在域中),
  4. 计算域中区间末端的值,
  5. 选择正确的 X。

在 Java 中最有效的方法是什么?可以使用哪些库?我听说图书馆允许进行这种分析,但听起来很复杂而且速度很慢,所以我一直在寻找任何数字想法,但找不到。

【问题讨论】:

  • 基本上,您有两个选择:1) 将圆圈上的点表示为(cos t, sin t) 并将其插入您的目标。然后,找到该一维目标的最大值。 2)为约束添加Lagrange Multipler,并使用数值优化方法找到3D目标的最大值(查看维基百科页面的示例1a)。

标签: java math optimization geometry


【解决方案1】:

以小增量跟随圆圈的路径。计算沿圆的每个点的距离总和。找到距离总和最大的位置。完毕。 java.lang.Math 就足够了。不需要额外的库。查找三角函数。

SP 段的角度为 phi。你从 0 到 2*pi (记住它使用弧度)。在循环中使用一个小数增加 phi。

类似:

  • phi=0.0;
  • maxSumDistance = 0.0;
  • phiAtMaxValue = 0.0;
  • 做一个循环:phi 从 0.0 变为 2*pi,每次向 phi 添加一个小数
  • 在循环内部:if (currentSumDistance > maxSumDistance) then maxSumDistance = currentSumDistance;和 phiAtMaxValue = phi 的当前值(循环变量);

在循环结束时,您将获得距离总和最大的 phi 角值。然后你从 phi 重新计算 P 的坐标,以及 SP 的距离。

这可能是一种蛮力方法,但为此计算导数似乎有点过头了,而且太复杂了。

【讨论】:

  • 这是一个O(n^2) 解决方案(围绕圆圈的步数乘以检查距离的点数),如果有更多点或者您想要更高的精度,它会快速增长。此外,根据您选择的粒度弧度长度,您可能会达到远离实际最大值的局部最大值。我觉得必须有一个成本更低的解决方案。
【解决方案2】:

首先,对于这个问题,在最坏的情况下,O(N^2) 似乎并没有那么糟糕。因为每次调用成本函数都会花费 O(N)。考虑这种情况:N 个黑点位于另一个圆(R > 1,S 中的中心)上,并将这个新圆分成 N 个相等的弧。在这种对称情况下,我们有 N 个最大值。只是为了检查它们,它需要 O(N^2)——计算每个点的成本函数。所以我认为任何检查所有局部极值的算法在最坏的情况下至少有 O(N^2)。

这是我针对一般情况的解决方案草图:

  • 如果 {Q_j} 是黑点,让我们定义 {O_j},这样每个 O_j 都是离 Q_j 最近的点,Q_j 位于 S 周围的红色圆圈上。点 {O_j} 将圆圈分成 n 个弧.我们可以很容易地计算出每个 O_j 坐标。

  • 似乎我们试图优化的成本函数在每条弧内只有一个局部极值(这部分需要更准确的证明),所以我们可以通过三元搜索找到这些极值——线性复杂度。我们还需要检查 O_j 的局部极值——线性复杂度。

  • 总的来说,我们必须检查 O(NlogN) 个点,每次检查花费 O(N)。至少这种方法比用小epsilon检查圆上的每个点更方便。

【讨论】:

    【解决方案3】:

    编辑:下面的算法不像 cmets 中解释的那样工作。我会留在这里作为参考。

    这可能有点幼稚,但是怎么样:

    • 求所有黑点的平均值。这可以很简单 sum(x-coord)/n 和 sum(y-coord)/n。这个“平均”点很可能 不要在圈子上。我们称这个点为“A”
    • 从这里画一条线 朝向 S 的平均点 = |AS|
    • 继续沿着这条线 角度,直到你到达 S 另一边的圆圈。让我们打电话 此点 O(相反)。您现在有了|ASO| 行。
    • O 可以计算,因为你知道圆的半径是 1,根据定义,这个点是红圈上离平均点 A 最远的点,从这里它不会跟随圆上的其他点是 远离所有黑点。

    极端情况:如果所有黑点都围绕原点对称(例如,一个点在 -2,-2,一个点在 2,2;那么上面的解决方案将没有答案,因为 A(平均点)将等于 S(原点 0,0)。您可以额外检查 A 是否等于 S,然后抛出异常。

    【讨论】:

    • 反例:如果我们在圆的左边有很多距离很近的点,而在右边有一个距离很远的点,我们希望答案是一个点在圆圈的右侧。但是,平均值将被拉向右侧,这种方法将以圆圈左侧的一个点作为答案。不过,不确定如果我们用几何中位数代替平均值会发生什么。
    • 您使用模糊的术语“很多点”和“小距离”与“非常大的距离”。我不相信平均点“不在它应该在的一边”。如果左边的点太多以至于右边的单个点变得无关紧要,那么数学就会检查出来。如果左侧没有足够的点以使单个点变得相关,那么数学仍然会检查。平均值是正确的平均值。
    • 好的,让我们再具体一点。假设我们在(-2, 0) 有9 个点,在(100, 0) 有一个点。平均值为(8.2, 0),得到答案(-1, 0)。如果我们检查一下,我们会看到所有点到(-1, 0) 的总距离是110。所有点到(1, 0) 的总距离为126
    猜你喜欢
    • 2019-06-06
    • 1970-01-01
    • 1970-01-01
    • 2021-08-20
    • 1970-01-01
    • 2011-06-04
    • 1970-01-01
    • 2022-10-13
    • 1970-01-01
    相关资源
    最近更新 更多