我有一個AI項目中,我應該做一個數獨解算器序言但不使用clpfd
包。我應該如何編寫代碼,並且有什麼方法可以在變量獲取值時進行打印?數獨解算器,而不clpfd
回答
沒有clpfd,你必須編寫一個經典的生成和測試搜索。關於clpfd的好處是約束限制了搜索空間。你可以在不使用clpfd的情況下模擬它。讓我們簡化一下任務,這樣我就可以說明一切。你怎麼能找到解決這兩個方程的X和Y值:X + Y = 10,2 * X + Y - 1 = 15?
首先,編碼您的兩個等式:
eq1(X,Y) :- 10 is X + Y.
eq2(X,Y) :- 15 is 2*X + Y - 1.
現在創建一個求解謂詞搜索空間:
solution(X, Y) :-
between(1, 10, X), between(1, 10, Y),
eq1(X,Y),
eq2(X,Y).
現在你可以運行它,看看:
?- solution(X,Y).
X = 6,
Y = 4 ;
false.
這比clpfd的效率要低,因爲clpfd會注意到關於方程式的事情,這會有助於解決它應變搜索空間:
?- [library(clpfd)].
true.
?- X + Y #= 10, 2*X + Y - 1 #= 15.
2*X+Y#=16,
X+Y#=10.
?- X + Y #= 10, 2*X + Y - 1 #= 15, X in 1..10.
X = 6,
Y = 4.
看,它已經發現只有一個解決方案,我根本不必限制Y.這非常令人印象深刻!但是你仍然可以在沒有clpfd的情況下使用Prolog,它只是更糟。 :)在這個例子中,我們可能嘗試了所有10x10 = 100個可能的組合來找到這個解決方案。效率較低。但並非不可能。
那麼,你有什麼限制,你必須找出數獨?可能是這樣的:
unique(Row) :- sort(Row, Sorted), length(Row, Length), length(Sorted, Length).
all_digits(Row) :- forall(between(1,9,X), memberchk(X, Row)).
等等。
編輯:組合的複雜性估計
假設我們做一個完全無原則搜索:也就是說,我們甚至嘗試顯然是錯誤的情況下,像所有787-9的網格。我們有9x9 = 81個單元格和9個可能的值(1-9)。這會產生9^81 =非常大的數字,在您的一生中不太可能被檢查。而且這些網格中的大部分都將無果而終。
假設你限制你的搜索,使每一行是1-9的排列。有9! 1-9的排列;其中9個,你可以乘以9,所以應該有9!^ 9。這仍然很糟糕! clpfd可能能夠通過結合3x3網格約束來進一步剔除這個問題;我不知道我會如何去做手動,除了以半程序方式,選擇一個3x3的網格排列,然後將每個3x1的排傳遞給下一個3x3的網格選擇。
值得注意的是,經典Prolog程序中的大部分優化都歸結爲使生成步驟生成更好的合格候選者或使測試步驟更便宜。更明顯的實現對檢查更復雜的實現仍然有用。
感謝@mat檢查我的數學和推薦this excellent article on the combinatorial problem of Sudoku。
- 1. 數獨解算器回溯
- 2. 我的數獨解算器不工作
- 3. java數獨解算器值不變
- 4. Python數獨解算器不會返回解決方案
- 5. 使用CLPFD解決CuFrog
- 6. 算法來解決數獨
- 7. Java數獨解算器不改變空單元
- 8. 數獨求解器不改變值
- 9. JavaScript的數獨解算器。以前的數字來自哪裏?
- 10. prolog clpfd:從數據創建算術約束
- 11. 數獨求解器調試
- 12. 數獨求解器bug
- 13. Haskell數獨求解器
- 14. 數獨求解器需要Python算法說明
- 15. C數獨的回溯解算器預檢功能
- 16. 我的數獨解算器總是返回無
- 17. 禪代碼爲一個數獨解算器
- 18. 試圖實施數獨求解器brute foce算法
- 19. 數獨求解器的算法複雜度(Big-O)
- 20. 數獨解算器,獲取框指向正確的瓦片
- 21. 在hadoop中運行數獨解算器示例
- 22. 使用clpfd和fdbg
- 23. 這個數獨解算器運行很長時間,我不知道爲什麼
- 24. 遞歸數獨求解器不正確的解決方案(C++)
- 25. 數獨求解器評估函數
- 26. C++中的數獨檢查器算法
- 27. VBA解算器不復位
- 28. 數獨解算器的異常線程「main」 java.util.ConcurrentModificationException它的迭代器
- 29. 與clpfd橋交叉難題
- 30. 如何調試clpfd程序?
相關OP問題[如何在序列中跟蹤clpfd的回溯?](http://stackoverflow.com/q/41935073/1243762) –
只需首先定義一個好的數據結構來表示一個(未完成的)sudoko,然後實現一個機制,您可以在其中設置一個字段並傳播約束(確保您沒有填寫無效值)。通過使用Prologs回溯機制,它將解決問題。 –
你允許使用變量嗎? – mat