我正在嘗試創建一個代碼,該代碼可以在 numpy 矩陣中生成所有可能的 0 和 1 組合,不包括旋轉。我是什么意思旋轉?我的意思是,下面的矩陣資料實際上是相同的,因為它具有相同的資料,但旋轉了 90o、180o 和 270o。

我一直在嘗試下面的代碼,但我認為我沒有得到所有組合,而且我缺少一些組合。你知道這是否是正確的方法嗎?不知道有沒有更有效的方法?
例如,考慮 dx=3 和 dy=3
import numpy as np
def myfunction(data)
print(data)
dx=3
dy=3
data = np.zeros([dx, dy], dtype=np.uint8)
y=0
for x in range(dx):
for r in range(2):
data[x, y] = r
myfunction(data)
for y in range(dy):
for s in range(2):
data[x, y] = s
myfunction(data)
非常感謝!
uj5u.com熱心網友回復:
這是一個矢量化解決方案,適用于小矩陣;代碼中的注釋說明了 3 x 3 的情況:
def get_binary_mats(n):
# all possible n by n binary matrices up to rotation:
bin_mats = (np.bitwise_and(np.arange(2**(n*n))[:,None], 2 ** np.arange(n*n)) > 0)\
.reshape(-1, n, n)
# define a score for each matrix based on position of ones
score = 2 ** np.arange(n*n).reshape(n,n)
# array([[ 1, 2, 4],
# [ 8, 16, 32],
# [ 64, 128, 256]])
score_arr = np.stack([np.rot90(score, k=k) for k in range(4)])
# array([[[ 1, 2, 4],
# [ 8, 16, 32],
# [ 64, 128, 256]],
# [[ 4, 32, 256],
# [ 2, 16, 128],
# [ 1, 8, 64]],
# [[256, 128, 64],
# [ 32, 16, 8],
# [ 4, 2, 1]],
# [[ 64, 8, 1],
# [128, 16, 2],
# [256, 32, 4]]])
scores = np.einsum("ijk,ljk->il", bin_mats, score_arr)
_, idx = np.unique(scores.min(1), return_index=True)
return bin_mats[idx,...]
主要思想是我們可以將 N × N 二進制矩陣與 N × N 矩陣進行“點積”,該矩陣由 2 的前 N^2 次方組成(我稱后者為分數矩陣)。當我們這樣做時,我們會為每個可能的二進制矩陣得到一個唯一的整數。
為了考慮旋轉,我們可以對“分數”矩陣進行 4 次旋轉的“點積”,并將每個二進制矩陣與四個結果中的最小值相關聯。我們可以將此最小值稱為二進制矩陣的分數。
最后,我們可以為每個獨特的分數選擇一個矩陣np.unique。例如,這里是 n = 2 的輸出:
array([[[False, False],
[False, False]],
[[ True, False],
[False, False]],
[[ True, True],
[False, False]],
[[False, True],
[ True, False]],
[[ True, True],
[ True, False]],
[[ True, True],
[ True, True]]])
作為健全性檢查,最多旋轉的二進制矩陣的數量與此 OEIS 序列一致,n 最多為 5:
%time assert [get_binary_mats(k).shape[0] for k in range(1, 6)] == [2, 6, 140, 16456, 8390720]
# takes 20 seconds on my machine
uj5u.com熱心網友回復:
我不確定我的回答是否是最有效的方式,但無論如何。
我們可以使用numpy.rot90函式旋轉每個矩陣。
讓我們創建兩個不同的字典,一個存盤主矩陣,另一個存盤主矩陣的旋轉,因此我們可以驗證新矩陣是否只是先前找到的矩陣的旋轉。
def Not_Rotated(dx, dy):
import numpy as np
from itertools import product
Big_Matrix = np.array([[list(i[x:x dx]) for x in range(0, len(i), dx)] for i in product("01", repeat=dx*dy)]) # Stores all possible combinations
Main = dict() # Stores not rotated
Main_c = 0
Rotations = dict() # Stores rotated
Rotation_c = 0
for i in range(len(Big_Matrix)): # Going through all combinations
flag = 1 # A flag to check if this combination is rotated of previous ones or not. 1= is not rotated of previous ones. 0 = is rotated.
for z in range(Rotation_c):
if np.array_equal(Big_Matrix[i],Rotations[z]): # Checking if this combination is rotated of previous ones or not
flag = 0
if flag: # If this combination is not a rotation of previous ones
Main[Main_c] = Big_Matrix[i]
# Rotate it three times and store the matrices
Rotations[Rotation_c] = np.rot90(Main[Main_c])
Rotations[Rotation_c 1] = np.rot90(Main[Main_c])
Rotations[Rotation_c 2] = np.rot90(Main[Main_c])
Rotation_c = 3
Main_c = 1
return Main
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/453066.html
