我想根据描述元素属性的matrix_a
二进制矩阵 ( ) 中的值将任意数量的元素排序到任意形状的矩阵 ( ) 中。定义中哪些可以彼此相邻。这种情况下的“相邻”包括对角线。一个具体但玩具的例子:element_map
matrix_b
elements
matrix_a
import numpy as np
#This is a just a mask of the final matrix, to show the shape.
#The center position (5) is adjacent to all other positions whereas
#position (1) is adjacent to 4, 2 and 5, etc.
matrix_a = np.array([[1, 4, 7],
[2, 5, 8],
[3, 6, 9]])
elements = range(0, 10)
#each 'row' corresponds to an element
#each 'column' corresponds to an attribute of the various elements
#here, each element has 5 attributes, which are always 0 or 1
element_map = np.array([[0, 0, 1, 0, 1], #element 1
[1, 1, 1, 0, 1], #element 2
[1, 0, 0, 1, 0], #element 3
[1, 0, 1, 0, 0], #etc.
[1, 1, 1, 0, 0],
[1, 1, 0, 1, 0],
[1, 0, 1, 0, 1],
[1, 1, 0, 0, 0],
[1, 1, 0, 0, 0]]) #element 9
所需的输出是,根据所需的邻接规则,将九个elements
放入 中,每个仅出现一次。规则是,对于放置在 中的任何元素,属性 的值(可以是任何属性)必须为零,并且属性 的所有相邻(在 中相邻)的值必须为 1 。matrix_a
matrix_b
element
matrix_a
element
x
matrix_a
elements
x
还假设我们有一个函数可以接受矩阵和坐标并返回所有相邻值:
def adj(m, x, y):
''' find adjacent values to coordinates x,y in a matrix, m'''
if x == 0:
if y == 0:
r = m[0:2,0:2] # x==0, y==0
else:
r = m[0:2,y-1:y+2] # x==0, y!=0
elif y == 0: # x != 0, y == 0
r = m[x-1:x+2,0:2]
else: #any other position
r = m[(x-1):(x+2),(y-1):(y+2)]
return [i for i in r.flatten().tolist() if i != m[x,y]]
#example:
q = np.arange(1,97).reshape(12,8).T
array([[ 1, 9, 17, 25, 33, 41, 49, 57, 65, 73, 81, 89],
[ 2, 10, 18, 26, 34, 42, 50, 58, 66, 74, 82, 90],
[ 3, 11, 19, 27, 35, 43, 51, 59, 67, 75, 83, 91],
[ 4, 12, 20, 28, 36, 44, 52, 60, 68, 76, 84, 92],
[ 5, 13, 21, 29, 37, 45, 53, 61, 69, 77, 85, 93],
[ 6, 14, 22, 30, 38, 46, 54, 62, 70, 78, 86, 94],
[ 7, 15, 23, 31, 39, 47, 55, 63, 71, 79, 87, 95],
[ 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96]])
adj(q, 5, 5)
[37, 45, 53, 38, 54, 39, 47, 55]
附带说明一下,8x12 矩阵和 96 个元素的可能搜索空间是 10**149 = 96!
也许这将是线性/整数编程的工作,但我不确定如何制定邻接约束
这可以通过 ILP(整数线性规划)来完成。粗剪如下所示。您似乎没有声明权重来考虑一个结果优于另一个结果,因此您也可能幸运地使用 CP(约束编程)方法。下面的 ILP 使用成功元素填充的数量作为目标。可能有很多解决方案(或没有),它只会抓住第一个发现的解决方案。
值得注意的是,您提供的示例没有 3x3 目标矩阵的解决方案。我使用下面的段从单位矩阵中生成元素(翻转 1/0),通过检查,它是最适合拟合元素列表的。
我
adj()
稍微调整了你的函数,因为你有一个混合模式,你在其中接受 (x, y) 并返回一个编号位置......我刚刚完成了全部 (x, y)如果存在解,对于中等大小的 ,往往会很快找到它
matrix_a
,特别是当解集很大时。我
cbc
在这里使用了求解器,这是一个很好的免费软件,但还有其他可以正常工作的 MIP 求解器(glpk、highs,...)这里仍然有一些“骨头上的肉”来优化这一点,主要是通过根据值将元组域修剪
[e, p, a]
为合法分配a
,这意味着任何具有非零属性的place[e, p, a]
元素都是不合法的,应该被删除来自 的域。然后,您可能会考虑预先计算任何给定元素的可能邻居,以稍微减小约束的大小。e
a
place
adjacency
代码:
输出(截断):