.net 获取给定空间中有障碍物的矩形的最大可能范围

.net 获取给定空间中有障碍物的矩形的最大可能范围,.net,math,.net,Math,我正在处理以下问题: 有一个带有空单元格的网格(以白色显示的空单元格)。此网格中的单个单元格已被元素“占据”(元素以橙色显示) 现在我有了一个矩形的起点(在本例中是第6行,第3列)。此矩形应占据尽可能多的空闲单元格。矩形应在橙色元素处或网格结束时停止 所附的屏幕截图显示了2个网格场景及其解决方案 左派的情况将再次出现 width = 2 height = 5 正确的情景将会重现 width = 1 height = 5 我曾多次尝试编写一个简单易用的代码,返回矩形的最大宽度和高度,但最终我总

我正在处理以下问题:

有一个带有空单元格的网格(以白色显示的空单元格)。此网格中的单个单元格已被元素“占据”(元素以橙色显示)

现在我有了一个矩形的起点(在本例中是第6行,第3列)。此矩形应占据尽可能多的空闲单元格。矩形应在橙色元素处或网格结束时停止

所附的屏幕截图显示了2个网格场景及其解决方案

左派的情况将再次出现

width = 2
height = 5
正确的情景将会重现

width = 1
height = 5
我曾多次尝试编写一个简单易用的代码,返回矩形的最大宽度和高度,但最终我总是得到一个又长又难看的代码

有没有一个简洁的数学解决方案,或者这个简单的问题并不像一开始看起来那么简单

多谢各位。
.

用0-1矩阵表示网格,其中
1
对应于障碍物

如果网格是
m x n
(a,b)
是起始单元格基于0的行和列索引,则
width=n-b
表示从该单元格开始的矩形的最大可能宽度,而不考虑任何障碍物。这是当前宽度。现在,开始从该单元格向下扫描柱,直到遇到底部边缘或障碍物。对于该列中的每个单元格,开始向右扫描,直到达到障碍物或当前宽度。如果首先遇到障碍物,请减小当前宽度。将当前宽度附加到宽度列表中(无论当前宽度是否已减小)

在这个阶段,您有一个宽度列表,每个潜在高度有一个宽度。只需扫描这个列表,将每个宽度乘以相应的高度(即1+基于0的列表索引)。返回使产品高度*宽度最大化的一对(高度,宽度)

Python实现:

def find_max_rect(grid,a,b):
    if grid[a][b] == 1: return (0,0)
    m = len(grid) #number of rows
    n = len(grid[0]) #number of columns
    width = n-b #maximum possible width given starting column
    widths = [] 
    i = a
    while i < m and grid[i][b] == 0:
        #scan right from (i,b+1) until a 1 or current width is hit
        for j in range(b+1,b+width):
            if grid[i][j] == 1:
                #an obstacle forces width to contract
                width = j-b #number of steps before obstacle
                break #out of inner loop
        widths.append(width)
        i += 1      
    max_area = 0
    max_at = -1
    for i,width in enumerate(widths):
        if (i+1)*width > max_area:
            max_area = (i+1)*width
            max_at = i
    return (max_at + 1,widths[max_at])
编辑时:我意识到没有什么理由只存储候选宽度,只对其进行一次迭代。相反,您可以随时跟踪最佳区域。以下代码在功能上等效,但效率更高:

def find_max_rect(grid,a,b):
    if grid[a][b] == 1: return (0,0)
    m = len(grid) #number of rows
    n = len(grid[0]) #number of columns
    current_height = 0
    current_width = n - b #maximum possible width given starting column
    max_area = 0
    best_height, best_width = current_height, current_width

    i = a
    while i < m and grid[i][b] == 0:
        current_height += 1
        #scan right from (i,b + 1) until a 1 or current width is hit
        for j in range(b + 1,b + current_width):
            if grid[i][j] == 1:
                #an obstacle forces width to contract
                current_width = j - b #number of steps before obstacle
                break
        #decide if the best should be adjusted
        current_area = current_height * current_width
        if  current_area > max_area:
            best_area, best_height, best_width = current_area, current_height, current_width
        i+=1
    return best_height, best_width
def find_max_rect(网格,a,b):
如果网格[a][b]==1:返回(0,0)
m=长度(网格)#行数
n=len(网格[0])#列数
当前高度=0
当前_宽度=n-b#给定起始列的最大可能宽度
最大面积=0
最佳高度,最佳宽度=当前高度,当前宽度
i=a
当i最大面积:
最佳面积、最佳高度、最佳宽度=当前面积、当前高度、当前宽度
i+=1
返回最佳高度、最佳宽度
def find_max_rect(grid,a,b):
    if grid[a][b] == 1: return (0,0)
    m = len(grid) #number of rows
    n = len(grid[0]) #number of columns
    current_height = 0
    current_width = n - b #maximum possible width given starting column
    max_area = 0
    best_height, best_width = current_height, current_width

    i = a
    while i < m and grid[i][b] == 0:
        current_height += 1
        #scan right from (i,b + 1) until a 1 or current width is hit
        for j in range(b + 1,b + current_width):
            if grid[i][j] == 1:
                #an obstacle forces width to contract
                current_width = j - b #number of steps before obstacle
                break
        #decide if the best should be adjusted
        current_area = current_height * current_width
        if  current_area > max_area:
            best_area, best_height, best_width = current_area, current_height, current_width
        i+=1
    return best_height, best_width