• 软件测试技术
  • 软件测试博客
  • 软件测试视频
  • 开源软件测试技术
  • 软件测试论坛
  • 软件测试沙龙
  • 软件测试资料下载
  • 软件测试杂志
  • 软件测试人才招聘
    暂时没有公告

字号: | 推荐给好友 上一篇 | 下一篇

拼图游戏的算法

发布: 2007-7-01 20:40 | 作者: admin | 来源: | 查看: 33次 | 进入软件测试论坛讨论

领测软件测试网

相信大家都玩过"滑块拼图"游戏!
 大概说一下 :假如一副图是由几个部分拼凑成的,现在要你把这些散块拼凑成一副完整的图片
       也可以是几个数字来拼凑
 比如 3*3的格子
    1 2 3
    4 5 6
    7 8   (相当于原始矩阵)
有一个格子是空的现在要你组合成
   1 2 7
   3 6 4
   5 8     (目标矩阵)
问题是编写一种算法 能根据输入的原始图形(矩阵)拼凑成目标图形(目标矩阵) 要求是步数最少(耗时间最少)
 #include"iostream.h"
struct node{
int nodesun[4][4];

int x,y;
}path[1000];
int zx[4]={-1,0,1,0};
int zy[4]={0,-1,0,1};
int top;
int desti[4][4];//目标状态
int detect(struct node *p)
{int i,j;
 for(i=1;i<4;i++)
   for(j=1;j<4;j++)
  if(p->nodesun[i][j]!=desti[i][j])
  return 0;
 return 1;
}

void printlj()
{int tempt;
int i,j;
tempt=1;
while(tempt<=top)
{  for(i=1;i<4;i++)
   for(j=1;j<4;j++)
 {cout<<path[tempt].nodesun[i][j];
  if(j==3)
  cout<<" "<<endl;
 }
 tempt++;
}
}

 
 

void main()
{ //初始化
 int i,j,m,n,f;
 int temp,find=0;
 top=1;
for(i=1;i<4;i++)
   for(j=1;j<4;j++)
 {cout<<"请输入第"<<i<<"行"<<"第"<<j<<"列的值"<<endl;
  cin>>temp;
  path[1].nodesun[i][j]=temp;
 }
 cout<<"请输入初始状态的空格的位置(行)"<<endl;
 cin>>temp;
 path[1].x=temp;
cout<<"请输入初始状态的空格的位置(列)"<<endl;
 cin>>temp;
 path[1].y=temp;
//目标状态
for(i=1;i<4;i++)
   for(j=1;j<4;j++)
 {cout<<"请输入目标状态第"<<i<<"行"<<"第"<<j<<"列的值"<<endl;
  cin>>temp;
  desti[i][j]=temp;
 }
 //深度优先搜索
while(!find)
{ m=path[top].x;
 n=path[top].y ;
 for(f=0;f<4;f++)
 {i=m+zx[f];
  j=n+zy[f];
  if(i>=1&&i<=3&&j>=1&&j<=3)
  {top++;
  path[top]=path[top-1];
path[top].nodesun[m][n]=path[top-1].nodesun[i][j];
path[top].nodesun[i][j]=0;

path[top].x=i;
path[top].y=j;

  if(detect(&path[top]))
  {printlj();
  find=1;
  break;
  }

  break;
  }//if
 
 }//for
 
  }//while
}



#include"iostream.h"
struct node{
int nodesun[4][4];
int pre;
int x,y;
}path[400];
int zx[4]={-1,0,1,0};
int zy[4]={0,-1,0,1};
int front,rear;
int desti[4][4];//目标状态
int detect(struct node *p)
{int i,j;
 for(i=1;i<4;i++)
   for(j=1;j<4;j++)
  if(p->nodesun[i][j]!=desti[i][j])
  return 0;
 return 1;
}

void printlj()
{int tempt;
int i,j;
tempt=rear;
while(tempt!=0)
{  for(i=1;i<4;i++)
   for(j=1;j<4;j++)
 {cout<<path[tempt].nodesun[i][j];
  if(j==3)
  cout<<" "<<endl;
 }
 tempt=path[tempt].pre;
}
}

 
 

void main()
{ //初始化
 int i,j,m,n,f;
 int temp,find=0;
 front=rear=1;
 path[1].pre=0;
for(i=1;i<4;i++)
   for(j=1;j<4;j++)
 {cout<<"请输入第"<<i<<"行"<<"第"<<j<<"列的值"<<endl;
  cin>>temp;
  path[1].nodesun[i][j]=temp;
 }
 cout<<"请输入初始状态的空格的位置(行)"<<endl;
 cin>>temp;
 path[1].x=temp;
cout<<"请输入初始状态的空格的位置(列)"<<endl;
 cin>>temp;
 path[1].y=temp;
//目标状态
for(i=1;i<4;i++)
   for(j=1;j<4;j++)
 {cout<<"请输入目标状态第"<<i<<"行"<<"第"<<j<<"列的值"<<endl;
  cin>>temp;
  desti[i][j]=temp;
 }
 //广度优先搜索
while(front<=rear&&!find)
{ m=path[front].x;
 n=path[front].y ;
 for(f=0;f<4;f++)
 {i=m+zx[f];
  j=n+zy[f];
  if(i>=1&&i<=3&&j>=1&&j<=3)
  {rear++;
  path[rear]=path[front];
path[rear].nodesun[m][n]=path[front].nodesun[i][j];
path[rear].nodesun[i][j]=0;
path[rear].pre=front;
path[rear].x=i;
path[rear].y=j;
  if(detect(&path[rear]))
  {printlj();
  find=1;
  break;
  }
  }
 }
  front++;
  }
}

上面是用最简单的深度优先,广度优先直接搜索得来得,毫无AI可言,这并不说明我不能写出其更好得算法,这里最简单得的估价函数f(x)=g(x)+h(x)
g(x)用初始化的节点到当前的节点的路径长度来表示h(x)启发函数用当前状态和目标状态的位置不同的个数来表

延伸阅读

文章来源于领测软件测试网 https://www.ltesting.net/


关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备10010545号-5
技术支持和业务联系:info@testage.com.cn 电话:010-51297073

软件测试 | 领测国际ISTQBISTQB官网TMMiTMMi认证国际软件测试工程师认证领测软件测试网