提问人:Saba 提问时间:12/20/2021 最后编辑:martineauSaba 更新时间:12/21/2021 访问量:204
如何生成一个具有排列的矩阵,其中任何 2x2 平方都有 4 个不相同的值?
How to generate a matrix with permutations where any 2x2 square has 4 non-identical values?
问:
因此,假设我的矩阵看起来像这样(始终是正方形):
a1 a2 a3
b1 b2 b3
c1 c2 c3
我希望正方形中的元素 , , 不相似 — 意思是 : 。(a1, a2, b1, b2)
(a2, a3, b2, b3)
etc
a1 != a2 != b1 != b2
我有以下代码用于递归生成矩阵:
def generate(elements):
if not elements:
return (),
final = []
for items in generate(elements[:-1]):
for item in elements[-1]:
final.append(items + (item,))
return final
def product(*args, repeat=1):
pools = [list(pool) for pool in args] * repeat
return list(generate(pools))
def main():
D = 3
combinations = product([0, 128, 196], repeat=D)
matrices = product(combinations, repeat=D)
return matrices
其中 是整数(未知数)的列表,比方说 和 是方阵的大小。elements
[0, 128, 196]
repeat
我希望函数中的某个地方应用该规则,以便它只会根据我提到的规则生成矩阵。
因此,最终结果将是 3x3 矩阵的所有可能变体,但应用了该规则。
宁愿在不导入熊猫或类似东西的情况下这样做。
答:
0赞
Stef
12/21/2021
#1
这是一种可能性:
- 使用 和 生成所有可能的矩阵
itertools.permutations
numpy.reshape
; - 检查矩阵是否适合用于测试相等的相邻元素。
numpy.diff
from more_itertools import distinct_permutations
from numpy import array, diff, count_nonzero
def check_matrix(m):
d_vert = diff(m, axis=0) # vertically adjacent
if count_nonzero(d_vert) < d_vert.size:
return False
d_hori = diff(m, axis=1) # horizontally adjacent
if count_nonzero(d_hori) < d_hori.size:
return False
d_dia1 = d_vert[:,:-1] + d_hori[1:,:] # northwest-southeast diagonally adjacent
if count_nonzero(d_dia1) < d_dia1.size:
return False
d_dia2 = d_hori[:-1,:] - d_vert[:,:-1] # southwest-northeast diagonally adjacent
return count_nonzero(d_dia2) == d_dia2.size
def gen_matrices(h,w, elements):
for p in distinct_permutations(elements, h*w):
m = array(p).reshape((h,w))
if check_matrix(m):
yield m
for m in gen_matrices(2, 3, [1,2,3,4,1,2]): # should be 8 results with 3 and 4 in the middle column
print(m)
# [[1 3 1]
# [2 4 2]]
# [[1 3 2]
# [2 4 1]]
# [[1 4 1]
# [2 3 2]]
# [[1 4 2]
# [2 3 1]]
# [[2 3 1]
# [1 4 2]]
# [[2 3 2]
# [1 4 1]]
# [[2 4 1]
# [1 3 2]]
# [[2 4 2]
# [1 3 1]]
文档:
- numpy.diff 中
- numpy.reshape
- numpy.count_nonzero
- numpy.size
- itertools.排列
- more_itertools.distinct_permutations
0赞
Saba
12/21/2021
#2
通过添加一个检查每 2 行的新函数来解决它。有点慢,但它有效。
def square_chec(row1, row2):
if row1[-1] == row2[-1]:
return False
for num in range(len(row1)-1):
if row2[num+1] == row1[num] or row2[num] == row1[num] or row1[num+1] == row2[num] or row2[num] == row1[num]:
return False
return True
def generate(elements):
if not elements:
return (),
final = []
for items in generate(elements[:-1]):
for item in elements[-1]:
if items:
if items[-1] != item:
if type(item) == tuple:
if square_chec(items[-1], item):
final.append(items + (item,))
else:
final.append(items + (item,))
else:
final.append(items + (item,))
return final
评论