用Python创建拉丁方程序
我试图输入一个订单,然后左上角的数量,并让它从那里创建一个拉丁方。问题是,我不知道如何让它在行和列中计数。该程序仅将左上角的数字按大小顺序x排列成方格。拉丁方是一个NP完全问题(请参阅),与数独一样,只是去掉了一些限制条件 你需要(以某种方式)搜索给定顺序的拉丁方空间。您有几种可能性: 1.手动状态空间搜索 您可以使用一些状态空间搜索技术自己编写拉丁方解算器。初始状态为拉丁方,除左上角字段外,其余字段均为空白。然后,您可以一次查看一个字段,并尝试将其设置为满足约束条件的数字。如果存在,则转到下一个字段,否则返回到父状态 你可以在在线状态空间搜索中找到大量的资源。搜索关键字,如:回溯、DFS、BFS、分支和绑定、A* 2.转换到另一个组合问题并使用现有解算器 您可以将此问题转换为另一个经过充分探索的组合优化问题,并使用解算器解决该问题 此问题可以表示为图着色-您可以通过以下方式将其转换为图着色问题:用Python创建拉丁方程序,python,latin-square,Python,Latin Square,我试图输入一个订单,然后左上角的数量,并让它从那里创建一个拉丁方。问题是,我不知道如何让它在行和列中计数。该程序仅将左上角的数字按大小顺序x排列成方格。拉丁方是一个NP完全问题(请参阅),与数独一样,只是去掉了一些限制条件 你需要(以某种方式)搜索给定顺序的拉丁方空间。您有几种可能性: 1.手动状态空间搜索 您可以使用一些状态空间搜索技术自己编写拉丁方解算器。初始状态为拉丁方,除左上角字段外,其余字段均为空白。然后,您可以一次查看一个字段,并尝试将其设置为满足约束条件的数字。如果存在,则转到下一
如果您找到一种方法来表示由某些数字填充的某个正方形的错误(例如,违反约束的数量,即同一行或列中相同数字的对的数量),您可以使用一些随机元启发式方法,如或,使用该误差函数将解决方案转化为有效的解决方案。您可以使用Jacobson和p.Matthews方法 M.T.Jacobson和p.Matthews,生成均匀分布 《随机拉丁方》,J.组合设计4(1996),405-437
以a为例。关键思想是您可以创建一个有效的行并旋转该行以生成一个有效的正方形:
# 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
大小为4的正方形如下所示:
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)]
然后只需旋转第一行:
[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)]
你到底想让你的代码做什么?用户输入左上角的数字(您可能应该检查该数字是否在1..order范围内),然后打印出填充的拉丁方?这应该包括对代码的解释,所有代码的答案都没有价值。@TristanWiley:我正要问“但是注释呢?”时,我意识到它们并不是一个很好的补充。尽管如此,代码还是有一个内置的解释,只是没有关注最有趣的部分。这些注释是为了帮助他/她从头到尾遵循程序。学生可以很容易地在谷歌上搜索拉丁方来加深对这个概念的理解。“拉丁方是一个NP完全问题”——并不总是这样。特别是当我的解决方案显示只有一个单元格被填充时。这里的问题是拉丁方构造,而不是拉丁方完成,所以它不是NP完全的。除了回溯,所有这些方法都是多余的。
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)]
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.]])