人工智能实验报告

时间:2024.4.30

昆明理工大学信息工程与自动化学院学生上机实验报告

2012 2013 学年第 1 学期 )

课程名称:人工智能导论 实验地点:20##年 11月 13 日

一、 实验问题

八数码问题:在3×3的方格棋盘上,摆放着1到8这八个数码,有1个方格是空的,其初始状态如图1所示,要求对空格执行空格左移、空格右移、空格上移和空格下移这四个操作使得棋盘从初始状态到目标状态。

初始状态:                                目标状态:

请任选一种盲目搜索算法(深度优先搜索或宽度优先搜索)或 任选一种启发式搜索方法(A 算法或 A* 算法)编程求解八数码问题(初始状态任选),并对实验结果进行分析,得出结论。

二、实验目的

1. 熟悉人工智能系统中的问题求解过程;

2. 熟悉状态空间的盲目搜索和启发式搜索算法的应用;

3. 熟悉对八数码问题的建模、求解及编程语言的应用。

三、实验原理

   常用的状态空间搜索有深度优先和广度优先。广度优先是从初始状态一层一层向下找,直到找到目标为止。深度优先是按照一定的顺序前查找完一个分支,再查找另一个分支,以至找到目标为止。 广度和深度优先搜索有一个很大的缺陷就是他们都是在一个给定的状态空间中穷举。这在状态空间不大的情况下是很合适的算法,可是当状态空间十分大,且不预测的情况下就不可取了。他的效率实在太低,甚至不可完成。由于八数码问题状态空间共有9!个状态,对于八数码问题如果选定了初始状态和目标状态,有9!/2个状态要搜索,考虑到时间和空间的限制,在这里采用A*算法作为搜索策略。在这里就要用到启发式搜索
  启发式搜索就是在状态空间中的搜索对每一个搜索的位置进行评估,得到最好的位置,再从这个位置进行搜索直到目标。这样可以省略大量无畏的搜索路径,提到了效率。在启发式搜索中,对位置的估价是十分重要的。采用了不同的估价可以有不同的效果。

    启发中的估价是用估价函数表示的,如:f(n) = g(n) + h(n)
  其中f(n) 是节点n的估价函数,g(n)是在状态空间中从初始节点到n节点的实际代价,h(n)是从n到目标节点最佳路径的估计代价。 在此八数码问题中,显然g(n)就是从初始状态变换到当前状态所移动的步数,估计函数f(n)我们就可采用当前状态各个数字牌不在目标状态未知的个数,即错位数。

四、程序框图

算法流程如下:

 

五、实验结果及分析

{1,2,3,8,0,5,7,4,6}

 

                      A(4)

 

   B(3)               C(5)               D(5)                      

 

E(2)               F(4)           G(4)                

 

H(0)

 

六、结论

A*算法中,限制h(x)<=h*(x)的原因是是为了保证取得最优解。通过分析证明,如果问题存在最优解,则这样的限制就可保证能找到最优解。虽然这个限制可能产生无用搜索。实际上,当某一节点x的h(x)>h*(x),则该节点就可能失去优先扩展的机会,因而导致得不到最优解。八数码问题是一个很难求解的问题,因为他需要用到复杂的C++程序编程知识,而自己在这个环节的运用上总体来说相对薄弱,所以开始时感觉很迷茫,无从下手,但是后来经过对所学知识的回顾和复习,对此问题终于找到了出口。这次实验让我深刻意识到学习C++程序编程的重要性,如果学好了这门课程,那么在以后的学习中将会轻松很多,同时让我找到了自身存在的不足,朝着这个方向努力的改善和提高自己。

七、源程序及注释

#include "Stdio.h"

#include "Conio.h"

#include "stdlib.h"

#include "math.h"

void Copy_node(struct node *p1,struct node *p2);

void Calculate_f(int deepth,struct node *p);

void Add_to_open(struct node *p);

void Add_to_closed(struct node *p);

void Remove_p(struct node *name,struct node *p);

int Test_A_B(struct node *p1,struct node *p2);

struct node * Solution_Astar(struct node *p);

void Expand_n(struct node *p);

struct node * Search_A(struct node *name,struct node *temp);

void Print_result(struct node *p);

typedef struct node

{

  int s[3][3];

  int i_0;  

  int j_0;  

  int f;   

  int d;    

  int h;   

  struct node *father;

  struct node *next; 

};

struct node s_0={{1,3,4,8,0,2,7,6,5},1,1,0,0,0,NULL,NULL};

struct node s_g={{1,2,3,8,0,4,7,6,5},1,1,0,0,0,NULL,NULL};

struct node *open=NULL;                            

struct node *closed=NULL;                           

int sum_node=0;                                    

int main(void)

{

  struct node s,*target;

  Copy_node(&s_0,&s);

  Calculate_f(0,&s);          

  target=Solution_Astar(&s);   

  if(target) Print_result(target);  

  else printf("问题求解失败!");

  getch();

  return 0;

}

struct node * Solution_Astar(struct node *p)

{

  struct node *n,*temp;

  Add_to_open(p);    

  while(open!=NULL)

    {

      n=open;            

      temp=open->next;

         Add_to_closed(n);

      open=temp;

      if(Test_A_B(n,&s_g)) 

          return n;     

      Expand_n(n);       

    }

  return NULL;

}

void Expand_n(struct node *p)

{

  struct node *temp,*same;

  if(p->j_0>=1) 

       {

      temp=p->father;

      if(temp!=NULL&&temp->i_0==p->i_0&&temp->j_0-1==p->j_0) 

                ;

         else

              {             

          temp=(struct node *)malloc(sizeof(struct node)); 

          Copy_node(p,temp); 

          temp->s[temp->i_0][temp->j_0]=temp->s[temp->i_0][temp->j_0-1]; 

          temp->s[temp->i_0][temp->j_0-1]=0;

          temp->j_0--;

          temp->d++;

          Calculate_f(temp->d,temp);      

          temp->father=p;                         

                if(same=Search_A(closed,temp))  

                     {

                       if(temp->f<same->f) 

                            {

                              Remove_p(closed,same); 

                              Add_to_open(temp);

                              sum_node++;

                            }

                       else;

                     }

                else if(same=Search_A(open,temp)) 

                     {

                       if(temp->f<same->f) 

                            {

                              Remove_p(open,same); 

                              Add_to_open(temp);

                              sum_node++;

                            }

                       else ;

                     }

                else 

                     {

                       Add_to_open(temp);

                    sum_node++;

                     }                    

              }

       }

  if(p->j_0<=1) 

       {

         temp=p->father;

         if(temp!=NULL&&temp->i_0==p->i_0&&temp->j_0+1==p->j_0) 

                ;

         else 

              {             

                temp=(struct node *)malloc(sizeof(struct node)); 

                Copy_node(p,temp); 

                temp->s[temp->i_0][temp->j_0]=temp->s[temp->i_0][temp->j_0+1]; 

                temp->s[temp->i_0][temp->j_0+1]=0;

                temp->j_0++;

                temp->d++;

                Calculate_f(temp->d,temp);      

                temp->father=p;                

                if(same=Search_A(closed,temp))  

                     {

                       if(temp->f<same->f) 

                            {

                              Remove_p(closed,same); 

                              Add_to_open(temp);

                              sum_node++;

                            }

                       else;

                     }

                else if(same=Search_A(open,temp)) 

                     {

                       if(temp->f<same->f)  

                            {

                              Remove_p(open,same); 

                              Add_to_open(temp);

                              sum_node++;

                            }

                       else ;

                     }

                else 

                     {

                       Add_to_open(temp);

                    sum_node++;

                     }

              }

       }

  if(p->i_0>=1) 

       {

         temp=p->father;

         if(temp!=NULL&&temp->i_0==p->i_0-1&&temp->j_0==p->j_0) 

                ;

         else 

              {             

                temp=(struct node *)malloc(sizeof(struct node)); 

                Copy_node(p,temp); 

                temp->s[temp->i_0][temp->j_0]=temp->s[temp->i_0-1][temp->j_0]; 

                temp->s[temp->i_0-1][temp->j_0]=0;

                temp->i_0--;

                temp->d++;

                Calculate_f(temp->d,temp);      

                temp->father=p;               

                if(same=Search_A(closed,temp))  

                     {

                       if(temp->f<same->f) 

                            {

                              Remove_p(closed,same); 

                              Add_to_open(temp);

                              sum_node++;

                            }

                       else;

                     }

                else if(same=Search_A(open,temp)) 

                     {

                       if(temp->f<same->f) 

                            {

                              Remove_p(open,same); 

                              Add_to_open(temp);

                              sum_node++;

                            }

                       else ;

                     }

                else 

                     {

                       Add_to_open(temp);

                    sum_node++;

                     }

              }

       }

  if(p->i_0<=1) 

       {

         temp=p->father;

         if(temp!=NULL&&temp->i_0==p->i_0+1&&temp->j_0==p->j_0) 

                ;

         else

              {             

                temp=(struct node *)malloc(sizeof(struct node)); 

                Copy_node(p,temp); 

                temp->s[temp->i_0][temp->j_0]=temp->s[temp->i_0+1][temp->j_0];  

                temp->s[temp->i_0+1][temp->j_0]=0;

                temp->i_0++;

                temp->d++;

                Calculate_f(temp->d,temp);      

                temp->father=p;               

                if(same=Search_A(closed,temp))  

                     {

                       if(temp->f<same->f) 

                            {

                              Remove_p(closed,same); 

                              Add_to_open(temp);

                              sum_node++;

                            }

                       else;

                     }

                else if(same=Search_A(open,temp)) 

                     {

                       if(temp->f<same->f) 

                            {

                              Remove_p(open,same); 

                              Add_to_open(temp);

                              sum_node++;

                            }

                       else ;

                     }

                else 

                     {

                       Add_to_open(temp);

                    sum_node++;

                     }                    

              }

       }

}

void Add_to_open(struct node *p)

{

  struct node *p1,*p2;

  p1=open;             

  p2=NULL;

  if(open==NULL)       

    {

      p->next=NULL;

      open=p;

    }

  else                  

    {

      while(p1!=NULL&&p->f>p1->f)

           {

          p2=p1;        

          p1=p1->next;

           }

      if(p2==NULL)    

           {

          p->next=open;

          open=p;

           }

      else if(p1==NULL) 

           {

          p->next=NULL;

          p2->next=p;

           }

      else             

           {

          p2->next=p;

          p->next=p1;

           }

    }

}

void Add_to_closed(struct node *p)

{

  if(closed==NULL)   

    {

      p->next=NULL;

      closed=p;

    }

  else                

    {

      p->next=closed;

      closed=p;

    }

}

struct node * Search_A(struct node *name,struct node *temp)

{

  struct node *p1;

  p1=name;                 

  while(p1!=NULL)

    {

      if(Test_A_B(p1,temp))  

          return p1;

      else

          p1=p1->next;

    }

  return NULL;

}

int Test_A_B(struct node *p1,struct node *p2)

{

  int i,j,flag;

  flag=1;

  for(i=0;i<=2;i++)

      for(j=0;j<=2;j++)

        {

          if((p2->s[i][j])!=(p1->s[i][j])) { flag=0; return flag; }

          else ;

        }

  return flag;

}

void Remove_p(struct node *name,struct node *p)

{

  struct node *p1,*p2;

  p1=NULL;

  p2=NULL;

  if(name==NULL)                          

     return;

  else if(Test_A_B(name,p)&&name->f==p->f)   

     {

       open=name->next;

       name->next=NULL;

       return;

     }

  else

     {

       p2=name;

       p1=p2->next;

       while(p1)

          {

            if(Test_A_B(p1,p)&&p1->f==p->f)  

                   {

                  p2->next=p1->next;

                  return;

                }

             else

                   {

                  p2=p1;                    

                  p1=p1->next;

                }

          }

       return;

     }

}

void Calculate_f(int deepth,struct node *p)

{

  int i,j,temp;

  temp=0; 

  for(i=0;i<=2;i++)    

    {

      for(j=0;j<=2;j++)

        {

          switch(p->s[i][j])

            {

              case 0: temp+=abs(i-1)+abs(j-1); break;

              case 1: temp+=abs(i-0)+abs(j-0); break;

              case 2: temp+=abs(i-0)+abs(j-1); break;

              case 3: temp+=abs(i-0)+abs(j-2); break;

              case 4: temp+=abs(i-1)+abs(j-2); break;

              case 5: temp+=abs(i-2)+abs(j-2); break;

              case 6: temp+=abs(i-2)+abs(j-1); break;

              case 7: temp+=abs(i-2)+abs(j-0); break;

              case 8: temp+=abs(i-1)+abs(j-0); break;

            }

        }

    }

  p->h=temp;

  p->f=deepth+p->h;

}

void Copy_node(struct node *p1,struct node *p2)

{

  int i,j;

  for(i=0;i<=2;i++)

    {

      for(j=0;j<=2;j++)

        { p2->s[i][j]=p1->s[i][j]; }

    }

  p2->i_0=p1->i_0;

  p2->j_0=p1->j_0;

  p2->f=p1->f;

  p2->d=p1->d;

  p2->h=p1->h;

  p2->next=p1->next;

  p2->father=p1->father;

}

void Print_result(struct node *p)

{

  struct node *path[100];

  struct node *temp,*temp_father;

  int i,j,k;

  for(i=0;i<=99;i++)                 

      path[i]=0;

  temp=p;

  printf("总共扩展 %d 个节点\n",sum_node);

  printf("总共扩展 %d 层\n",temp->d);

  printf("*************************************************\n");

  printf("解路径如下:\n");

  for(i=p->d;i>=0;i--)                 

    {

      path[i]=temp;

      temp=temp->father;

    }

  for(k=0;k<=p->d;k++)              

    {

      temp=path[k];                 

      printf("第%d步 ",temp->d);

         if(k-1>=0)                   

              {

               temp_father=path[k-1];

             if(temp->i_0<temp_father->i_0) printf("->上移\n");

             if(temp->i_0>temp_father->i_0) printf("->下移\n");

             if(temp->j_0<temp_father->j_0) printf("->左移\n");

             if(temp->j_0>temp_father->j_0) printf("->右移\n");

              }

         else

                printf("\n");

         printf("当前:f=%d,d=%d,h=%d\n",temp->f,temp->d,temp->h);

      printf("当前节点状态为:\n");

      for(i=0;i<=2;i++)

        {

          for(j=0;j<=2;j++)

            {

              printf("%d  ",temp->s[i][j]);

            }

          printf("\n");

        }      

      printf("\n");

    }

}

更多相关推荐:
人工智能实验报告

人工智能九宫格重移搜索成员赵春杰20xx210665羊森20xx210653黄鑫20xx210周成兵20xx210664王素娟20xx2106441问题描述八数码问题也称为九宫问题在33的棋盘摆有八个棋子每个棋...

人工智能试验报告汇总

人工智能课程实验指导书实验内容实验一产生式系统实验实验二移动机器人的路径规划与行为决策实验实验三梵塔问题实验实验四A算法实验实验五化为子句集的九步法实验实验六子句消解实验实验七模糊假言推理器实验实验八BP网络实...

人工智能实验报告

华北电力大学实验报告实验名称课程名称人工智能及应用专业班级学生姓名号成绩指导教师李继荣实验日期20xx5学华北电力大学实验报告华北电力大学实验报告华北电力大学实验报告华北电力大学实验报告华北电力大学实验报告华北...

人工智能实验报告

人工智能第二次实验报告一实验题目遗传算法的设计与实现二实验目的通过人工智能课程的学习熟悉遗传算法的简单应用三实验内容用遗传算法求解fxx2的最大值x031x取整数可以看出该函数比较简单只要是为了体现遗传算法的思...

人工智能实验报告

人工智能技术实验报告实验名称人工智能实验1姓名班级指导教师完成时间20xx04301读程序指出运行结果domainsssymbolpredicatespsp1sp2sp3sp4sp5ssp11sp12sp31s...

人工智能实验报告

西南大学实验报告人工智能院系计算机与信息科学学院专业学号姓名指导老师

中南大学人工智能实验报告

人工智能实验报告专业自动化班级09级学号姓名日期20xx12人工智能实验报告目录一实验八自动规划实验群3二实验一生产式系统实验群6三实验二搜索策略实验群7四实验七神经网络9五实验心得和体会102人工智能实验报告...

人工智能实验报告

人工智能实验报告题目基于web动物识别系统院系计算机科学与技术系专业计算机科学与技术专业学号071221139学生姓名张莲舟日期20xx421一实验题目基于web的动物识别系统二实验目的理解和掌握产生式知识表示...

人工智能实验报告计算机

实验二九宫重排一实验目的A算法是人工智能领域最重要的启发式搜索算法之一本实验通过九宫重排问题强化学生对A算法的理解与应用为人工智能后续环节的课程奠定基础二问题描述给定九宫格的初始状态要求在有限步的操作内使其转化...

中南大学人工智能实验报告

人工智能实验报告老师黄芳班级计科1001学号0909090430姓名赵鼎平日期20xx117目录一神经网络实验群4二生产式系统实验群5三搜索策略实验群6四自动规划实验群8五实验心得和体会11神经网络实验群生产式...

人工智能实验报告 八数码问题

实验一启发式搜索算法姓名徐维坚学号2220xx3484日期20xx629一实验目的熟练掌握启发式搜索A算法及其可采纳性二实验内容使用启发式搜索算法求解8数码问题1编制程序实现求解8数码问题A算法采用估价函数wn...

MIT人工智能实验室:如何做研究

人工智能实验室AIWorkingPaper31619xx年10月来自MIT人工智能实验室如何做研究作者人工智能实验室全体研究生编辑DavidChapman版本13时间19xx年9月译者柳泉波北京师范大学信息学院...

人工智能实验报告(49篇)