Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
递归回溯Haskell_Haskell - Fatal编程技术网

递归回溯Haskell

递归回溯Haskell,haskell,Haskell,好的,我正在尝试在Haskell中创建一个数独解算器,但是我得到一个错误,说我无法将预期的类型[[Int]]与实际的类型IO()匹配。下面是我对递归解算器的尝试、错误消息和其他相关代码: 递归解算器尝试: test i j q s_board = if ((valid_row i q s_board )&&(valid_column j q s_board)&& (valid_sub_board i j q s_board)) then (solve (set_

好的,我正在尝试在Haskell中创建一个数独解算器,但是我得到一个错误,说我无法将预期的类型[[Int]]与实际的类型IO()匹配。下面是我对递归解算器的尝试、错误消息和其他相关代码:

递归解算器尝试:

test i j q s_board = if ((valid_row i q s_board )&&(valid_column j q s_board)&&  (valid_sub_board i j q s_board)) then (solve (set_value i j q s_board)) else s_board

foo i j s_board = if ((get_value i j s_board) == 0) then [test i j q s_board | q <- [1..9]] else s_board  

solve s_board = if (full_board s_board) then (print_board s_board) else [foo i j s_board | i <- [0..8], j <- [0..8]]

你们知道我到目前为止有什么问题吗。我是Haskell的新手,这是我尝试的第一个真正的程序。任何帮助都将不胜感激。

如果您是Haskell的新手,最好在处理Monads之前花点时间。IO需要单子

不使用IO monad(
putStrLn
etc),首先将一个工作程序放在一起是个好主意。只需在
ghci
中加载程序,并调用函数即可。当你对此感到满意,并且你在REPL上有一个函数可以给出你的答案时,你可以考虑将它打印到STDOUT上(与“世界”交互——Haskell需要对monads有一些了解)

因此,让您的
solve
函数作为初学者:

解决问题
仅此而已,而不是更多。因此,与其在这里执行IO,不如:

solve s_board = 
  if (full_board s_board) then (print_board s_board) 
  else [foo i j s_board | i <- [0..8], j <- [0..8]]
只需返回结果。然后在
ghci
中处理
solve
,继续修复程序并重新加载它,直到它工作为止。一旦它工作,只需编写一个函数,用所需的参数调用solve并打印它

因此,一旦你的程序真正运作起来,你就可以解决IO的分心问题:

print_board s_board = putStrLn $ show $ solve s_board

这将是阅读的下一步:

如果你是Haskell的新手,在处理Monads之前花点时间是个好主意。IO需要单子

不使用IO monad(
putStrLn
etc),首先将一个工作程序放在一起是个好主意。只需在
ghci
中加载程序,并调用函数即可。当你对此感到满意,并且你在REPL上有一个函数可以给出你的答案时,你可以考虑将它打印到STDOUT上(与“世界”交互——Haskell需要对monads有一些了解)

因此,让您的
solve
函数作为初学者:

解决问题
仅此而已,而不是更多。因此,与其在这里执行IO,不如:

solve s_board = 
  if (full_board s_board) then (print_board s_board) 
  else [foo i j s_board | i <- [0..8], j <- [0..8]]
只需返回结果。然后在
ghci
中处理
solve
,继续修复程序并重新加载它,直到它工作为止。一旦它工作,只需编写一个函数,用所需的参数调用solve并打印它

因此,一旦你的程序真正运作起来,你就可以解决IO的分心问题:

print_board s_board = putStrLn $ show $ solve s_board

这将是阅读的下一步:

if的两个分支必须具有相同的类型,但在

if (full_board s_board) then
    (print_board s_board)
else
    [foo i j s_board | i <- [0 .. 8], j <- [0 .. 8]]
因此,这些函数中的每一个都返回一个
Grid
s的列表,通过返回一个可以从当前网格访问的解决方案的空列表来修剪死胡同。当尚未诊断出死胡同时,将尝试所有允许的组合

那你就可以了

solve_and_print :: Grid -> IO ()
solve_and_print s_board = case solve s_board of
                            [] -> putStrLn "Sorry, that board had no solution."
                            (g:_) -> print_board g
但是,这将多次产生相同的解决方案,而且对于穷举搜索来说效率极低,因为所有可能的顺序都会出现各种猜测组合

所以,让我们来看看如何使它更有效。如果我们有一个算法来选择下一个猜测值的位置,我们可以删减结果列表中解的排列和重复。最简单的算法是选择第一个空闲单元。让我们写一个函数来寻找网格的自由单元

free_cells :: Grid -> [(Int,Int)]
free_cells s_board = [(i,j) | i <- [0 .. 8], j <- [0 .. 8], get_value i j s_board == 0]
接下来,我们找到可能放在单元格
(i,j)
中的值

可能的_值::网格->(Int,Int)->[Int]
可能的_值s_板(r,c)=[q | q(Int,Int)->[Grid]

猜测s|U板(r,c)=[解决方案| v如果
的两个分支必须具有相同的类型,但在

if (full_board s_board) then
    (print_board s_board)
else
    [foo i j s_board | i <- [0 .. 8], j <- [0 .. 8]]
因此,这些函数中的每一个都返回一个
网格列表
s,并通过返回一个可从当前网格访问的解决方案的空列表来修剪死胡同。当还没有诊断出死胡同时,将尝试所有允许的组合

那你就可以了

solve_and_print :: Grid -> IO ()
solve_and_print s_board = case solve s_board of
                            [] -> putStrLn "Sorry, that board had no solution."
                            (g:_) -> print_board g
但是,这将多次产生相同的解决方案,而且对于穷举搜索来说效率极低,因为所有可能的顺序都会出现各种猜测组合

这样,让我们看看如何使它更有效。如果我们有一个算法来选择下一个位置,我们可以修剪结果列表中的排列和重复。最简单的算法是选择第一个自由单元。所以我们写一个函数来找到网格的自由单元。< /P>

free_cells :: Grid -> [(Int,Int)]
free_cells s_board = [(i,j) | i <- [0 .. 8], j <- [0 .. 8], get_value i j s_board == 0]
接下来,我们找到可能放在单元格
(i,j)
中的值

可能的_值::网格->(Int,Int)->[Int]
可能的_值s_板(r,c)=[q | q(Int,Int)->[Grid]
猜测s|U板(r,c)=[解| v
possible_values :: Grid -> (Int, Int) -> [Int]
possible_values s_board (r,c) = [q | q <- [1 .. 9], isPossible s_board q]
  where
    isPossible v = valid_row r v s_board
                   && valid_column c v s_board
                   && valid_sub_board r c v s_board
guesses :: Grid -> (Int, Int) -> [Grid]
guesses s_board (r,c) = [solution | v <- possible_values s_board (r,c)
                                  , solution <- solve $ set_value r c v s_board]