八数码问题 Eight Digital Problem
八数码问题
利用启发式搜索,找出以下问题的最优解。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int BLANK = 0;
const int R = 3;
const int C = 3;
pair<int, int> find_blank(const vector<vector<int>> &m) {
for (int r = 0; r < m.size(); r++) {
for (int c = 0; c < m[r].size(); c++) {
if (m[r][c] == BLANK) {
return make_pair(r, c);
}
}
}
return make_pair(-1, -1);
}
vector<pair<int, int>> address_derive(const pair<int, int> &father) {
vector<pair<int, int>> addresses;
const int r = father.first, c = father.second;
if (r - 1 >= 0) {
addresses.push_back(make_pair(r - 1, c));
}
if (r + 1 < R) {
addresses.push_back(make_pair(r + 1, c));
}
if (c - 1 >= 0) {
addresses.push_back(make_pair(r, c - 1));
}
if (c + 1 < C) {
addresses.push_back(make_pair(r, c + 1));
}
return addresses;
}
vector<vector<vector<int>>> matrix_derive(const vector<vector<int>> &father) {
vector<vector<vector<int>>> matrices;
pair<int, int> address = find_blank(father);
vector<pair<int, int>> addresses = address_derive(address);
for (const auto e : addresses) {
int r = e.first, c = e.second;
vector<vector<int>> son = father;
swap(son[address.first][address.second], son[r][c]);
matrices.push_back(son);
}
return matrices;
}
int evaluate(const vector<vector<int>> &m, const vector<vector<int>> &goal) {
int difference = 0;
for (int r = 0; r < goal.size(); r++) {
for (int c = 0; c < goal[r].size(); c++) {
if (goal[r][c] == BLANK) {
continue;
}
difference = m[r][c] != goal[r][c] ? difference + 1 : difference;
}
}
return difference;
}
struct Block {
int g;
int h;
vector<vector<int>> m;
Block(int g = 0, int h = 0, vector<vector<int>> m = vector<vector<int>>())
:g(g), h(h), m(m) {};
};
void print(const Block &b) {
for (const auto r : b.m) {
for (const auto c : r) {
cout << c << " ";
}
cout << endl;
}
cout << b.g << " " << b.h << endl;
cout << endl;
}
bool in_close(const vector<vector<vector<int>>> &close, const vector<vector<int>> &m) {
for (auto e : close) {
if (e == m) {
return true;
}
}
return false;
}
bool in_open(const vector<Block> &open, const vector<vector<int>> &m) {
for (auto e : open) {
if (e.m == m) {
return true;
}
}
return false;
}
void search(const vector<vector<int>> &begin, const vector<vector<int>> &goal) {
vector<Block> open;
vector<vector<vector<int>>> close;
open.push_back(Block(0, evaluate(begin, goal), begin));
int g = 0;
while (open.size()){
sort(open.begin(), open.end(), [](const Block &lhs, const Block &rhs) {
return (lhs.g + lhs.h) < (rhs.g + rhs.h);
});
Block cur = open.front();
open.erase(open.begin());
close.push_back(cur.m);
print(cur);
if (cur.m == goal) {
break;
}
vector<vector<vector<int>>> matrices = matrix_derive(cur.m);
for (auto e : matrices) {
if(!in_open(open, e)){
if (!in_close(close, e)) {
open.push_back(Block(cur.g+1, evaluate(e, goal), e));
}
}
}
}
}
int main() {
vector<vector<int>> begin = { {2,1,6},{4,0,8},{7,5,3} };
vector<vector<int>> goal = { {1,2,3}, {8,0,4}, {7,6,5} };
search(begin, goal);
return 0;
}
八数码问题 Eight Digital Problem的更多相关文章
- 八数码问题(8-Puzzle Problem)
八数码问题(8-Puzzle Problem) P1379 八数码难题 - 洛谷 题目概述:在 \(3 \times 3\) 的棋盘上摆放着 \(8\) 个棋子,棋子的编号分别为 \(1\) 到 \( ...
- hdu 1043 Eight 经典八数码问题
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 The 15-puzzle has been around for over 100 years ...
- poj 1077-Eight(八数码+逆向bfs打表)
The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've see ...
- HDU 1043 Eight (BFS·八数码·康托展开)
题意 输出八数码问题从给定状态到12345678x的路径 用康托展开将排列相应为整数 即这个排列在全部排列中的字典序 然后就是基础的BFS了 #include <bits/stdc++.h ...
- HDU 3567 Eight II(八数码 II)
HDU 3567 Eight II(八数码 II) /65536 K (Java/Others) Problem Description - 题目描述 Eight-puzzle, which is ...
- HDU 1043 Eight(八数码)
HDU 1043 Eight(八数码) 00 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Problem Descr ...
- Eight(经典题,八数码)
Eight Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- Codeforces 645A Amity Assessment【八数码】
题目链接: http://codeforces.com/problemset/problem/645/A 题意: 2*2的八数码问题 分析: 这题n为2,不需要搜索,直接判断字母排列顺序就好了. 注意 ...
- HDU-1043 Eight八数码 搜索问题(bfs+hash 打表 IDA* 等)
题目链接 https://vjudge.net/problem/HDU-1043 经典的八数码问题,学过算法的老哥都会拿它练搜索 题意: 给出每行一组的数据,每组数据代表3*3的八数码表,要求程序复原 ...
随机推荐
- 如何打印一棵树(Java)
1.有一棵多叉树,将它打印出来. import java.util.LinkedList; /** * 需求:按层打印一棵树 * 说明:树是保存在一个链表中 * created by wangjunf ...
- SpringMVC项目模块浅析
本文为个人笔记,对于springmvc模块的规划,仁者见仁.智者见智,请不要生搬硬套. 一.基础模块-basic 主要内容是dao.spring-xml.domain.service等内容,模块内分层 ...
- Github Issues
快捷键r
- vector erase的错误用法
直接写 a.erase(it)是错误的,一定要写成it=a.erase(it)这个错误编译器不会报错.而且循环遍历删除的时候,删除了一个元素,容器里会自动向前移动,删除一个元素要紧接着it--来保持位 ...
- django 【form表单】
#########################根据类来生成表单################# ''' django form类 通模型类的属性映射到数据库的字段一样,表单类的字段会映射到HTM ...
- 解析img图片没找到onerror事件
本篇文章主要介绍了img图片没找到onerror事件 Stack overflow at line: 0 需要的朋友可以过来参考下,希望对大家有所帮助 打开网页时提示 Stack overflow a ...
- js原型链的说明
首先需要明确的是:只有对象有__proto__属性,而函数只有prototype属性,没有__proto__属性,函数的原型有一个constructor属性,指向的是函数本身! Function是Ob ...
- [博客迁移]探索Windows Azure 监控和自动伸缩系列3 - 启用Azure监控扩展收集自定义监控数据
上一篇我们介绍了获取Azure的监控指标和监控数据: http://www.cnblogs.com/teld/p/5113376.html 本篇我们继续:监控虚拟机的自定义性能计数器. 随着我们应用规 ...
- Web处理方式
ProcessRequest 方法简称 PR方法 PR方法内部调用Page_Load方法 MVC设计模式 Model是指要处理的业务代码和数据操作代码 View视图主要是指的跟用户打交道并能够展示 ...
- STL容器之map
[1]map容器 map 是关联容器.容器中的每一个元素都是由一个键值和一个数据值组成的. set 是一个集合它以其元素作为键值(同一个键值只能出现一次),且默认以升序排列. list 是一个顺序容器 ...