女王統治 給定一個n×n板,統治數量是攻擊或佔領每個方塊所需的皇后(或其他棋子)的最小數量。對於n = 8,女王的統治數字爲5. 編寫謂詞解析(N),以獲得覆蓋所有方塊所需的最小皇后數。女王統治
女王統治
回答
這裏是一個愚蠢的「所有解決方案」片段:
queens_coverage(N, Places) :-
findall(X/Y, (between(1,N,X), between(1,N,Y)), B),
placement(B, [], Places).
placement([], Placement, Placement).
placement(Unplaced, SoFar, Placement) :-
select(Place, Unplaced, Places),
remove_attacks(Place, Places, Remains),
placement(Remains, [Place|SoFar], Placement).
remove_attacks(X/Y, [U/V|Places], Remains) :-
(U == X ; V == Y ; abs(U-X) =:= abs(V-Y)),
!, remove_attacks(X/Y, Places, Remains).
remove_attacks(P, [A|Places], [A|Remains]) :-
remove_attacks(P, Places, Remains).
remove_attacks(_, [], []).
如置換的問題通常,該代碼是沒有希望的低效:
?- setof(L-Ps, (queens_coverage(4,Ps),length(Ps,L)), R), length(R, T).
R = [3-[1/1, 2/3, 4/2], 3-[1/1, 2/4, 3/2], 3-[1/1, 2/4, 4/3], 3-[1/1, 3/2, 2/4], 3-[1/1, 3/4, .../...], 3-[1/1, .../...|...], 3-[.../...|...], 3-[...|...], ... - ...|...],
T = 144.
?- setof(L-Ps, (queens_coverage(5,Ps),length(Ps,L)), R), length(R, T).
R = [3-[1/1, 2/4, 4/3], 3-[1/1, 3/4, 4/2], 3-[1/1, 3/4, 5/3], 3-[1/1, 3/5, 4/3], 3-[1/1, 4/2, .../...], 3-[1/1, .../...|...], 3-[.../...|...], 3-[...|...], ... - ...|...],
T = 2064.
?- setof(L-Ps, (queens_coverage(6,Ps),length(Ps,L)), R), length(R, T).
R = [4-[1/1, 2/3, 3/6, 6/2], 4-[1/1, 2/3, 6/2, 3/6], 4-[1/1, 2/4, 4/5, 5/2], 4-[1/1, 2/4, 4/5, .../...], 4-[1/1, 2/4, .../...|...], 4-[1/1, .../...|...], 4-[.../...|...], 4-[...|...], ... - ...|...],
T = 32640.
?- setof(L-Ps, (queens_coverage(7,Ps),length(Ps,L)), R), length(R, T).
ERROR: Out of global stack
當然,存儲所有的列表是一個真正的浪費。
?- integrate(min, qc(7), R).
R = 4-[1/2, 2/6, 4/1, 5/5] .
?- integrate(min, qc(8), R).
R = 5-[1/1, 2/3, 3/5, 4/2, 5/4]
而不是select/3您應該應用適當的啓發式。一個簡單的一個可能是貪婪的選擇......
編輯
這裏是集成:
integrate(min, Goal, R) :-
State = (_, _),
repeat,
( call(Goal, V),
arg(1, State, C),
((var(C) ; V @< C) -> U = V ; U = C),
nb_setarg(1, State, U),
fail
; arg(1, State, R)
),
!.
nb_setarg/3是SWI-Prolog的內置,ARG/3的ISO。如果你的Prolog錯過了它們,你應該用assert/retract來取代 - 比如說。
集成需要謂詞,並且與附加的參數調用它與所存儲的當前最小進行比較:這裏是:
qc(N, L-Ps) :- queens_coverage(N,Ps),length(Ps,L).
作爲貪婪啓發式,安置的第二條款可以被替換通過
placement(Unplaced, SoFar, Placement) :-
integrate(min, peek_place_of_min_remain(Unplaced), (_Count,Place,Remains)),
!, placement(Remains, [Place|SoFar], Placement).
peek_place_of_min_remain(Unplaced, (Count,Place,Remains)) :-
select(Place, Unplaced, Places),
remove_attacks(Place, Places, Remains),
length(Remains, Count).
嗨CapelliC, 1.我需要澄清我的問題:任何兩個皇后允許互相攻擊,也就是說兩個皇后可以在同一排,柱或對角線上。 但是在你提供的解決方案中,似乎兩個皇后不可能。我想稍微改變一下代碼。你能否解釋下面的條款真的這麼做: remove_attacks(P,[A | Places],[A | Remains]): - remove_attacks(P,Places,Remains)。 我有點困惑。現在我再次陷入困境。 – user2585677
2.你的建議是對的,我應該使用貪婪的啓發式。我想出了一個啓發式的,但我不知道如何在序言中實現。啓發式 函數是h =#(未覆蓋方塊)。具體而言,每次我們選擇這樣的方形來放置一次將皇后放在正方形上的皇后時,剩下的未被覆蓋的正方形的數量是最少的。 3.您能否在命令'integrate(min,qc(7),R)'中提供謂詞「integrate」的代碼。 – user2585677
現在我瞭解了'整合'的細節。並等待更多指導。 – user2585677
- 1. 女王碰撞
- 2. 8女王的可能解決方案。
- 3. 超級女王謎陣列例外
- 4. 定製Yii的統治PARAM
- 5. 有一個NetBeans統治者
- 6. 大O和函數統治
- 7. 國際象棋遊戲中的女王運動(Javascript)
- 8. 我女王之謎的代碼有什麼錯誤?
- 9. N-Queens算法。劇情扭曲:女王也是騎士
- 10. N皇后女王是安全的無限循環
- 11. n女王回溯迭代所有的位置
- 12. c#解決與int數組八個女王?
- 13. Rails的王菲實時通知系統
- 14. Sparql:獲得統治城市的所有政治家
- 15. One Upstart統治他們全部
- 16. 一個XSLT來統治他們
- 17. 是有效的哥倫布統治者
- 18. 一個segue來統治他們全部
- 19. 象棋任務 - 王魯克Vs的王
- 20. 國王迷宮
- 21. 親子王國
- 22. autohotkeys王牌編輯
- 23. 在王牌編輯
- 24. 找到所有的客戶名稱由三個或更多的話(例如英王喬治五世)
- 25. 解決N皇后統治難題的算法
- 26. 如何在複合辛普森的統治方法
- 27. 由控制檯統治的應用程序取決於它
- 28. 一張桌子來統治他們全部,或千人小?
- 29. 看跌的div像統治者在左側和頂部W/jsfiddle.net
- 30. Flex DataGrid列寬:一列來統治它們全部?
N皇后問題是不同的:找到一個安置皇后不相互攻擊。 – CapelliC
當然,我的問題是:給定一個n×n棋盤,找到控制號碼,這是攻擊或佔用每個方塊所需的最少皇后數量。對於n = 8女王的統治數字是5. – user2585677
嗨,CapelliC,上面的代碼是你在另一個問題中的答案。你能否提供一些關於我的問題的提示?我看到了一些算法,但我仍然不知道如何解決皇冠統治問題。 – user2585677