人工智能导论(2)——启发式算法(八数码问题)
来源:互联网 发布:松江报警主机怎样编程 编辑:程序博客网 时间:2024/06/07 07:02
实验要求
用A*算法来解决八数码问题。
代码实现
#include<iostream>#include<stdio.h>#include<cmath> using namespace std;int open_cnt=0; int open_node_cnt;//open表节点个数 int close_cnt=0;int noresoult=0;struct Node{ int a[3][3]; int x,y; int f,g,h; int flag; //上一次移动方向 Node *father;}start,end;struct Open_Close{ int f; Node *np;}open[10000],close[10000];bool isable(){//判断是否有解,逆序数之和奇偶性相同,有解 int s[9],e[9]; int tf=0,ef=0; int k=0; for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ s[k]=start.a[i][j]; e[k]=end.a[i][j]; k++; } } for(int i=0;i<9;i++){ for(int j=0;j<i;j++){ if(s[i]>s[j]&&s[j]!=0) tf+=1; if(e[i]>e[j]&&e[j]!=0) ef+=1; } } if((tf%2==1&&ef%2==1)||(tf%2==0&&ef%2==0)) return true; else return false;}int a_start_h(Node *node){ //求 h() int old_x,old_y,end_x,end_y; int h=0; for(int k=1;k<9;k++){ for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ if(node->a[i][j]==k){ old_x=i; old_y=j; } if(end.a[i][j]==k){ end_x=i; end_y=j; } } } h+=abs(old_x-end_x)+abs(old_y-end_y); } return h;}void input(){ //输入 for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ cin>>start.a[i][j]; if(start.a[i][j]==0){ start.x=i; start.y=j; } } } for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ cin>>end.a[i][j]; if(end.a[i][j]==0){ end.x=i; end.y=j; } } } start.g=0; start.h=a_start_h(&start); start.f=start.g+start.h;}int show(Node *node){ //显示 Node *p=node; if(p==&start) return 1; else show(p->father); cout<<"==============\n"; for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ cout<<p->a[i][j]<<" "; } printf("\n"); } cout<<"==============\n\n";}bool isend(Node *node){ //判断是否为目标节点 for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ if(node->a[i][j]!=end.a[i][j]) return false; } } return true;} void sort(Open_Close *open){ //open表排序 int min=99999,min_flag=0; Open_Close temp; for(int i=0;i<=open_cnt;i++){ if(min>open[i].f&&open[i].f>0){ min=open[i].f; min_flag=i; } } temp=open[min_flag]; open[min_flag]=open[0]; open[0]=temp; }void move(int flag,Node *node){ //向四个方向扩展 int temp; if(flag==1&&node->x>0){ Node *n = new Node(); for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ n->a[i][j]=node->a[i][j]; } } n->a[node->x][node->y]=node->a[node->x-1][node->y]; n->a[node->x-1][node->y]=0; n->x=node->x-1; n->y=node->y; n->flag=3; n->father=node; n->g=node->g+1; // 求 g() n->h=a_start_h(n); n->f=n->g+n->h; open_cnt++; open_node_cnt++; open[open_cnt].np=n; //添加到open表 open[open_cnt].f=n->f; // 求 f() } else if(flag==2&&node->y<2){ Node *n = new Node(); for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ n->a[i][j]=node->a[i][j]; } } n->a[node->x][node->y]=node->a[node->x][node->y+1]; n->a[node->x][node->y+1]=0; n->x=node->x; n->y=node->y+1; n->flag=4; n->father=node; n->g=node->g+1; // 求 g() n->h=a_start_h(n); n->f=n->g+n->h; open_cnt++; open_node_cnt++; open[open_cnt].np=n; //添加到open表 open[open_cnt].f=n->f; // 求 f() } else if(flag==3&&node->x<2){ Node *n = new Node(); for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ n->a[i][j]=node->a[i][j]; } } n->a[node->x][node->y]=node->a[node->x+1][node->y]; n->a[node->x+1][node->y]=0; n->x=node->x+1; n->y=node->y; n->flag=1; n->father=node; n->g=node->g+1; // 求 g() n->h=a_start_h(n); n->f=n->g+n->h; open_cnt++; open_node_cnt++; open[open_cnt].np=n; //添加到open表 open[open_cnt].f=n->f; // 求 f() } else if(flag==4&&node->y>0){ Node *n = new Node(); for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ n->a[i][j]=node->a[i][j]; } } n->a[node->x][node->y]=node->a[node->x][node->y-1]; n->a[node->x][node->y-1]=0; n->x=node->x; n->y=node->y-1; n->flag=2; n->father=node; n->g=node->g+1; // 求 g() n->h=a_start_h(n); n->f=n->g+n->h; open_cnt++; open_node_cnt++; open[open_cnt].np=n; //添加到open表 open[open_cnt].f=n->f; // 求 f() } } void expand(Node *node){ //节点扩展 for(int i=1;i<5;i++){ if(i!=node->flag) move(i,node); }}int main(){ input(); open[0].np=&start;//start放入open表 open_node_cnt=1; if(isable()){ while(true){//open表不为空 if(isend(open[0].np)){ cout<<"\n路径:\n"; show(open[0].np); break; } expand(open[0].np);//扩展最优节点的子节点 open[0].np=NULL; open[0].f=-1; open_node_cnt--; sort(open); //open表排序 } } else cout<<"无解";} /*有解1 0 37 2 46 8 51 2 38 0 47 6 5无解1 2 3 4 0 7 6 5 83 2 1 6 5 0 4 7 8*/
阅读全文
0 0
- 人工智能导论(2)——启发式算法(八数码问题)
- 八数码游戏分析—启发式搜索算法(2)
- 人工智能算法八数码之启发式搜索算法(A*)+扩展15数码算法的实现
- 启发式搜索算法求解八数码问题(C)
- 八数码问题-启发式搜索(A*算法)
- 八数码游戏(启发式搜索A*算法)
- 八数码问题高效算法(人工智能实验)
- 八数码问题(启发式搜索)
- 【启发式搜索】八数码问题
- [人工智能]八数码问题
- 人工智能-八数码问题
- 启发式搜索-A*算法解决八数码问题
- HDU 1043 Eight 八数码问题 A*搜索 启发式算法
- 八数码游戏分析+源码——启发式搜索(一)
- 八数码游戏分析+源码——启发式搜索(二)
- 八数码问题: 八数码的游戏 九宫格里面放入8个数字 启发式搜索(1)
- 人工智能实验-八数码问题
- 人工智能之八数码问题
- 【干货#010】解决 Page[pages/XXX/XXX] not found错误
- 模板方法模式
- 概率论_随机变量及其分布1
- Oracle PL/SQL DBA 编程实践基础
- Android报错总结
- 人工智能导论(2)——启发式算法(八数码问题)
- SQL 单列转多列
- CRASH fd leak
- python内置函数getattr(),hasattr(),setattr(),delattr()【属性相关】
- ubuntuKylin17.04重装KDE
- 根据进度算颜色值
- sqlserver中用游标,拼接sql,批量修改数据库字段类型
- Java关于md5+salt盐加密验证
- 《maven实战》学习笔记7——maven项目版本管理和灵活构建