order=input('Input the order of a Latin Square: ')
top_left=input('Input the top-left number: ')
int_order=int(order)
int_top_left=int(top_left)
for order in range(int_order):
for top_left in range(int_order):
print(int_top_left, end = ' ')
print()
所以我想输入一个订单,然后输入一个左上角的数量并让它从那里创建一个拉丁方,问题是我不知道如何让它在行和列中计数,这个程序仅将左上角数字排列在方形网格中,大小顺序为x阶。任何帮助表示赞赏。
答案 0 :(得分:3)
拉丁方是一个NP完全问题(参见http://en.wikipedia.org/wiki/Latin_square#Mathematical_puzzles),就像数独一样,只有一些约束被删除。
你需要(以某种方式)搜索给定顺序的拉丁方的空间。你有几个可能性:
您可以使用一些状态空间搜索技术自己编写Latin Square解算器。您的初始状态将是拉丁广场,除了左上角字段之外的所有字段都是空白。您可以一次查看一个字段并尝试将其设置为满足约束条件的数字。如果有,请继续进入下一个字段,否则回溯到父状态。
您可以在线状态空间搜索中找到巨大数量的资源。搜索关键字:回溯,DFS,BFS,分支和界限,A *
您可以将此问题转换为另一个经过深入研究的组合优化问题,并使用解算器。
此问题可以表示为图形着色 - 您可以通过以下方式将其转换为图形着色问题:
事实上,拉丁方(或多或少)是图形着色,只使用不同的术语:)。
图形着色可以通过CSP(约束满足编程)求解器来解决,或者您可以直接将问题插入CSP。
您可以使用ILP(整数线性编程)解决它。有调整解决方案。 GLPK是开源的,并且有python绑定(例如PyGLPK)
如果你想办法如何表达一些由某些数字填充的方格的错误(例如,约束违规的数量,即同一行或列中相同数字的对数),你可以使用一些随机数像Simmulated Annealing或Evolutionary Algorithms这样的metaheuristics使用该错误函数将解决方案驱动为有效的解决方案。
答案 1 :(得分:1)
您可以使用Jacobson和P. Matthews方法。
微米。 T. Jacobson和P. Matthews,生成均匀分布 随机拉丁方,J. Combinatorial Design 4(1996),405-437
选择look。
答案 2 :(得分:1)
关键思想是您可以创建一个有效行并旋转该行以生成一个有效正方形:
def create_latin_square(n: int):
row = [i for i in range(1, n+1)]
return [row[i:] + row[:i] for i in range(n)]
4号正方形看起来像这样:
[1, 2, 3, 4] # row
[2, 3, 4, 1] # row, rotated by 1 to the left
[3, 4, 1, 2] # row, rotated by 2 to the left
[4, 1, 2, 3] # row, rotated by 3 to the left
然后只旋转第一行:
def create_latin_square(n: int, start_el: int=1):
row = [i for i in range(1, n+1)]
row = row[start_el-1:] + row[:start_el-1]
return [row[i:] + row[:i] for i in range(n)]
答案 3 :(得分:1)
这是什么?
def latin_square(n, mod='ballanced'):
import numpy as np
mat = np.empty((n,n,))*np.nan
mat[:,0] = range(1,n+1)
if mod=='ballanced':
shift = (.5-np.mod(np.array(range(1,n)),2))/.5*np.ceil(np.array(range(1,n))/2)
shift = shift.astype(int)
elif mod=='normal':
shift = np.array(range(n-1, -1, -1))
for col in range(1, n):
mat[:, col] = np.roll(mat[:,0], shift[col-1])
return(mat)
latin_square(6)
array([[1., 2., 6., 3., 5., 4.],
[2., 3., 1., 4., 6., 5.],
[3., 4., 2., 5., 1., 6.],
[4., 5., 3., 6., 2., 1.],
[5., 6., 4., 1., 3., 2.],
[6., 1., 5., 2., 4., 3.]])
答案 4 :(得分:0)
#Highest number in square
order_of_sq = int(input("Enter order of sq: "))
#Number you want to start the square with
top_left = int(input("Enter top left number: "))
#Sets a placeholder for a variable called top_left_init
top_left_init=0
#Sets the initial value of top_left to a new variable because the code will change the value of top left later on
top_left_init += top_left
#Initialize the value of count
count = 0
#Add 1 to the highest value in latin square to account for the range function (the ending number is always one less than the number you enter into the range function)
for values in range (1,order_of_sq+1):
#Prevents the program from adding too many characters to the line
while count != order_of_sq:
#Prints numbers with spaces after them in a horizontal manner
print(top_left,sep=' ',end=' ')
#Adds 1 to the top_left
top_left += 1
#Count is used to keep track of how many characters are in your line
count+=1
#Restarts the numbers in your line when you reach the highest number
if top_left == order_of_sq+1:
top_left = 1
#Creates a new row
print()
count = 0
#Calls the initial value of top_left and adds 1 to it before beginning the next row
top_left_init += 1
#Resets top_left_init to 1 if it reaches the highest number in the square
if top_left_init == order_of_sq + 1:
top_left_init = 1
top_left = top_left_init
else:
top_left = top_left_init
main()的