关于三角形和凸包的一些思考
忽略任何具有 2 个或更少点和 3 个点的集合总是给出 1 个三角形。
现在是降低上限的困难部分
walk through the inner points using them as center for all triangles.
If any triangle is empty we can save a triangle by removing the hull edge.
if two or more adjacent triangles are empty we will have to keep every other triangle or join the 3 points to a new triangle, as the middle point can be left out.
note the best result.
这位教授是不是没有更好的结果?不。
如果存在一个包围所有剩余点的三角形,那就更好了。
N = number of points
U = upper bound
L = lower bound
T = set of triangles
R = set of remaining points
A = set of all points
B = best solution
BestSolution(A)
if A < 3 return NoSolution
if A == 3 return A
if not Sorted(A) // O(N)
SortByX(A) // O(n lg n) or radex if possible O(N)
H = ConvexHull(A)
noneHull = A - H
B = HullTriangles(H, noneHull) // removing empty triangles
U = size B
if noneHull == 0
return U // make triangles of 3 successive points in H and add the remaining to the last
if U > Roundup(N/3)
U = Roundup(N/3)
B = MakeIndepenTriangles(A)
AddTriangle(empty, A)
return // B is best solution, size B is number of triangles.
AddTriangle(T, R)
if size T+1 >= U return // no reason to test if we just end up with another U solution
ForEach r in R // O(N)
ForEach p2 in A-r // O(N)
ForEach p3 in A-r-p2 // O(N)
t = Triangle(r, p2, p3)
c = Candidate(t, T, R)
if c < 0
return c+1 // found better solution
return 0
Candidate(t, T, R)
if not Overlap(t, T) // pt. 3, O(T), T < U
left = R-t
left -= ContainedPoints(t) // O(R) -> O(N)
if left is empty
u = U
U = size T + 1
B = T+t
return U-u // found better solution
return AddTriangle(T+t, left)
return 0
所以……总运行时间……
候选人 O(N)
加三角形 O(N^3)
递归仅限于当前最优解 U
O((N N^3)^U) -> O((N^4)^U)
空间是 O(U N)
因此,在我们使用蛮力之前减少 U 是必不可少的。
- 快速减少 R 应该减少递归
- 所以从更大的并且希望更多的封闭三角形开始会很好
- 船体中的任何 3 点都应该是一些不错的候选者
- 这些将剩余的点分成 3 个部分,可以独立调查
- 将每个部分视为一个外壳,其中它的 2 个基点是三角形的一部分,但第 3 个基点不在集合中。
- 如果可能,将其设为 BFS,以便我们首先选择最封闭的
- 空间可能是个问题
- O(HUN)
- 否则首先从船体周围 1/3 的点开始。
AddTriangle 真的很糟糕,所以我们真的可以制作多少个三角形
从 N 中选择 3 是
N!/(N-3)!
而且我们不关心订单所以
N!/(3!(N-3)!)
N!/(6(N-3)!)
N (N-1) (n-2) / 6
对于循环来说仍然是 O(N^3),但它让我们感觉更好。如果排列时间过长,循环可能仍然更快。
AddTriangle(T, R)
if size T+1 >= U return // no reason to test if we just end up with another U solution
while t = LazySelectUnordered(3, R, A) // always select one from R first O(R (N-1)(N-2) / 6) aka O(N^3)
c = Candidate(t, T, R)
if c < 0
return c+1 // found better solution
return 0