八皇后问题

【算法分析】回溯法解八皇后问题(n皇后问题)

有些话、适合烂在心里 提交于 2019-12-07 04:48:06
回溯法解题思路: (1)针对所给问题,定义问题的解空间;    (2)确定易于搜索的解空间结构;    (3)以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索。 八皇后问题: 八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 图解回溯法解八皇后问题: 回溯法解N皇后问题 1 、使用一个一维数组表示皇后的位置, 其中数组的下标表示皇后所在的行, 数组元素的值表示皇后所在的列。 2 、假设前n- 1 行的皇后已经按照规则排列好, 那么可以使用回溯法逐个试出第n行皇后的合法位置, 所有皇后的初始位置都是第 0 列, 那么逐个尝试就是从 0 试到 N - 1 , 如果达到 N ,仍未找到合法位置, 那么就置当前行的皇后的位置为初始位置 0 , 然后回退一行,且该行的皇后的位置加 1 ,继续尝试, 如果目前处于第 0 行,还要再回退,说明此问题已再无解。 3 、如果当前行的皇后的位置还是在 0 到 N - 1 的合法范围内, 那么首先要判断该行的皇后是否与前几行的皇后互相冲突, 如果冲突,该行的皇后的位置加 1 ,继续尝试, 如果不冲突,判断下一行的皇后, 如果已经是最后一行,说明已经找到一个解

枚举顺序

六眼飞鱼酱① 提交于 2019-12-06 12:18:25
1,设计好的枚举顺序可以减少无用状态的遍历。 2,好的枚举顺序可以满足题目中的输出条件。 如某八皇后问题中的要求输出字典序前三的某问题。 来源: https://www.cnblogs.com/beiyueya/p/11982890.html

八皇后问题—经典回溯算法

余生颓废 提交于 2019-12-05 21:52:28
八皇后问题 八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。 回溯算法思想 回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。八皇后问题就是回溯算法的典型,第一步按照顺序放一个皇后,然后第二步符合要求放第2个皇后,如果没有位置符合要求,那么就要改变第一个皇后的位置,重新放第2个皇后的位置,直到找到符合条件的位置就可以了。回溯在迷宫搜索中使用很常见,就是这条路走不通,然后返回前一个路口,继续下一条路。回溯算法说白了就是穷举法。不过回溯算法使用剪枝函数,剪去一些不可能到达最终状态(即答案状态)的节点,从而减少状态空间树节点的生成。回溯法是一个既带有系统性又带有跳跃性的的搜索算法。它在包含问题的所有解的解空间树中,按照深度优先的策略,从根结点出发搜索解空间树。算法搜索至解空间树的任一结点时,总是先判断该结点是否肯定不包含问题的解。如果肯定不包含,则跳过对以该结点为根的子树的系统搜索,逐层向其祖先结点回溯。否则,进入该子树,继续按深度优先的策略进行搜索

回溯法--八皇后问题

这一生的挚爱 提交于 2019-12-05 10:01:26
def queene(n): helpQueene([-1]*n,0,n) def helpQueene(columnPositions,rowIndex,n): global count if rowIndex == n: count+=1 printSolution(columnPositions,n) return for column in range(n): columnPositions[rowIndex]=column if isValid(columnPositions,rowIndex): helpQueene(columnPositions,rowIndex+1,n) def isValid(columnPositions,rowIndex): for i in range(rowIndex): if columnPositions[i] == columnPositions[rowIndex]: return False elif abs(columnPositions[i]-columnPositions[rowIndex])==(rowIndex-i): return False return True def printSolution(columnPositions,n): for row in range(n): line="" for column

八皇后

蓝咒 提交于 2019-12-04 20:15:30
  今天手撕八皇后。   问题背景:八皇后问题最早是由国际西洋棋棋手马克斯·贝瑟尔于1848年提出。之后陆续有数学家对其进行研究,其中包括高斯和康托,并且将其推广为更一般的n皇后摆放问题。八皇后问题的第一个解是在1850年由弗朗兹·诺克给出的。诺克也是首先将问题推广到更一般的n皇后摆放问题的人之一。1874年,S.冈德尔提出了一个通过行列式来求解的方法,这个方法后来又被J.W.L.格莱舍加以改进。   艾兹格·迪杰斯特拉在1972年用这个问题为例来说明他所谓结构性编程的能力。   八皇后问题出现在1990年代初期的著名电子游戏第七访客中。    ······   不说废话,看题目:   如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的, 任两个皇后都不能处于同一条横行、纵行或斜线上 。   我们可以将它看作一个搜索问题:   (1)以行为单位,逐行向下搜索。   (2)每一行都应该搜索所有可能的值。   (3)之前行的皇后的摆放位置会影响后面行皇后的摆放位置。   注意第三点, 因为我们每摆放一个皇后,都会因为新皇后的作用域而改变整个棋盘的格局,从而影响后续皇后的摆放。所以我们在搜索时,一旦一种路径已经搜索完成,我们需要将尝试该路径时摆放的皇后清空。    那么让我们尝试将每一行需要做的事情写出来:   遍历该行的每一个格子

八皇后问题

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-04 09:25:00
public class EightQueenDemo { public static int count = 0; public boolean check(int array[][], int num, int i, int j) { //每行每列都只有一个棋子 for(int k = 0; k < num; k++) { if(array[i][k] == 1) return false; if(array[k][j] == 1) return false; } /*把i和j的值分别置为比当前棋子位置的值少一,即为左上角一格, i >= 0 && j >= 0;控制i和j在棋盘范围内, --i, --j;向左上角移动 */ for(int s = i - 1, t = j - 1; s >= 0 && t >= 0; s--, t--) { if(array[s][t] == 1) return false; } /*i的值为当前棋子的行值减一,j的值为当前棋子的列值加一,即为右上角一格, i != N && j != N; 控制i和j在棋盘范围内, --i, ++j;向右上角移动 */ for(int s = i - 1, t = j + 1; s >= 0 && t < num; s--, t++) { if(array[s][t] == 1) return false;

python解决八皇后问题

寵の児 提交于 2019-12-04 04:00:50
运用python的生成器可轻松解决八皇后问题 使用元组表示可能的解,其中每个元素表示相应行中皇后所在位置(列),即state[0]=3,则说明第一行的皇后在第4列。 # _*_ coding:utf-8 _*_ import random #检测冲突 def conflict(state, nextX): #state为各皇后相应位置 nextY = len(state) for i in range(nextY): if abs(state[i] - nextX) in (0, nextY - i): #下一个皇后与当前皇后在同一列或位于同一对角线 return True return False #递归 def queens(num=8, state=()): #num为皇后数 for pos in range(num): if not conflict(state, pos): if len(state) == num - 1: yield (pos,) else: for result in queens(num, state + (pos,)): yield (pos,) + result #图形输出(随机一结果) def prettyprint(solution): def line(pos, length=len(solution)): #辅助函数 return '.

生成器递归解决八皇后问题(基本属于抄题,勉强理解)

十年热恋 提交于 2019-12-03 15:50:46
昨天失败了,看了一晚上还是没搞定,但至少有头目了。 讲八皇后之前,我还是先来一个简单的递归生成器: 我给自己标记下分析的思路,怕到时候又忘记了,这是一个多层列表的去除[]剥皮器。 def flatten(nested): try: for sublist in nested: for element in flatten(sublist):         # print(element)         yield element # 主输出,用for循环接受。 except TypeError: yield nested # 子返回 这个看似乎非常简单的递归生成器,本来我以为我看懂了,没仔细分析,后面仔细分析了一下,其实我没懂,再大把力气花下去,又懂了 这种递归生成器用了双yield,其实这里面会让人陷进去,我以前也写过一些简单的递归,一般都是用return,这次的双yield,把我还苦了 因为后面的八皇后递归生成器也是双yield的格式,如果用递归生成器可能也只能用yield, 记住一点yield的返回值需要用next, send(None), 或者案例里面通过for循环取值,其实案例用next取值,可能我分析的时候可以少走很多弯路。 经过测试next取值失败,next取值无法对列表套列表里面的元素全部返回值,只会返回列表套列表的元素里面第一个值。 这个可能跟for

递归—八皇后问题

≡放荡痞女 提交于 2019-12-03 10:11:21
八皇后问题 说明:   八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即: 任意两个皇后都不能处于同一行、同一列或统一斜线上,问有多少中摆法(92) 。 思路分析: (1)第一个皇后先放第一行第一列 (2)第二个皇后放在第二行第一列、然后判断是否OK,如果不OK,继续放在第二列、第三列、依次把所有列都放完,找到一个合适 (3)当得到一个正确解时,在栈回退到上一个栈时,就会开始回溯,即将第一个皇后,放到第一列的所有正确解,全部得到。 (4)然后回头继续第一个皇后放到第二列,后面继续循环执行1,2,3,4的步骤 (5) 来源: https://www.cnblogs.com/niujifei/p/11787987.html

八皇后问题

匿名 (未验证) 提交于 2019-12-03 00:15:02
Description 对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2...b8,其中bi为相应摆法中第i行皇后所处的列数。已经知道8皇后问题一共有92组解(即92个不同的皇后串)。 给出一个数b,要求输出第b个串。串的比较是这样的:皇后串x置于皇后串y之前,当且仅当将x视为整数时比y小。 Input 第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个正整数b(1 <= b <= 92) Output 输出有n行,每行输出对应一个输入。输出应是一个正整数,是对应于b的皇后串。 Sample Input 3 6 4 25 Sample Output 25713864 17582463 36824175 1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <string> 5 #include <math.h> 6 #include <algorithm> 7 #include <vector> 8 #include <stack> 9 #include <queue> 10 #include <set> 11 #include <map> 12 #include <sstream> 13 const int INF