首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >N-Queens示例程序奇怪输出

N-Queens示例程序奇怪输出
EN

Stack Overflow用户
提问于 2016-03-24 03:42:48
回答 1查看 77关注 0票数 2

我尝试使用squeen.icl示例中的代码。当我尝试使用BoardSize :== 11时,就没有问题了。但是,当我将其更改为12时,输出是[。为什么?怎么解决这个问题?

代码语言:javascript
复制
module squeen
import StdEnv

BoardSize :== 12

Queens::Int [Int] [[Int]] -> [[Int]]
Queens row board boards
    | row>BoardSize =  [board : boards]
    | otherwise     =  TryCols BoardSize row board boards

TryCols::Int Int [Int] [[Int]] -> [[Int]]
TryCols 0 row board boards =  boards
TryCols col row board boards
    | Save col 1 board  =   TryCols (col-1) row board queens
    | otherwise         =   TryCols (col-1) row board boards
where   queens  = Queens (row+1) [col : board] boards

Save::!Int !Int [Int] -> Bool
Save  c1 rdiff [] =  True
Save  c1 rdiff [c2:cols]
    | cdiff==0 || cdiff==rdiff || cdiff==0-rdiff    =   False
    | otherwise                                     =   Save c1 (rdiff+1) cols
where   cdiff   = c1 - c2


Start::(Int,[Int])
Start   =   (length solutions, hd solutions)
where   solutions   = Queens 1 [] []
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-24 06:44:18

这是因为堆上的空间快用完了。默认情况下,清洁程序堆设置为2M。当然,你可以改变这个。当从命令行使用clm时,可以将-h 4M添加到其命令行或clean程序本身的命令行。如果使用的是Clean,则可以通过Project、Application更改堆大小。

(仍然被打印(这是我得到的,而不是[)的原因如下。清洁程序将尽可能多地输出其输出,而不是等到整个输出已知。例如,这意味着一个简单的行(如Start = [0..] )将垃圾邮件发送到您的终端,而不是等到整个无限列表都在内存中,然后打印出来。在squeen.icl的情况下,Clean看到开始的结果将是元组,因此直接打印开口大括号。但是,当试图计算元组的元素(length solutionshd solutions)时,堆会被填满,使程序终止。

我不知道在Windows上得到一个完整的堆是什么样子,但是在Linux(/Mac)上,它看起来是这样的:

代码语言:javascript
复制
$ clm squeen -o squeen && ./squeen -h 2M
Linking squeen
Heap full.
Execution: 0.13  Garbage collection: 0.03  Total: 0.16
($

请注意,元组开头大括号位于最后一行。因此,当使用终端时,很容易发现这个错误。

有趣的是,由于length利用尾递归,所以可以计算元组的第一个元素,即使使用一个小堆(可以用[]替换第二个元素)。另外,元组的第二个元素可以在一个小堆上计算(用0替换第一个元素)。

重点是,长度是计算在头部之前,因为它必须打印的第一个。对于普通的length调用,列表的部分是垃圾收集的(在迭代前100个元素之后,可以丢弃它们,从而减少堆的使用),hd调用确保列表的第一个元素不会被丢弃。如果第一个元素没有被丢弃,第二个元素也不能被丢弃,第三个元素等等。因此,整个列表都保存在内存中,而这实际上并不是必需的。翻转lengthhd调用可以解决这个问题:

代码语言:javascript
复制
Start :: ([Int], Int)
Start = (hd solutions, length solutions)
where solutions = Queens 1 [] []

现在,在调用hd之后,没有理由将整个列表保存在内存中,这样length就可以丢弃它迭代过的元素,堆也不会被填满。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36192889

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档