我有一些代码可以确定一个N*N整数列表是否构成一个幻方:
import itertools
#Function square magic
def magic_square(matrix):
dimension = len(matrix[0])
sum_list = []
#Horizontal code:
sum_list.extend([sum (lines) for lines in matrix])
#Vertical code:
for col in range(dimension):
sum_list.append(sum(row[col] for row in matrix))
#Diagonals code
diagonal1 = 0
for i in range(0,dimension):
diagonal1 +=matrix[i][i]
sum_list.append(diagonal1)
diagonal2 = 0
for i in range(dimension-1,-1,-1):
diagonal2 +=matrix[i][i]
sum_list.append(diagonal2)
if len(set(sum_list))>1:
return False
return True
m=[[7, 12, 1, 14], [2, 13, 8, 11], [16, 3, 10, 5], [9, 6, 15, 4]]
print(magic_square(m))
m=[[2, 7, 6], [9, 5, 1], [4, 3, 8]]
print(magic_square(m))
m=[[2, 7, 6], [9, 5, 1], [4, 3, 7]]
print(magic_square(m))
print("**************************")
#Now, i use itertools like this:
for i in itertools.combinations(range(1,10), 3):
if sum(i) == 15:
print (i)
# I get the combinations each of three numbers with sum 15
我的问题是最后一部分:我想生成整数1到N^2的所有排列,将每个排列分成一个正方形--一个由N行和N列组成的二维列表--并使用我的函数找到所有幻方。我写的itertools代码可以找到3个数字的组合,但我找不到组成正方形的组合。
感谢@Prune的帮助。
如果我有:
1 5 9
1 6 8
2 4 9
2 5 8
2 6 7
3 4 8
3 5 7
4 5 6
我如何一次使用三个矩阵元素,生成一个平方魔术,并知道它是否是真是假?
示例:
[1 5 9,1 6 8,2 4 9]
或
[1 5 9,1 6 8,2 5 8]
或
[1 5 9,1 6 8,2 6 9]等,等。
发布于 2016-12-29 08:32:38
我明白了--你想生成幻方的所有排列。您需要涵盖范围从1到N^2的所有排列,每个排列都以N列表的N元素的形式返回。
import itertools
N = 3
for seq in itertools.permutations(range(1, N*N+1)):
# Split the sequence into a candidate magic square,
# N rows of N elements each.
cand = [seq[i:i+N] for i in range(0, N*N, N)]
这将生成一系列候选方块;依次将每个方块提供给您的检查例程,并打印出现True的方块。我希望你能处理好这部分。
以下是这一代早期的几个候选示例:
[(1, 3, 5), (6, 2, 8), (4, 7, 9)]
[(1, 3, 5), (6, 2, 8), (4, 9, 7)]
[(1, 3, 5), (6, 2, 8), (7, 4, 9)]
[(1, 3, 5), (6, 2, 8), (7, 9, 4)]
[(1, 3, 5), (6, 2, 8), (9, 4, 7)]
[(1, 3, 5), (6, 2, 8), (9, 7, 4)]
[(1, 3, 5), (6, 2, 9), (4, 7, 8)]
[(1, 3, 5), (6, 2, 9), (4, 8, 7)]
[(1, 3, 5), (6, 2, 9), (7, 4, 8)]
[(1, 3, 5), (6, 2, 9), (7, 8, 4)]
[(1, 3, 5), (6, 2, 9), (8, 4, 7)]
[(1, 3, 5), (6, 2, 9), (8, 7, 4)]
方法的更改
请注意,这不是您的原始算法:它生成整个正方形,而不是只生成3行。独立生成有一个逻辑缺陷,它将生成不包括所有9个数字的幻方,同时复制其他数字。例如:
7 2 6
4 5 6
4 8 3
发布于 2017-01-04 01:49:29
给定停止点的算法
你目前有三个不同整数1-9的所有8种可能的组合,它们的总和是15。要以你要求的简单方式解决魔方,我建议执行以下步骤:
更快的代码
为了提高效率,有多种方法可以攻击排列。例如,按最低元素(1、2、3或4)将行分为四组。在生成正方形时,从每组中选取不超过一行。这将大大减少您检查的总方块,因为它减少了元素的重复。
另一种方法是选择前两行,然后从列和中派生第三行。然后,您只需要进行四个检查:两条对角线之和是否为15,生成的底部行是否合法(只有数字1-9),以及没有重复的数字。
更有效地查找8行
您不必遍历720个三元组来找到这8行。相反,生成90个开始对;对于每个开始对,派生出第三个元素(15减去前两个)。如果第三个元素是7个缺失数字中的一个(1-9,但前两个都不是),那么它就是您想要的行之一。
我希望这能引导你找到一个解决方案。
发布于 2018-07-13 07:57:31
这里有一个准一行的解决方案(好处是在找到答案时产生答案)。它将长度为N*N的排列映射到numpy reshape,然后确定矩阵是否为魔术矩阵。
import numpy
import functools
import itertools
N = 3
for item in filter(lambda o: len(set(numpy.sum(o, axis=0))
.union(numpy.sum(o, axis=1))
.union({o.diagonal().sum()})
.union({numpy.fliplr(o).diagonal().sum()})
) == 1,
map(functools.partial(numpy.reshape, newshape=(N, N)),
itertools.permutations(range(N*N)))):
print(item)
https://stackoverflow.com/questions/41368021
复制相似问题