我有一个边界框,里面有很多点。我想添加另一个点,其位置距离任何先前添加的点最远,并且远离盒子的边缘。
这种事情有共同的解决方案吗?谢谢!
答案 0 :(得分:11)
这是一个小Mathematica计划。
虽然只有两行代码(!),但您可能需要更多传统语言,以及能够找到最多功能的数学库。
我认为你不熟练掌握Mathematica,所以我会逐行解释和评论。
首先,我们在{0,1} x {0,1}中创建一个包含10个随机点的表,并将其命名为 p 。
p = Table[{RandomReal[], RandomReal[]}, {10}];
现在我们创建一个最大化的函数:
f[x_, y_] = Min[ x^2,
y^2,
(1 - x)^2,
(1 - y)^2,
((x - #[[1]])^2 + (y - #[[2]])^2) & /@ p];
哈!语法变得棘手!我们来解释一下:
该函数为您提供{0,1} x {0,1}中最小距离的任意点,从该点到我们的集合p和边缘。前四个术语是到边缘的距离,最后一个(难以阅读,我知道)是一个包含到所有点的距离的集合。
接下来我们要做的是最大化这个函数,所以我们将获得最大距离到目标的最小距离。
但首先让我们来看看f []。如果你批判地看一下它,你会发现它不是真正的距离,而是距离的平方。我这样定义它,因为这样功能更容易最大化,结果是相同的。
另请注意,f []不是“漂亮”功能。如果我们在{0,1}中绘制它,我们得到类似的东西:
这就是为什么你需要一个很好的数学包来找到最大值。
Mathematica是一个非常好的包,我们可以直接最大化:
max = Maximize[{f[x, y], {0 <= x <= 1, 0 <= y <= 1}}, {x, y}];
就是这样。最大化函数返回点,并将平方距离返回到最近的边界/点。
HTH!如果您需要帮助翻译成另一种语言,请发表评论。
修改
虽然我不是C#人,但在搜索了SO和谷歌搜索引用后,来到这里:
一个候选包是DotNumerics
您应该遵循包中提供的以下示例:
file: \DotNumerics Samples\Samples\Optimization.cs
Example header:
[Category("Constrained Minimization")]
[Title("Simplex method")]
[Description("The Nelder-Mead Simplex method. ")]
public void OptimizationSimplexConstrained()
HTH!
答案 1 :(得分:4)
您要解决的问题的名称是the largest empty sphere problem。
它可以在平面中的O(n ^ 4)时间内轻松解决。只需考虑所有O(n ^ 3)点的三元组并计算它们的外心。其中一点是你想要的点。 (嗯,在你的情况下,你还必须考虑“一方”作为你的三个点之一,所以你不仅要找到外围中心,而是稍微更一般的点,比如从两点和一侧等距离。)
如上面的维基百科链接所示,通过计算Voronoi图也可以在O(n log n)时间内解决问题。更具体地说,那么你想要的点是你的点的Delaunay三角剖分中的一个三角形的外心(这是Voronoi图的对偶),其中只有O(n)。 (同样,为了完全适应你的问题,你必须考虑盒子两侧的效果。)