#include<iostream> #include<vector> #include<string> #include<queue> using namespace std; int fac[] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880 };//康拖展开判重// 0!1!2!3! 4! 5! 6! 7! 8! 9! int moves[4][2] = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };//u,d,l,r char moveIndex[5] = "udlr";//正向搜索 int index[1000000] = {false}; typedef struct point { int s[9];//为什么不选择二维数组呢?1、数组规模已知,一维可以转化为二维 2、二维遍历比较麻烦 int number;//康托展开hash值 原因:1、映射到一个数字,方便比较 2、方便标记是否被访问过 int loc;//0的位置 int hx; int step; string path; void gethx(point aim) { hx = 0; for (int i = 0; i < 9; i++) { int x = i / 3, y = i % 3; for (int j = 0; j < 9; j++) { if (s[i] == aim.s[j]) { int aimx = j / 3, aimy = j % 3; hx = abs(aimx - x) + abs(aimy - y); } } } } void sToNumber()//结构体内已经定义的变量可直接引用。那么这结构体和类的区别有哪些。构造函数??? { number = 0;//在初始化是叠加了当然会导致错误智障! for (int i = 0; i < 9; i++) { int count = 0; for (int j = i + 1; j < 9; j++) if (s[j] < s[i]) count++; number += (fac[9 - i - 1] * count); } } }; struct cmp{//重载括号 bool operator()(point a, point b) { return (a.hx+a.step)>(b.hx+b.step); } }; bool dfs(point &in, point &aim,string &path) { priority_queue<point,vector<point>,cmp> p;//找最小,两种方式:1、最小堆 2、优先队列 //不能不写中间那项,默认参数的规则 in.gethx(aim); p.push(in); index[in.number] = true; while (!p.empty()){ cout << 1; point cur = p.top(); p.pop(); if (cur.number==aim.number){ path = cur.path; return true; } //没找到,准备交换入栈 int x = cur.loc / 3, y = cur.loc % 3; //cout << x << " " << y << endl; for (int i = 0; i < 4; i++){ int xtemp=x+(moves[i][0]); int ytemp=y+(moves[i][1]);//0的新位置 if (x<0 || x>2 || y<0 || y>2) continue; point next(cur); next.loc = xtemp * 3 + ytemp; //cout << next.loc; swap(next.s[next.loc], next.s[cur.loc]); //for (int i = 0; i < 9; i++) cout << next.s[i] << " "; next.sToNumber(); if (index[next.number] == true) continue; next.step++; next.path = cur.path + moveIndex[i]; next.gethx(aim); index[next.number] = true; if (next.number == aim.number) { cout << "最少步数为:" << next.step << endl; path = next.path; return true; } //cout << next.number << " " << aim.number << endl; p.push(next); } //system("pause"); } return false; } int main() { point in, aim; //cout << "请输入起始位置"; int temp1[9] = { 2,3,4,1,5,0,7,6,8 }; int temp2[9] = { 1,2,3,4,5,6,7,8,0 }; for (int i = 0; i < 9; i++){ in.s[i] = temp1[i]; if (in.s[i] == 0) in.loc = i; } in.step = 0; in.sToNumber(); for (int i = 0; i < 9; i++) { aim.s[i]=temp2[i]; } aim.sToNumber(); string path; if (dfs(in, aim, path)){ cout << path; } else cout << "失败了"; return 0; }
算法_八数码问题启发式搜索(C++)
猜你喜欢
转载自blog.csdn.net/m0_38034312/article/details/80527180
今日推荐
周排行