女王统治 给定一个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