Hao Chen

cighao@gmail.com

  • About ME
  • Archives
  • Exploring World
Search

Hao Chen

cighao@gmail.com

  • About ME
  • Archives
  • Exploring World

利用概率算法求解八皇后问题

2016-10-20

前面介绍了通过回溯法求解八皇后问题

但是当皇后的数量较多时,回溯法非常地耗时。所以提出了一种基于概率地随机放置皇后的方法。

每次都将8个皇后随机放在8行,如果满足条件就成功,否则全部重新放置,直到成功为止。

实验表明,这样地放置方法比回溯法更快。

还有一种优化就是对于一部分皇后随机放置,另一部分皇后采用回溯法放置,这样效果会更好。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include"stdio.h"
#include"stdlib.h"
#include"assert.h"
#include"time.h"

#define MAX 500
int check_pos(const int r[MAX],const int i,const int j);
void print(const int r[MAX],const int n);
int queen_lv(int r[MAX],const int n);

int main(int argc,char *argv[]){
if(argc!=2){
fprintf(stderr,"Please input the number of queen!\n");
return 0;
}
int n=atoi(argv[1]);
if(n<4){
fprintf(stderr,"The number of queen must be larger than 4 !\n");
return 0;
}
srand((unsigned int)time(NULL));
int results[MAX]; // results[i]=j,表示把第i个皇后放在位置(i,j)上
while(queen_lv(results,n)==0)
; //一直随机放,直到存在一个解
// print(results,n);
return 0;
}

//所有皇后的位置都是随机放的
int queen_lv(int r[MAX],const int n){
int num=0;
int i,j,k,nb;
i= 0;
while(1){
nb = 0; //第i个皇后可以放的位置的数量
for(j=0;j<n;j++){ // 试探0-7的位置对于第 i 个皇后来说是否可以放置
if(check_pos(r,i,j)){
nb++;
if(rand()%nb+1 == 1) //以 1/nb 的概率将第i个皇后放在j列上
k=j;
}
}
if(nb>0){ //放置第i个皇后的位置,并继续放下一个皇后
r[i++] = k;
}
if(nb==0 || i==n)
break;
}
if(nb>0)
return 1; //成功了
else
return 0;//如果第i个皇后没有可行的位置,则这次随机过程失败,完全重新开始放置
}

//第i个皇后放在(i,j)位置是否合适
int check_pos(const int r[MAX],const int i,const int j){
int k;
for(k=0;k<i;k++){
if(r[k] == j) //是否在同列
return 0;
if(r[k]+k == i+j) //是否在45度对角线
return 0;
if(r[k]-k == j-i) //是否在135度对角线
return 0;
}
return 1;
}
//打印皇后放置的位置
void print(const int r[MAX],const int n){
//省略,参考之前的代码
}

结果

分别利用回溯法和 Las Vegas 概率算法求解 n 皇后问题的一个解,对它们所耗的时间进行比较。

当 n=8 时,回溯法 0.084ms,Las Vegas 概率算法 0.029 ms。

当 n=20 时,回溯法 133.581ms,Las Vegas 概率算法 9.314 ms。

改进

Las Vegas 概率算法每次放置皇后的位置都是随机的,这样过于悲观。可以使用 Las Vegas 算法放置前一部分的皇后,后面的皇后使用回溯法放置,但不考虑重放前面通过 LV 算法放置的皇后。

代码实现方面只要将后面的几行改为:

1
2
3
4
5
6
7
if(nb = 0 || i = stepVegas) //跳出循环
break;
...
if(nb>0) //已随机放好stepVegas个皇后
backtrace(); //采用回溯法放后面的皇后
else
return 0;

改进后的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include"stdio.h"
#include"stdlib.h"
#include"assert.h"
#include"time.h"

#define MAX 500

int check_pos(const int r[MAX],const int i,const int j);
void print(const int r[MAX],const int n);
int queen_lv(int r[MAX],const int n,const int sv);
int backtrace(int r[MAX],const int n,int start);

int main(int argc,char *argv[]){
if(argc!=3){
fprintf(stderr,"Please input the number of queen and vs!\n");
return 0;
}
int n=atoi(argv[1]);
if(n<4){
fprintf(stderr,"The number of queen must be larger than 4 !\n");
return 0;
}
int sv=atoi(argv[2]);
srand((unsigned int)time(NULL));
int results[MAX]; // results[i]=j,表示把第i个皇后放在位置(i,j)上

while(queen_lv(results,n,sv)==0)
; //一直随机放,直到存在一个解

//print(results,n);
return 0;
}

// 前vs个皇后随机放置
int queen_lv(int r[MAX],const int n,const int sv){
int num=0;
int i,j,k,nb;
i= 0;
while(1){
nb = 0; //第i个皇后可以放的位置的数量
for(j=0;j<n;j++){ // 试探0-7的位置对于第 i 个皇后来说是否可以放置
if(check_pos(r,i,j)){
nb++;
if(rand()%nb+1 == 1) //以 1/nb 的概率将第i个皇后放在j列上
k=j;
}
}
if(nb>0){ //放置第i个皇后的位置,并继续放下一个皇后
r[i++] = k;
}
if(nb==0 || i==sv)
break;
}
if(nb>0)
return backtrace(r,n,sv+1); //成功了
else
return 0;//如果第i个皇后没有可行的位置,则这次随机过程失败,完全重新开始放置
}

//利用回溯法从第start个皇后开始放,前start-1个已经放好了
int backtrace(int r[MAX],const int n,int start){
int i,j,num;
i=start;j=0,num=0;
while(1){
int find=0;
while(j<n){ // 寻找第i个皇后放置的位置j
if(check_pos(r,i,j))
break;
j++;
}
if(j<n){ // 如果找到了记录该位置,继续放置第i个皇后
r[i++] = j;
j = 0;
}else{ // 如果没有找到合适的位置,回溯到第i-1个皇后,将其位置放在原来位置的下一个位置
j = r[--i] + 1 ;
}
if(i == n && r[i-1]<n){ //找到了一个合适的解
//print(r,n);
j=r[--i]+1;
num++;
return num; //找到一个解就返回
}else if(i<start) //已经找到了全部的解
break;
}
return num;
}
//第i个皇后放在(i,j)位置是否合适
int check_pos(const int r[MAX],const int i,const int j){
//省略,参考之前的代码
}
//打印皇后放置的位置
void print(const int r[MAX],const int n){
//省略,参考之前的代码
}
  • 算法

扫一扫,分享到微信

微信分享二维码
flashsim 源码分析(一):安装 flashsim
回溯法求解八皇后问题

Related Issues not found

Please contact @cighao to initialize the comment

© 2025 Hao Chen
Hexo Theme Yilia by Litten
  • Search

tag:

  • Javascript
  • Web 前端
  • Matlab
  • 遗传算法
  • 算法
  • Hexo
  • 计算机
  • Linux IO
  • Cassandra
  • 数论
  • SSD
  • NVMe
  • Database
  • 论文阅读
  • Disksim
  • flashsim
  • Ubuntu
  • 画图
  • 信号处理
  • 黑客
  • Mysql
  • Python
  • 爬虫
  • 粒子群算法
  • 模拟退火算法
  • Neo4j
  • Ngrok
  • SPDK
  • RocksDB
  • Java
  • Matplotlib
  • openstack swift
  • 分布式存储
  • 对象存储
  • 学术
  • Tool
  • C语言
  • 正则表达式
  • 端口扫描
  • 二层规划
  • 排序
  • 随笔
  • Nodejs
  • Tools
  • 数据库

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

  • 数据库中的热点行优化 (SIGMOD'21 Paper 解读)

    2022-02-28

    #Database#论文阅读

  • NVMe SSD中namespace的介绍和创建

    2020-04-12

    #SSD#NVMe

  • 快速搭建 L2TP VPN 服务器

    2019-11-20

    #计算机#Tool

  • SPDK 介绍(二):SPDK 相关博客

    2019-10-25

    #SPDK

  • SPDK 介绍(一):使用 FIO 测试 SPDK

    2019-10-23

    #SPDK

  • RocksDB 介绍(一):相关博客

    2019-10-22

    #RocksDB

  • Linux IO 相关资料

    2019-09-29

    #计算机#Linux IO

  • Cassandra 介绍(三):Commitlog 介绍(1)

    2019-09-26

    #Cassandra

  • Cassandra 介绍(二):Blogs

    2019-09-22

    #Cassandra

  • Cassandra 介绍(一):Install and test with YCSB

    2019-09-19

    #Cassandra

  • 阿里数据库内核月报(汇总)

    2019-09-03

    #数据库

  • Neo4j 介绍(五):使用 java 访问 neo4j

    2019-04-24

    #Neo4j

  • Neo4j 介绍(四):关于 neo4j 的一些博客

    2019-04-21

    #Neo4j

  • Neo4j 介绍(三):使用 python 访问 neo4j

    2019-04-21

    #Neo4j

  • Neo4j 介绍(二):main 函数

    2019-04-13

    #Neo4j

  • 日常遇到的一些小问题的解决方案

    2019-03-29

    #计算机#Tool

  • Neo4j 介绍(一):安装

    2019-03-21

    #Neo4j

  • matlab 画图(十): 分组和堆叠的条形图

    2019-01-13

    #Matlab#画图

  • 论文写作常用工具

    2018-11-20

    #Tools

  • Openstack Swift学习(八):配置ntp

    2018-09-29

    #openstack swift#分布式存储#对象存储

  • Openstack Swift学习(七):ssbench 使用

    2018-09-29

    #openstack swift#分布式存储#对象存储

  • Openstack Swift学习(六):服务启动源码分析

    2018-09-29

    #openstack swift#分布式存储#对象存储

  • Openstack Swift学习(五):debug 总结

    2018-09-29

    #openstack swift#分布式存储#对象存储

  • Openstack Swift学习(四):中间件

    2018-09-29

    #openstack swift#分布式存储#对象存储

  • Openstack Swift学习(三):log 配置

    2018-09-22

    #openstack swift#分布式存储#对象存储

  • Openstack Swift学习(二):相关文档

    2018-07-20

    #openstack swift#分布式存储#对象存储

  • Openstack Swift学习(一):安装

    2018-07-12

    #openstack swift#分布式存储#对象存储

  • 在 linux 上首次使用 SSD

    2017-03-20

    #SSD

  • disksim-3.0 with flashsim 源码分析(六):垃圾回收

    2017-02-27

    #SSD#Disksim#flashsim

  • disksim-3.0 with flashsim 源码分析(五):写操作

    2017-02-27

    #SSD#Disksim#flashsim

  • disksim-3.0 with flashsim 源码分析(四):初始化

    2017-02-27

    #SSD#Disksim#flashsim

  • disksim-3.0 with flashsim 源码分析(三):callFsim()函数介绍

    2017-02-21

    #SSD#Disksim#flashsim

  • disksim-3.0 with flashsim 源码分析(二):DFTL 中的 cache

    2016-12-10

    #SSD#Disksim#flashsim

  • disksim-3.0 with flashsim 源码分析(一):disksim-3.0 和 flashsim 的安装

    2016-12-06

    #SSD#Disksim#flashsim

  • flashsim 源码分析(五): flashsim 的初始化

    2016-11-22

    #SSD#flashsim

  • flashsim 源码分析(四): 总线上锁机制的实现

    2016-11-13

    #SSD#flashsim

  • flashsim 源码分析(三): 总线通道中的交叉

    2016-11-11

    #SSD#flashsim

  • flashsim 源码分析(二): flashsim 中的面向对象设计

    2016-11-09

    #SSD#flashsim

  • flashsim 源码分析(一):安装 flashsim

    2016-11-08

    #SSD#flashsim

  • 利用概率算法求解八皇后问题

    2016-10-20

    #算法

  • 回溯法求解八皇后问题

    2016-10-20

    #算法

  • 利用概率算法估算集合大小

    2016-10-17

    #算法

  • 神奇的卡特兰数

    2016-10-07

    #算法#数论

  • 论文阅读:基于闪存的缓冲区管理算法

    2016-08-23

    #SSD#论文阅读#学术

  • 论文阅读:针对闪存的成本感知的缓冲区管理策略(DASFAA 2015)

    2016-08-19

    #SSD#论文阅读#学术

  • 暴力破解 wifi 密码

    2016-08-04

    #黑客

  • 论文阅读:SSD内部多级并行性的探索和利用(TOC 2013)

    2016-07-20

    #SSD#论文阅读#学术

  • 论文阅读:SSD中基于PSO的缓冲区管理算法(ICITCS 2015)

    2016-07-19

    #SSD#论文阅读#学术

  • 利用二级指针删除链表节点

    2016-07-09

    #算法

  • 抓包获取简书的登录密码

    2016-07-07

    #黑客

  • disksim with ssdmodel 源码解析(二十二):读写和擦除时间的计算

    2016-06-28

    #SSD#Disksim

  • 求离散采样信号的波峰和波谷

    2016-05-31

    #信号处理

  • matlab 画图(九): 横坐标标签倾斜设置

    2016-05-13

    #Matlab#画图

  • matlab 画图(八): 双坐标绘图

    2016-04-29

    #Matlab#画图

  • matlab 画图(七): 扇形图

    2016-04-24

    #Matlab#画图

  • matlab 画图(六): 横向柱状图

    2016-04-20

    #Matlab#画图

  • matlab 画图(五): 垂直柱状图

    2016-04-17

    #Matlab#画图

  • matlab 画图(四): 句柄作图示例

    2016-04-16

    #Matlab#画图

  • disksim with ssdmodel 源码解析(二十一):warm up ssd

    2016-04-15

    #SSD#Disksim

  • matlab 画图(三): 图形句柄

    2016-04-14

    #Matlab#画图

  • matlab 画图(二): 基本作图技巧

    2016-04-13

    #Matlab#画图

  • disksim with ssdmodel 源码解析(二十):统计结果的提取

    2016-04-12

    #SSD#Disksim

  • matlab 画图(一): 线条样式设计

    2016-04-11

    #Matlab#画图

  • disksim with ssdmodel 源码解析(十九):ssd 的初始化

    2016-03-31

    #SSD#Disksim

  • disksim with ssdmodel 源码解析(十八):GC 分析(五)

    2016-03-30

    #SSD#Disksim

  • disksim with ssdmodel 源码解析(十七):GC 分析(四)

    2016-03-30

    #SSD#Disksim

  • SSD 编程学习笔记(一)

    2016-03-29

    #SSD

  • disksim with ssdmodel 源码解析(十六):GC 分析(三)

    2016-03-29

    #SSD#Disksim

  • disksim with ssdmodel 源码解析(十五):GC 分析(二)

    2016-03-27

    #SSD#Disksim

  • disksim with ssdmodel 源码解析(十四):ssd_activate_elem函数分析

    2016-03-24

    #SSD#Disksim

  • disksim with ssdmodel 源码解析(十三):如何兼容64位系统

    2016-03-23

    #SSD#Disksim

  • disksim with ssdmodel 源码解析(十二):写操作分析

    2016-03-23

    #SSD#Disksim

  • disksim with ssdmodel 源码解析(十一):地址映射

    2016-03-23

    #SSD#Disksim

  • matplotlib 画图(四):text 和 label 的设置

    2016-03-22

    #画图#Matplotlib

  • disksim with ssdmodel 源码解析(十):GC分析(一)

    2016-03-19

    #SSD#Disksim

  • disksim with ssdmodel 源码解析(九):syssim_driver 系统级接口(二)

    2016-03-19

    #SSD#Disksim

  • disksim with ssdmodel 源码解析(八):syssim_driver 系统级接口(一)

    2016-03-19

    #SSD#Disksim

  • matplotlib 画图(三):线的连续与间断

    2016-03-19

    #画图#Matplotlib

  • disksim with ssdmodel 源码解析(七):block的组织形式

    2016-03-18

    #SSD#Disksim

  • matplotlib 画图(二):图形填充

    2016-03-17

    #画图#Matplotlib

  • disksim with ssdmodel 源码解析(六):disksim_setup_disksim

    2016-03-16

    #SSD#Disksim

  • disksim with ssdmodel 源码解析(五):程序流程介绍

    2016-03-16

    #SSD#Disksim

  • matplotlib 画图(一):横向柱状图

    2016-03-16

    #画图#Matplotlib

  • 一种时间复杂度为 O(N) 整数排序算法

    2016-03-15

    #算法#排序

  • disksim with ssdmodel 源码解析(四):ssd_event_arrive 函数的介绍

    2016-03-13

    #SSD#Disksim

  • disksim with ssdmodel 源码解析(三):初次使用介绍

    2016-03-12

    #SSD#Disksim

  • disksim with ssdmodel 源码解析(二):输入参数的介绍

    2016-03-06

    #SSD#Disksim

  • 在 Hexo 中给文章添加版权信息

    2016-03-01

    #Hexo

  • python中的爬虫神器 XPath 介绍

    2016-03-01

    #Python#爬虫

  • 程序员得长多高

    2016-02-26

    #Python#爬虫#随笔

  • Hexo 博客添加打赏功能

    2016-02-23

    #Hexo

  • Hexo 主题优化

    2016-02-14

    #Hexo

  • 利用 HttpClient 刷 CSDN 博客文章浏览量

    2016-02-04

    #Java

  • nodejs 中模块使用的介绍

    2016-01-10

    #Nodejs

  • 利用 javascript 实现回到顶部效果

    2016-01-09

    #Javascript#Web 前端

  • Ngrok: 一个提供内网到外网映射的工具

    2015-12-18

    #Ngrok

  • 如何给数百万考生的成绩排序

    2015-12-17

    #算法#排序

  • 在 Hexo 中给文章添加目录

    2015-12-13

    #Hexo

  • Java 动态加载类

    2015-12-06

    #Java

  • python 中安装 requests 模块

    2015-12-05

    #Python#爬虫

  • 利用模拟退火算法求解TSP问题

    2015-12-04

    #算法#模拟退火算法

  • 模拟退火算法简介

    2015-12-03

    #算法#模拟退火算法

  • 粒子群优化算法简介

    2015-11-30

    #算法#粒子群算法

  • Hexo yilia主题添加网站访客人数统计

    2015-11-30

    #Hexo

  • 利用粒子群算法求解非线性二层规划问题

    2015-11-07

    #算法#粒子群算法#二层规划

  • 遗传算法的 matlab 实现

    2015-11-03

    #Matlab#遗传算法#算法

  • 基于javascript实现的2048小游戏

    2015-11-02

    #Javascript#Web 前端

  • 随机生成正整数 1-n 的一个排列

    2015-10-11

    #算法#C语言

  • disksim with ssdmodel 源码解析(一):disksim及ssdmodel模块扩展的安装

    2015-09-09

    #SSD#Disksim#Ubuntu

  • 固态硬盘(SSD)原理及相关介绍

    2015-08-31

    #SSD

  • windows7下安装ubuntu及相关问题的解决方案

    2015-08-27

    #Ubuntu

  • python 正则表达式的使用

    2015-08-22

    #Python#爬虫#正则表达式

  • 基于 python socket 的端口扫描程序

    2015-03-29

    #Python#端口扫描

  • mysql windows 下zip安装

    2015-03-29

    #Mysql