九宫问题(八数码)求解过程动态演示

2016-01-29 12:15 138 1 收藏

九宫问题(八数码)求解过程动态演示,九宫问题(八数码)求解过程动态演示

【 tulaoshi.com - C语言心得技巧 】

九宫问题(八数码)求解过程动态演示

作者:赵宏伟

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com) 下载源代码

一、题目说明:
  
(九宫问题)在一个3×3的九宫中有1-8这8个数及一个空格随机的摆放在其中的格子里,如图1-1所示。现在要求实现这个问题:将该九宫格调整为如图1-1右图所示的形式。调整的规则是:每次只能将与空格(上、下、或左、右)相邻的一个数字平移到空格中。试编程实现这一问题的求解。

(图1-1)

二、题目分析:

  
九宫问题是人工智能中的经典难题之一,问题是在3×3方格棋盘中,放8格数,剩下的没有放到的为空,每次移动只能是和相邻的空格交换数。程序自动产生问题的初始状态,通过一系列交换动作将其转换成目标排列(如下图1-2到图1-3的转换)。
  (图1-2) (图1-3)

  九宫问题中,程序产生的随机排列转换成目标共有两种可能,而且这两种不可能同时成立,也就是奇数排列和偶数排列。我们可以把一个随机排列的数组从左到右从上到下用一个一维数组表示,如上图1-2我们就可以表示成{8,7,1,5,2,6,3,4,0}其中0代表空格。
在这个数组中我们首先计算它能够重排列出来的结果,公式就是:

∑(F(X))=Y,其中F(X)

  就是一个数他前面比这个数小的数的个数,Y为奇数和偶数个有一种解法。那么上面的数组我们就可以解出它的结果。

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com)
F(8)=0;F(7)=0;F(1)=0;F(5)=1;F(2)=1;F(6)=3;F(3)=2;F(4)=3;Y=0+0+0+1+1+3+2+3=10

  Y=10是偶数,所以他的重排列就是如图1-3的结果,如果加起来的结果是奇数重排的结果就是如图1-1最右边的排法。

三、算法分析

  
九宫问题的求解方法就是交换空格(0)位置,直至到达目标位置为止。图形表示就是:

(图3-1)

  要想得到最优的就需要使用广度优先搜索,九宫的所以排列有9!种,也就是362880种排法,数据量是非常大的,我使用的广度搜索,需要记住每一个结点的排列形式,要是用数组记录的话会占用很多的内存,我们把数据进行适当的压缩。使用DWORD形式保存,压缩形式是每个数字用3位表示,这样就是3×9=27个字节,由于8的二进制表示形式1000,不能用3位表示,我使用了一个小技巧就是将8表示位000,然后用多出来的5个字表示8所在的位置,就可以用DWORD表示了。用移位和或操作将数据逐个移入,比乘法速度要快点。定义了几个结果来存储遍历到了结果和搜索完成后保存最优路径。
类结构如下:

class CNineGird{public:struct PlaceList    {DWORDPlace;PlaceList*Left;PlaceList*Right;    };struct Scanbuf{DWORD Place;int ScanID;};struct PathList{unsigned char Path[9];};private:PlaceList *m_pPlaceList;Scanbuf *m_pScanbuf;RECT m_rResetButton;RECT m_rAutoButton;public:int m_iPathsize;clock_t m_iTime;UINT m_iStepCount;unsigned char m_iTargetChess[9];unsigned char m_iChess[9];HWND m_hClientWin;PathList *m_pPathList;bool m_bAutoRun;private:inline bool AddTree(DWORD place , PlaceList*& parent);void FreeTree(PlaceList*& parent);inline void ArrayToDword(unsigned char *array , DWORD & data);inline void DwordToArray(DWORD data , unsigned char *array);inline bool MoveChess(unsigned char *array , int way);bool EstimateUncoil(unsigned char *array);void GetPath(UINT depth);public:void MoveChess(int way);bool ComputeFeel();void ActiveShaw(HWND hView);void DrawGird(HDC hDC , RECT clientrect);
                        

来源:http://www.tulaoshi.com/n/20160129/1485300.html

延伸阅读
标签: 分娩
在妊娠期间,子宫虽然日益膨大,但子宫平滑肌的收缩一直很弱,基本上处于平静状态,因而并不引起孕妇的感觉。到了 分娩 前几天,子宫收缩才逐渐加强。下面,小编对分娩过程进行大揭秘。 一、分娩的机制 对动物的研究已经积累了分娩最初发动机制的证据,认为胎儿的存在乃是引起分娩的关键性因素;但这种设想是否能适用于人类,还有待进一步...
标签: PS PS基础
一提到皮肤修润,人们马上就会想到时尚杂志上那些皮肤完美无暇的明星和模特。这些照片并不追求人物皮肤的真实效果,而是通过后期细致的处理和修饰,使皮肤质感达到一种非常理想化的动人效果。 在修饰这类照片时,需要细致与耐心,有时要对逐个毛孔或者逐个像素进行处理,以达到一种完美无暇的效果,即使制作成大幅海报招贴,图片中的肌肤也看...
--删除 drop procedure if exists up_common_select --创建 CREATE PROCEDURE `up_common_select` ( in t_name varchar(50) ) begin declare v_sql varchar(500); set v_sql= concat('select * from ',t_name); select v_sql; --注意:prepare...
PS教你打造流畅酷炫的动态演示     静态设计 步骤1 新建画布 (图老师整理) 步骤2 视图新建参考线,垂直,间隔15px,左面4条,右面4条 视图新建参考线,水平,在40px,128px,220px处设置水平参考线。 完成后效果如下图。 步骤 3 在画布上添加状态栏(也就是第一条水平参...
一开始用phpMyAdmin来执行,后来出现一堆错误,后来去掉了begin,end之后可以正常执行,但要执行存储过程,在phpMyAdmn中不行,而在mysql命令行文本框中就可以。 接下来又遇到更难的问题,在存储过程中加入预处理语句,更不行了,在mysql命令行文本框下执行同样,下面的运行记录,给大家参考,能否有高手来帮助。 代码如下: mysql CREATE PRO...

经验教程

439

收藏

66
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部