毕竟新手上路23333,有谬误还请指正。 课程设计遇到八数码问题(这也是一坨),也查过一些资料并不喜欢用类函数写感觉这样规模小些的问题没有必要,一开始用深度搜索却发现深搜会陷入无底洞,如果设定了深度限制又会有很多情况无法找到,然后果断放弃,改用广度搜索。  如果要改善代码效率还可以用双向搜索,即从起始状态和最终状态同时搜索,找到相同状态,这样搜索时间会缩短一半。此外还可以用A*(启发式算法)会显得高端很多。

题目要求: 在一个3*3的棋盘上,随机放置1到8的数字棋子,剩下一个空位。数字可以移动到空位(编程时,空位可用0代替,且可以理解为是空位的上、下、左、右移动),经过若干次移动后,棋局到达指定目标状态。 数组表示棋局状态。用函数表示空格(0)的移动,使用函数具有前提条件,满足条件才可以使用。 用广度优先或深度优先搜索求解。还可以使用启发式求解,以提高搜索效率。 要求: ① 编程求解问题; ② 给出中间状态; ③ 给出解序列(函数调用序列)

 #include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <sstream>
#include <deque>
#include <functional>
#include <iterator>
#include <list>
#include <map>
#include <memory>
#include <stack>
#include <set>
#include <numeric>
#include <utility>
#include <cstring>
#include <fstream> using namespace std;
int board[]; //初始状态,一维数组模拟二维
int destboard[]; //目标状态
int dx[] = {-, , , }; //数字0的移动偏移量
int dy[] = {, , , -};
map<int, bool> mark; //记录已搜索的状态 int lists(int i, int j)
{
return i* + j; //返回i, j二维数组的一维位置
} int judge() //运算前判断是否可以找到一种对于初末状态可行的变换
{
int first_d[],last_d[],i,j=,k,rank1=,rank2=;
for(i=;i<=;i++) //初状态赋值给first_d[10]
{
while()
{
if(j==){j=;}
if(j==){j=;}
first_d[i]=destboard[j];
j++;
break;
}
}
j=;i=;
for(k=;k<=;k++) //最终状态赋值给last_d[10]
{
while()
{
last_d[k]=board[lists(i, j)];
j++;
if(j==){i++;j=;}
break;
}
} for(j=;j<=;j++) //计算初状态的奇偶性
{
for(i=;i<j;i++)
{
if(first_d[i]>first_d[j]&&first_d[i]!=&&first_d[j]!=){rank1++;}
}
} for(j=;j<=;j++) //计算末状态的奇偶性
{
for(i=;i<j;i++)
{
if(last_d[i]>last_d[j]&&last_d[i]!=&&last_d[j]!=){rank2++;}
}
}
int a1=rank1%,a2=rank2%;
if(a1!=a2){return ;} //判断奇偶性是否相同,相同才可以从出状态变到末状态
else{return ;}
} struct Stat //结构体三个参数
{
int step; // 步数
int board[]; // 状态
Stat(int *b, int s=)
{
memcpy(this->board, b, sizeof(int)*); //对状态的赋值操作
step = s;
}
}; bool ok(int *b) // 判断是否到已经达目标状态
{
for(int i=; i<=; ++i)
for(int j=; j<=; ++j)
{
if(b[lists(i, j)] != destboard[lists(i, j)])
return false;
}
return true;
} int Bfs()
{
int judge_first=judge();
ofstream ofs; //建立数据外存文件
ofs.open("output.dat");
if(judge_first==){cout<<"不存在"<<endl;return ;}
if(judge_first==)
{
queue<Stat> que; //建队que
que.push(Stat(board, )); // 初始状态入队
while(que.size())
{
int m=, mk=; // 记录状态m,以及基数mk
Stat p = que.front(); //取出队头元素
for(int i=; i<=; ++i)
{
for(int j=; j<=; ++j)
{
ofs<<p.board[lists(i, j)]<<" ";
}
ofs<<endl;
}
ofs<<endl; que.pop(); //出队 if(ok(p.board))
{
return p.step; // 到达目标则返回最短步数
} for(int i=; i<=; ++i) // 这个是为了标记初始状态,不能遗漏
for(int j=; j<=; ++j)
{
m+=p.board[lists(i, j)]*mk;
mk*=;
}
if(!mark.count(m)) // 未标记则标记
mark[m] = true; for(int k=; k<; ++k) // 四个方向搜索
{
Stat n(p.board, p.step+); // n是下一步搜索的状态
int zx, zy; // zx,zy存放当前状态0的位置 for(int i=; i<=; ++i) // 搜索当前状态的0的位置
for(int j=; j<=; ++j)
{
if(p.board[lists(i,j)]==)
{
zx = i;
zy = j;
break;
}
if(p.board[lists(i,j)]==)
break;
} int nx = zx+dx[k]; //下一个状态的0的位置
int ny = zy+dy[k];
m = ; //标记状态
mk = ;
swap(n.board[lists(nx,ny)],n.board[lists(zx, zy)]); //交换 for(int i=; i<=; ++i)
for(int j=; j<=; ++j)
{
m+=n.board[lists(i, j)]*mk;
mk*=;
}
if(!mark.count(m))
{
mark[m] = true;
que.push(n); //若未搜索过,则入队
}
}
}
ofs.close(); //结束外存
return ;
}
return ;
} int main()
{
cout<<"广度搜索八数码问题:\n";
cout<<"请输入初始状态用0-8表示\n";
memset(board, , sizeof(board));
for(int i=; i<=; ++i)
for(int j=; j<=; ++j)
scanf("%1d", &board[lists(i, j)]); cout<<"请输入结束状态\n";
for(int m=;m<=;m++){scanf("%d",&destboard[m]);}
for(int m=;m<=;m++){scanf("%d",&destboard[m]);}
for(int m=;m<=;m++){scanf("%d",&destboard[m]);}
mark.clear(); cout<<"准备搜索...\n";
system("pause");
cout<<"搜索中.....\n"; int t=Bfs();
cout<<"搜索完毕,过程已经以文件的形式存储\n";
if(t==){cout<<"没有找到"<<endl;}
else{cout<<"深度为:"<<t<< endl;}
system("pause");
return ;
}

输入初始状态和最终状态,中间过程会生成在”output.dat”中。

八数码问题:C++广度搜索实现的更多相关文章

  1. HDU-1043 Eight八数码 搜索问题(bfs+hash 打表 IDA* 等)

    题目链接 https://vjudge.net/problem/HDU-1043 经典的八数码问题,学过算法的老哥都会拿它练搜索 题意: 给出每行一组的数据,每组数据代表3*3的八数码表,要求程序复原 ...

  2. HDU 1043 八数码(A*搜索)

    在学习八数码A*搜索问题的时候须要知道下面几个点: Hash:利用康托展开进行hash 康托展开主要就是依据一个序列求这个序列是第几大的序列. A*搜索:这里的启示函数就用两点之间的曼哈顿距离进行计算 ...

  3. [luogu]P1379 八数码难题[广度优先搜索]

    八数码难题 ——!x^n+y^n=z^n 我在此只说明此题的一种用BFS的方法,因为本人也是初学,勉勉强强写了一个单向的BFS,据说最快的是IDA*(然而蒟蒻我不会…) 各位如果想用IDA*的可以看看 ...

  4. codevs1225八数码难题(搜索·)

    1225 八数码难题  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题解       题目描述 Description Yours和zero在研究A*启 ...

  5. Poj 1077 eight(BFS+全序列Hash解八数码问题)

    一.题意 经典的八数码问题,有人说不做此题人生不完整,哈哈.给出一个含数字1~8和字母x的3 * 3矩阵,如: 1  2  X            3 4  6            7  5  8 ...

  6. A*算法 -- 八数码问题和传教士过河问题的代码实现

    前段时间人工智能的课介绍到A*算法,于是便去了解了一下,然后试着用这个算法去解决经典的八数码问题,一开始写用了挺久时间的,后来试着把算法的框架抽离出来,编写成一个通用的算法模板,这样子如果以后需要用到 ...

  7. ACM/ICPC 之 BFS-广搜进阶-八数码(经典)(POJ1077+HDU1043)

    八数码问题也称为九宫问题.(本想查查历史,结果发现居然没有词条= =,所谓的历史也就不了了之了) 在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同.棋盘上还有一个 ...

  8. BFS(八数码) POJ 1077 || HDOJ 1043 Eight

    题目传送门1 2 题意:从无序到有序移动的方案,即最后成1 2 3 4 5 6 7 8 0 分析:八数码经典问题.POJ是一次,HDOJ是多次.因为康托展开还不会,也写不了什么,HDOJ需要从最后的状 ...

  9. 双向广搜+hash+康托展开 codevs 1225 八数码难题

    codevs 1225 八数码难题  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond   题目描述 Description Yours和zero在研究A*启 ...

随机推荐

  1. RGB to HSI, HSI to RGB Conversion Calculator

    The RGB color model is an additive system in which each color is defined by the amount of red, green ...

  2. init.php 建立自己的前端共享文件

    文件位置:include/init.php 1.新建文件lib_xxx.php(lib_liangxin.php) 2.在文件init.php 第74行加入代码 require(ROOT_PATH . ...

  3. Zabbix 3.0 安装笔记

    Zabbix 3.0 只支持CentOS 7.0以上版本,所以先在虚拟机中安装好CentOS 7.0 x64,并设置好IP,允许虚拟机联网. 1.安装MySQL 从最新版本的linux系统开始,默认的 ...

  4. Python之路【番外篇】回顾&类的静态字段

    回顾 回顾:字符串.列表.字典的修改关于内存的情况 一.字符串 str1 = 'luotianshuai' str2 = str1 print id(str1) print id(str2) prin ...

  5. Yii2 数据操作Query Builder(转)

    Query Builder $rows = (new \yii\db\Query()) ->select(['dyn_id', 'dyn_name']) ->from('zs_dynast ...

  6. 数据库创建用户SQL

    ', default_database=TableName use TableName create user A for login A with default_schema=dbo exec s ...

  7. 用java实现zip压缩

    本来是写到spaces live上的,可是代码的显示效果确实不怎么好看.在javaeye上试了试代码显示的顺眼多了. 今天写了个用java压缩的功能,可以实现对文件和目录的压缩. 由于java.uti ...

  8. What is the most common software of data mining? (整理中)

    What is the most common software of data mining? 1 Orange? 2 Weka? 3 Apache mahout? 4 Rapidminer? 5 ...

  9. CF459A Pashmak and Garden (水

    Pashmak and Garden Codeforces Round #261 (Div. 2) A. Pashmak and Garden time limit per test 1 second ...

  10. 如何使用UltraCompare对比两个文件夹内容差异

    http://jingyan.baidu.com/article/cb5d6105e13599005c2fe0f8.html