簡體   English   中英

N-Queens 示例程序奇怪的輸出

[英]N-Queens example program strange output

我嘗試使用squeen.icl示例中的代碼。 當我嘗試使用BoardSize :== 11 ,沒有問題。 但是當我將其更改為12 ,輸出為[ 為什么? 如何解決?

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 [] []

這是因為堆上的空間不足。 默認情況下,Clean 程序的堆設置為 2M。 當然,您可以更改此設置。 從命令行使用clm ,您可以將-h 4M添加到其命令行或 clean 程序本身的命令行。 如果您使用的是 Clean IDE,則可以通過“項目選項”、“應用程序”更改堆大小。

(仍然打印(這是我得到的,而不是[ ) 的原因如下。一個 Clean 程序將輸出盡可能多的輸出,而不是等到整個輸出已知。這意味着,對於例如,像Start = [0..]這樣的簡單行會向您的終端發送垃圾郵件,而不是等到整個無限列表都在內存中后再打印它。在squeen.icl的情況下,Clean 看到 Start 的結果將是一個元組,因此直接打印左括號。但是,當嘗試計算元組的元素( length solutionshd solutions )時,堆填滿,使程序終止。

我不知道當你在 Windows 上得到一個完整的堆時會是什么樣子,但在 Linux(/Mac) 上,它看起來像這樣:

$ 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調用解決了這個問題:

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

現在,在調用hd之后,沒有理由將整個列表保留在內存中,因此length可以丟棄它迭代過的元素,並且堆不會填滿。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM