Python 将非平方矩阵拆分为平方子矩阵
给定任何非平方矩阵。我正在寻找一种算法,将其拆分为Python 将非平方矩阵拆分为平方子矩阵,python,algorithm,matrix,Python,Algorithm,Matrix,给定任何非平方矩阵。我正在寻找一种算法,将其拆分为N方子矩阵。不需要原始矩阵的所有元素都在新的子矩阵中(实际上并不总是可能的),但是这些元素应该尽可能少。此外,我只需要一个解决方案,而不是所有可能的组合 例如,如果N=2且矩阵为2x4,则一个除法可以是: 1 1 2 2 1 1 2 2 如果是2x5,则: 1 1 2 2 - 1 1 2 2 - 现在,最后一列未指定给任何子矩阵 固定的是原始数组的大小以及N子矩阵必须是正方形的事实。所以我必须找到新数组的索引的秩。在这个问题中,他们要求一个类
N
方子矩阵。不需要原始矩阵的所有元素都在新的子矩阵中(实际上并不总是可能的),但是这些元素应该尽可能少。此外,我只需要一个解决方案,而不是所有可能的组合
例如,如果N=2
且矩阵为2x4,则一个除法可以是:
1 1 2 2
1 1 2 2
如果是2x5,则:
1 1 2 2 -
1 1 2 2 -
现在,最后一列未指定给任何子矩阵
固定的是原始数组的大小以及N
子矩阵必须是正方形的事实。所以我必须找到新数组的索引的秩。在这个问题中,他们要求一个类似的问题,但是,原始矩阵是平方的,他们查找所有的组合,在这种情况下,我只需要一个解,原始矩阵不必是平方的
有什么想法吗?不难证明,贪婪算法最终会覆盖尽可能多的内容
因此,扫描您的矩阵以查找尚未覆盖的第一个元素(例如,从左到右从上到下),并在此处创建一个新的1×1平方子矩阵。继续向右下角扩展到2×2、3×3等子矩阵,只要它适合原始矩阵。卡住时,从头开始,直到创建了N个子矩阵。我已经实现了自顶向下的递归方法 给定一个矩阵
(x,y,h,w)| |(左上x坐标,左上y坐标,高度,宽度)
,我执行了以下操作:-
假设矩阵=
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
我从左上角选择了所有可能大小的正方形:-
可能性1:
1 0 0 0 0
0 0 0 0 0
0 0 0 0 0
可能性2:
1 1 0 0 0
1 1 0 0 0
0 0 0 0 0
可能性3:
1 1 1 0 0
1 1 1 0 0
1 1 1 0 0
然后我将剩余的空间分成两个矩形,并对相同的矩形进行递归
例如,可能性#2可以用两种方式分解,x
和y
表示两个新的工作部分:
方式1:
1 1 y y y
1 1 y y y
x x y y y
方式2:
1 1 y y y
1 1 y y y
x x x x x
下面是Python的一个实现:
import sys,copy
sys.setrecursionlimit(10**4)
def display_final_matrix(arr_matrix):
temp =[['-' for i in range(init_matrix[3])] for j in range(init_matrix[2])]
ctr=ord('a')
for matrix in arr_matrix:
for i in range(matrix[1],matrix[1]+matrix[2]):
for j in range(matrix[0],matrix[0]+matrix[3]):
temp[i][j]=chr(ctr)
ctr+=1
for i in temp:
print(i)
def find_min_leftover(matrix,n):
x = matrix[0]
y = matrix[1]
h = matrix[2]
w = matrix[3]
if n==0:
return h*w, []
min_left=1<<64
result_arr=[]
for i in range(1,min(h,w)+1):
current_selection = [x,y,i,i]
# Possibility 1
mtr1 = [x+i,y+0,h,w-i]
mtr2 = [x+0,y+i,h-i,i]
for j in range(n):
left_mtr1 , mtr1_subselection = find_min_leftover(mtr1,j)
left_mtr2 , mtr2_subselection = find_min_leftover(mtr2,n-1-j)
if left_mtr1 + left_mtr2 < min_left:
min_left = left_mtr1+left_mtr2
result_arr =[current_selection]+mtr1_subselection+mtr2_subselection
# Possibility 2
mtr1 = [x+i,y+0,i,w-i]
mtr2 = [x+0,y+i,h-i,w]
for j in range(n):
left_mtr1 , mtr1_subselection = find_min_leftover(mtr1,j)
left_mtr2 , mtr2_subselection = find_min_leftover(mtr2,n-1-j)
if left_mtr1 + left_mtr2 < min_left:
min_left = left_mtr1+left_mtr2
result_arr =[current_selection]+mtr1_subselection+mtr2_subselection
return min_left,result_arr
# Top Left x-coord, Top Left y-coord, Height, Width
init_matrix = [0,0,6,6]
min_left,final_matrix = find_min_leftover(init_matrix,5)
print(min_left)
print(final_matrix)
display_final_matrix(final_matrix)
记忆是可能的,因为
0非常感谢。我没有说(现在我已经编辑了),但我需要所有子矩阵的大小相同。对不起,我认为这是含蓄的,但显然不是。我的错。我想@orlp的答案是你在这种情况下应该选择的。@Xbel不,我的答案不适用于所有大小相同的子矩阵。这确实是一项非常关键的要求。我建议您在添加该要求后再问一个新问题。@Xbel您可以计算给定大小的N
正方形是否可以放置在O(1)
中的给定矩形中。从那里你可以对答案进行二元搜索,因为所有大小的方块都适合答案,而没有较大的方块适合@orlp这应该行的对吧?好的。谢谢大家。我想最公平的决定是提出一个新问题并接受这个问题的答案。
4
[[0, 0, 2, 2], [2, 0, 2, 2], [2, 2, 4, 4], [0, 2, 2, 2], [0, 4, 2, 2]]
['a', 'a', 'b', 'b', '-', '-']
['a', 'a', 'b', 'b', '-', '-']
['d', 'd', 'c', 'c', 'c', 'c']
['d', 'd', 'c', 'c', 'c', 'c']
['e', 'e', 'c', 'c', 'c', 'c']
['e', 'e', 'c', 'c', 'c', 'c']