算法实验5--N皇后
实验名称
回溯法解N皇后问题
实验目的
- 掌握回溯递归算法、迭代算法的设计与实现;
- 设计回溯算法求解;
- 分析算法的时间复杂度。
实验环境
操作系统:win 10;
编程语言:Java;
开发工具:IDEA;
问题描述
在n×n
格的国际象棋上摆放n个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法?
实验过程
回溯法
按照优先级条件向前搜索以达到目标。但是当探索到某一步时,发现原先选择并不能达到目标,就退回上一步重新选择,这种走不通就退回的技术叫做回溯。
问题解决思路
用数组模拟棋盘,从第一行开始,依次选择位置,如果当前位置满足条件,则向下选择位置,如果不满足条件,那么当前位置向后移动一位。
最后一个不满足,回溯到上一行,选择下一个位置继续进行探索。
其实并不需要一个n*n的数组,我们只需要一个长度为n的数组来存储位置,array[i] = k;表示第i行,第k个位置放皇后。
解题步骤
1. 因为皇后之间不能放在同一行,同一列,同一斜线。所以每行放一个皇后,就解决了不在同一行的问题。result[row]=j;表示第row行,第j列放置皇后。
2. 在第i行的时候,遍历n列,试探位置,和之前所有行放的位置进行比较。
3. 判断当前位置是否可以放皇后:如果当前列和之前皇后所在的列相等即result[i] == col 或者在同一个斜线上: result[i] == col - sub || result[i] == col + sub;代表当前位置不合法,返回false,如果当前位置可以放置皇后,那就将这个位置的坐标记录下来result[row] = j;j代表的是皇后所在的列;
4. 回溯,然后在下一行寻找皇后放置的位置。
代码实现
1. package org.qianyan.algorithm;
2.
3. import java.util.ArrayList;
4. import java.util.Arrays;
5. import java.util.List;
6.
7. /**
8. * @Author Huhuitao
9. * @Date 2020/12/17 15:51
10. */
11. public class NQueens {
12. public static void main(String[] args) {
13. NQueens nQueens = new NQueens();
14. long begin_time = System.currentTimeMillis();
15. int N = 8;
16. List<List<String>> lists = nQueens.solveNQueens(N);
17. long end_time = System.currentTimeMillis();
18. System.out.println(end_time - begin_time + "ms");
19. lists.stream().forEach(list -> {
20. System.out.println("==========================");
21. for (int i = 0; i < list.size(); i++) {
22. System.out.println(list.get(i));
23. }
24. });
25. System.out.println("==========================");
26. System.out.println(N+"皇后,有"+lists.size()+"种解决方案");
27. }
28.
29. private List<List<String>> results = new ArrayList<>(); // 结果集
30.
31. public List<List<String>> solveNQueens(int n) {
32. int[] result = new int[n]; // 记录每一行皇后放置的 列坐标
33. backtracking(result, 0);
34. return results;
35. }
36.
37. /**
38. * 回溯
39. *
40. * @param result
41. * @param row
42. */
43. private void backtracking(int[] result, int row) {
44. if (row == result.length) {
45. //递归结束条件,放置完成最后一行,将结果添加到results
46. List<String> temp = new ArrayList<>();
47. for (int i = 0; i < result.length; i++) {
48. char[] str = new char[row];
49. Arrays.fill(str, '.');
50. str[result[i]] = 'Q';
51. temp.add(new String(str)); // 根据每一行出现皇后的位置填充解
52. }
53. results.add(temp); // 加入当前解
54.
55. }
56. for (int j = 0; j < result.length; j++) {
57. //如果这个位置能放置皇后
58. if (isValidation(result, row, j)) {
59. //记录放置坐标
60. result[row] = j;
61. //放置下一行
62. backtracking(result, row + 1);
63. }
64. }
65.
66. }
67.
68. // 验证,无同行/同列棋子
69. // 对角线无棋子
70. private boolean isValidation(int[] result, int row, int col) {
71. for (int i = 0; i < row; i++) { // 第一行可以放任意位置
72. int sub = row - i; // 行数差
73. // 如果同列、同对角线出现皇后,说明不能在row col放置皇后
74. if (result[i] == col || result[i] == col - sub || result[i] == col + sub) {
75. return false;
76. }
77. }
78. //检测结束后能放置
79. return true;
80. }
输出结果
算法分析
N 皇后问题的解空间是一棵n叉树,树的深度是n,最坏情况下解空间树深度是n,除了根节点和叶子结点,其余结点的子节点有n个分支,总分枝的个数是nn,每个分支都判断约束函数,判断约束条件需要O(n)的时间,因此耗时需要O(n(n+1)),所以时间复杂度是O(n^(n+1));
回溯法的另一个重要特性是在搜索执行的同时产生解空间,从开始结点起最长的路径是n,我们声明的result数组大小是n,用来保存皇后的坐标。所以该算法的空间复杂度是O(n)。
回溯法算是一种选优搜索法,按照选优条件深度优先搜索,达到目标,当搜索到某一步时,发现原先选择不是目标或者不是最优就退回重新选择。这种方法通过剪枝来减少递归的次数。如果超时的话可以换其他方法解决。
算法实验5--N皇后的更多相关文章
- 【算法导论】八皇后问题的算法实现(C、MATLAB、Python版)
八皇后问题是一道经典的回溯问题.问题描述如下:皇后可以在横.竖.斜线上不限步数地吃掉其他棋子.如何将8个皇后放在棋盘上(有8*8个方格),使它们谁也不能被吃掉? 看到这个问题,最容易想 ...
- 【StatLearn】统计学习中knn算法实验(2)
接着统计学习中knn算法实验(1)的内容 Problem: Explore the data before classification using summary statistics or vis ...
- 数据结构与算法实验题 6.1 s_sin’s bonus
数据结构与算法实验题 6.1 s_sin's bonus ★实验任务 正如你所知道的 s_sin 是一个非常贪玩的人 QAQ(如果你非常讨厌他请直接从第二段开 始看),并且令人感到非常遗憾的是,他是一 ...
- 数据结构与算法实验题 9.1 K 歌 DFS+剪枝
数据结构与算法实验题 K 歌 ★实验任务 3* n 个人(标号1~ 3 * n )分成 n 组 K 歌.有 m 个 3 人组合,每个组合都对应一个分数,你能算出最大能够得到的总分数么? ★数据输入 输 ...
- 数据结构与算法实验题 4.2 Who is the strongest
数据结构与算法实验题 4.2 Who is the strongest ★实验任务 在神奇的魔法世界,召唤师召唤了一群的魁偶.这些魁偶排成一排,每个魁偶都有一个 战斗值.现在该召唤师有一个技能,该技能 ...
- HDU 3791 二叉搜索树 (数据结构与算法实验题 10.2 小明) BST
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=3791 中文题不说题意. 建立完二叉搜索树后进行前序遍历或者后序遍历判断是否一样就可以了. 跟这次的作业第 ...
- 吴裕雄--天生自然HADOOP学习笔记:hadoop集群实现PageRank算法实验报告
实验课程名称:大数据处理技术 实验项目名称:hadoop集群实现PageRank算法 实验类型:综合性 实验日期:2018年 6 月4日-6月14日 学生姓名 吴裕雄 学号 15210120331 班 ...
- 201871010110-李华 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告
项目 内容 课程班级博客链接 班级博客 这个作业要求链接 作业要求 我的课程学习目标 (1)理解并掌握代码风格及设计规范:(2)通过任务3进行协作开发,尝试进行代码复审,在进行同伴复审的过程中体会结对 ...
- 201871030108-冯永萍 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告
实验三 软件工程结对项目 项目 内容 课程班级博客链接 https://edu.cnblogs.com/campus/xbsf/2018CST 这个作业要求链接 https://www.cnblogs ...
- 201871030116-李小龙 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告
项目 内容 课程班级博客链接 https://edu.cnblogs.com/campus/xbsf/2018CST 这个作业要求链接 https://www.cnblogs.com/nwnu-dai ...
随机推荐
- 重庆聚焦区块链应用,Panda Global觉得春天真的来了!
近日,由2020中国智博会组委会主办.重庆市大数据应用发展管理局与渝中区人民政府联合承办.重庆市区块链应用创新产业联盟和四川省区块链行业协会联合执行的"2020线上智博会区块链应用创新大赛& ...
- Codeforces Edu Round 47 A-E
A. Game Shopping 按照题意模拟既可. #include <iostream> #include <cstdio> using namespace std; co ...
- SpringBoot添加多数据源mysql和oracle
项目结构 多数据源配置文件 MultiDataSourceConfig.java SqlSessionTemplate1.java SqlSessionTemplate2.java package c ...
- elasticsearch-head 配置
elasticsearch-head install node.js Download node.js: 将下载的包,解压并配置环境变量 vim /etc/profile #set for n ...
- sqli-labs Less24 登录出现报错Cannot send session cache limiter....
问题描述 这是一道二次注入题,注册完成后,应该登录然后修改密码,但是登录的时候出现: Warning: session_start(): Cannot send session cache limit ...
- Java基础进阶:学生管理系统数组方式分包源码实现,教师管理系统集合和数组两种方式源码实现,图书馆管理系统源码实现,现附重难点,代码实现源码,课堂笔记,课后扩展及答案
1.案例驱动模式 1.1案例驱动模式概述 (理解) 通过我们已掌握的知识点,先实现一个案例,然后找出这个案例中,存在的一些问题,在通过新知识点解决问题 1.2案例驱动模式的好处 (理解) 解决重复代码 ...
- Python之复制列表
将一个列表的数据复制到另外一个列表中. 1 a = [1,2,3] #定义列表a 2 3 b = a[:] #将列表a的切片赋值给b,也可以理解为将b的值设置为a[:] 4 5 print(a) #打 ...
- spring整合sharding-jdbc实现分库分表
1.创建两个库,每个库创建两个分表t_order_1,t_order_2 DROP TABLE IF EXISTS `t_order_1`; CREATE TABLE `t_order_1` ( `i ...
- 基于Redis的消息队列使用:spring boot2.0整合redis
一 . 引入依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="ht ...
- Mybatis【8】-- Mybatis返回List或者Map以及模糊查询怎么搞?
使用mybatis的时候,经常发现一个需求,我怎么知道自己是不是增加/修改/删除数据成功了? 好像执行sql之后都没有结果的.其实不是的,增删改的sql执行之后都会有一个int类型的返回值,表示的意思 ...