问题描述
我尝试优化https://airflow.apache.org/docs/stable/kubernetes.html代码,最终代码如下所示
def load_users_into_table(postgres_hook,schema,path):
gdf = read_csv(path)
gdf.to_sql('users',con=postgres_hook.get_sqlalchemy_engine(),schema=schema)
我的问题是,即使如下所示成功打印了解决方案,变量 solved 也只是一个nonetype而没有存储任何内容。
_pg_hook = PostgresHook(postgres_conn_id = _conn_id)
with dag:
test = KubernetesP@R_404_6487@perator(
namespace=namespace,image=image_name,cmds=["python","-c"],arguments=[load_users_into_table],labels={"dag-id": dag.dag_id},name="airflow-test-pod",task_id="task-1",is_delete_operator_pod=True,in_cluster=in_cluster,get_logs=True,config_file=config_file,executor_config={
"KubernetesExecutor": {"request_memory": "512Mi","limit_memory": "1024Mi","request_cpu": "1","limit_cpu": "2"}
}
)
this函数将打印解决方案,但不返回任何内容。我该怎么办才能存储打印的解决方案?
解决方法
问题在您的代码中
solve_sudoku(sudoku)
sudoku[row,col] = 0
return
在第一行中,您会重复执行,但是忽略了返回值,该返回值会丢弃该调用及其下的所有递归的所有返回值。
在最后一行,您在None
上返回默认值。这两种方法都会破坏您递归返回值的连续性。
使用完全填充的数独数组(其中一个没有任何零)的print(sudoku)
调用时,发生solve_sudoku
调用,而不是在顶级递归调用中。
每次用不完整的数独数组调用solve_sudoku
时,您正在测试最左上角填充零的单元格中介于1到10之间的每个数字,如果该数字可以放置在该单元格中,则放置在那里尝试解决网格的其余部分,然后将单元格设置回零。对介于1到10之间的每个数字执行此操作后,将返回None
,这就是为什么您看到顶级None
调用返回了solve_sudoku
的原因。
几个小时后,我想到了这个解决方案。 已解决立即存储解决方案。
import numpy as np
sudoku = np.array([[0,9,5,6,8],[0,7,1,3,0],[2,4],6],[6,2,8,4,5],[7,[9,1],[5,0]])
solved = np.zeros_like(sudoku)
def check(arg,row,col,n):
if np.sum(arg[row,:] == n) != 0: return False;
if np.sum(arg[:,col] == n) != 0: return False;
row0,col0 = (row//3)*3,(col//3)*3
if np.sum(arg[row0:row0+3,col0:col0+3] == n) != 0: return False;
return True
def solve_sudoku(arg):
global solved
rows,cols = np.where(arg == 0)
for row in rows:
for col in cols:
for num in range(1,10):
if check(arg,num):
arg[row,col] = num
solve_sudoku(arg)
arg[row,col] = 0
return
solved = arg.copy()
solve_sudoku(sudoku)
我不知道这是否是优化代码的最佳方法,欢迎反馈。
,def check(grid,num,x,y):
for i in range(9):
if grid[i][y] == num:
return False
for j in range(9):
if grid[x][j] == num:
return False
x0 = (x//3) * 3
y0 = (y//3) * 3
for i in range(3):
for j in range(3):
if grid[x0+i][y0+j] == num:
return False
return True
def solve(grid):
for i in range(9 + 1):
if i==9:
return True
for j in range(9):
if grid[i][j] == 0:
for num in range(1,10):
if check(grid,i,j):
grid[i][j] = num
if solve(grid):
return True
grid[i][j] = 0
return False
这应该为您工作。它不返回数组而是对其进行修改。因此,如果您通过
solve(sudoku_grid)
然后打印sudoku_grid,它将为您提供已解决的输出
,if check(sudoku,num):
sudoku[row,col] = num
solve_sudoku(sudoku)
sudoku[row,col] = 0
在某个周期“solve_sudoku(sudoku)”会得到解。当你得到你的解决方案时,你应该立即通过返回或打破循环来停止回溯。否则,下一行“sudoku[row,col] = 0”将取消您之前的尝试并继续检查下一个可能的数字。由于数独只有一个解决方案,因此没有必要继续检查下一个数字。您可以只返回一个真值来结束循环。例如,您可以这样编码 如果 solve_sudoku(sudoku)==True: 返回真