考虑这种布局:
+-------------+ | | | | | +--+ | | |##| | | |##| | | +--+------+ | |######| | |######| +------+------+
黑色部分是占用空间。现在我需要一个返回最大剩余矩形空间的算法。 (从上到下,从左到右排序。)
像这样:
1 2 3 4 +-------------+ +---- -------+ |#############| |### ######| |#############| |### ######| | +--+ | |###+ +######| |###| |######| |###| |######| |###+ +------| | +--+ |### |######| |### |######| +---- +------+
封闭容器的宽度和高度。 (我的代码中的一页。)
已占用矩形的列表。它们可以是您喜欢的任何形式。 E.g。 (x,y,宽度,高度)或(x1,y1,x2,y2)
我正在处理花车,因此首选数学解决方案。
答案 0 :(得分:6)
从您的示例中可以看出,您并不是要求排除重叠(例如,1和2有左上角的分段),所以这可能符合您的需求:
根据占用空间所标识的角落将空间划分为矩形。
通过将线段从这些角延伸到整个空间的边缘来形成“基本矩形”。
使用任何系统的订单(例如从上到下,从左到右):
3.1。选择一个基本矩形,并尽可能将其扩展到具有共同边的其他基本矩形。
3.2。形成所有(唯一的)这种扩展矩形的集合。
请注意,这会根据步骤2中的“基本矩形”进行搜索/构建,而不是逐点遍历整个空间,因此性能应该更好。
答案 1 :(得分:1)
请原谅我写代码:
for(int y = 0; y < rows; y++){
for(int x = 0; x < columns; x++){
// (x, y) would be the current space
if(checkEmptySpace(x,y)){
// empty space found
}
}
}
这是最简单直接的方法。但不好的一点是,它必须遍历可能导致效率低下的所有空间。
简易:
答案 2 :(得分:1)
char mark = 'A';
for(i from 0 to rows)
colstart = 0;
while(colstart = next empty col in ith row)
width = 0;
for(j from colstart to columns)
{
if(empty)
width++;
else
break;
}
if(width == 0)
continue
for(n from colstart to colstart + width)
for(m from i to rows)
if(!empty)
break;
if(m != i)
set the rectangle from i, colstart to m - 1, colstart + width
with mark char and increment mark;
更新:java代码。
public class Program
{
public static char occuppied;
public static char vacant;
public static char mark;
public static void main(String[] args)
{
int rows = 7;
int cols = 11;
mark = 'A';
occuppied = '#';
vacant = '-';
char[][] matrix = new char[rows][cols];
setRect(matrix, vacant, 0, 0, rows, cols);
setRect(matrix, occuppied, 3, 3, 2, 2);
setRect(matrix, occuppied, 5, 5, 2, 6);
print(matrix);
for(int i = 0; i < rows; i++)
{
int colstart = 0;
while((colstart = nextEmptyCol(matrix[i], colstart)) != -1)
{
int width = 0;
for(int j = colstart; j < cols; j++)
{
if(matrix[i][j] == vacant)
width++;
else
break;
}
if(width == 0)
continue;
int height = 1;
outer:
for(; height + i < rows; height++)
for(int n = 0; n < width; n++)
{
if(matrix[i + height][colstart + n] == occuppied)
break outer;
}
System.out.println("width = " + width + ", height = " + height);
setRect(matrix, mark, i, colstart, height, width);
print(matrix);
mark++;
}
}
}
public static void setRect(char[][] matrix, char c, int startrow, int startcol, int numrows, int numcols)
{
for(int i = 0; i < numrows; i++)
for(int j = 0; j < numcols; j++)
matrix[startrow + i][startcol + j] = c;
}
public static void print(char[][] matrix)
{
int rows = matrix.length;
int cols = matrix[0].length;
for(int i = 0; i < rows; i++)
{
for(int j = 0; j < cols; j++)
System.out.print(matrix[i][j] + " ");
System.out.println();
}
for(int i = 0; i < cols; i++)
System.out.print("==");
System.out.println();
}
public static int nextEmptyCol(char[] row, int start)
{
for(int i = start; i < row.length; i++)
if(row[i] == vacant)
return i;
return -1;
}
}
答案 3 :(得分:0)
(注意3.1是相同的算法,只有倒置的自由/阻塞,并且坐标不同)
答案 4 :(得分:0)
您正在寻找与Code Golf: Running Water
类似的内容答案 5 :(得分:0)
我认为只考虑对象不会得到最好的数学。
例如,在下图中,“r”rect是最佳匹配,但不会从任何角落开始。
+-------------+
| rrrr |
|+--+rrrr +--+|
||##|rrrr |##||
||##|rrrr |##||
||##|rrrr |##||
||##|rrrr |##||
|+--+rrrr +--+|
| rrrr |
+-------------+
答案 6 :(得分:0)
这是我用于完全相同情况的算法:
这将返回空空间矩形的列表。
ESR.left < O.left
,请用NESR.right = O.left
创建新的空白矩形(NESR)并将其添加到ESR列表中,其他障碍物必须检查是否重叠。ESR.right > O.right
,则创建新的ESR,NESR.left = O.right
ESR.bottom < O.bottom
,则创建新的ESR,NESR.top = O.bottom
ESR.top > O.top
,则创建新的ESR,NESR.bottom = O.top
N.B::这是If序列,不是if序列。这意味着您为每个重叠部分最多创建4个新的ESR。
答案 7 :(得分:-1)
我认为您可以实施Montecarlo Approach。
问候。