【发布时间】:2020-06-21 13:33:09
【问题描述】:
我有一堆由它们的方向描述的线以及一个描述其起源的点。我必须将这些线组合起来,使它们形成可以位于彼此内部的矩形,但它们的边缘不能重叠。我也知道线条的原点位于矩形的边缘内,但不一定位于该边缘的中间。基本上我的输入可能是这样的:
而我想要达到的效果是这样的:
现在每条线都由与其他线相交以形成正确矩形的点来描述。
我正在寻找一种算法来找到相关的交点并将它们链接到描述矩形的线。
【问题讨论】:
我有一堆由它们的方向描述的线以及一个描述其起源的点。我必须将这些线组合起来,使它们形成可以位于彼此内部的矩形,但它们的边缘不能重叠。我也知道线条的原点位于矩形的边缘内,但不一定位于该边缘的中间。基本上我的输入可能是这样的:
而我想要达到的效果是这样的:
现在每条线都由与其他线相交以形成正确矩形的点来描述。
我正在寻找一种算法来找到相关的交点并将它们链接到描述矩形的线。
【问题讨论】:
首先,如前所述,这个问题可能有多种解决方案。例如,我没有看到任何使以下内容无效的约束:
所以,你需要定义一个目标,例如:
在这里,我尝试使用贪婪的方法来最大化矩形的数量。请记住,贪心算法永远不会保证找到最优解,而是在合理的时间内找到次优解。
现在,我的算法有两个步骤:
第 1 步:找到所有可能的矩形
两条垂直线(l & r)加上两条水平线(b & t)可以形成一个有效的矩形,如果:
l.x < r.x and b.y < t.yl.y and r.y are between b.y and t.yb.x and t.x are between l.x and r.x在下面的伪代码中,Xs 和 Ys 分别是垂直和水平线的排序列表:
function findRectangles
for i1 from 1 to (nx-1)
for i2 from (i1+1) to nx
for j1 from 1 to (ny-1)
if (Ys[j1].x>=Xs[i1].x and
Ys[j1].x<=Xs[i2].x and
Ys[j1].y<=Xs[i1].y and
Ys[j1].y<=Xs[i2].y)
for j2 from (j1+1) to ny
if (Ys[j2].x>=Xs[i1].x and
Ys[j2].x<=Xs[i2].x and
Ys[j2].y>=Xs[i1].y and
Ys[j2].y>=Xs[i2].y)
add [i1 j1 i2 j2] to results
end if
end for
end if
end for
end for
end for
end
第 2 步:选择有效矩形
有效的矩形,如问题中所述,不能部分重叠,也不能共享边。在上一步中,找到了太多的矩形。但是,正如我之前所说,这些矩形的组合可能不止一种满足约束条件。为了最大化矩形的数量,我建议使用以下倾向于接受较小矩形的算法:
function selectRects( Xs, Ys, rects )
results[];
sort rectangles by their area;
for i from 1 to rects.count
if (non of edges of rects[i] are eliminated)&
(rects[i] does not partially overlap any of items in results)
add rects[i] to results;
Xs[rects[i].left].eliminated = true;
Xs[rects[i].right].eliminated = true;
Ys[rects[i].bottom].eliminated = true;
Ys[rects[i].top].eliminated = true;
end if
end for
end
【讨论】: