摘要:本部分的程序代码下载:http://www2.cnblogs.com/Files/zhenyulu/HRD_64_HashTable_1.rar 在修改了那么多代码后需要再重新审视一下现在的程序,其实现在的程序代码已经显得很不协调,因为在修改的大量的数据结构后,算法也应当尽量贴近新的数据结构。所以我重新设计了新的布局表示以及棋子的算法。 在原有的华容道程序中,我使用了大量的Position结构来表...
阅读全文
文章分类 - 华容道与数据结构
摘要:在这部分内容里,我们用HashTable取代AVLTree以进一步提高系统的检索效率。毕竟我们不需要AVLTree的排序功能。另外,从纯粹的理论上来说,AVLTree的算法复杂度至少是O(Log2(x))级别,而HashTable则接近于O(C)级别。 一、 使用HashTable 在华容道程序中,要搜索以前出现过的布局,及时消除重复布局。早最初的设计中,我使用AVLTree来达到这个目的。AVL...
阅读全文
摘要:自从《华容道与数据结构》系列文章写完后,有很多热心的朋友提出了宝贵的意见,使得华容道程序的运行效率不断提升。在这里特别感谢"智能算法爱好者"与sumtec,给程序提出了很多建设性意见。 在《华容道与数据结构(续)》这部分内容中,我将从两个方面对原有程序进行改造,"以内存换效率",进一步提升华容道程序的执行效率。方法包括两方面:1、将原有4字节棋局表示变为8字节表示以省去原有程序中的排序操作。2、用...
阅读全文
摘要:在华容道程序写完后,我想尽办法优化程序的执行效率。衡量的尺子一直是河北石家庄李智广的"华容道全能版 V1.1",因此优化到5、6秒的执行时间就已经很满足了。期间的性能优化方法包括: 尽量减少CircularLinkedList中的节点数 去掉无用的接口,合并命名空间。避免接口转换对效率的影响 将排序算法代码调整为静态方法以提高调用效率。 这些对性能的调优使得代码的执行时间缩短了1.5~2秒左...
阅读全文
摘要:十六、 WinHRD的设计 基本组件的编写工作完成后,我们设计一个程序测试一下。在提供的源代码中提供了两个例子。一个是ConsoleHRD(DOS环境下的求解程序),比较简单。另外一个是Windows界面的WinHRD。 我们这里来看看WinHRD的设计:首先主窗口要实现IResultHandler接口以处理华容道组件提供的信息。例如当前搜索到了多少层级,以及求解的结果是什么。用户可以自己单独...
阅读全文
摘要:十五、 Mediator的设计 华容道自动求解程序的解题过程可以说是Layout、CircularLinkedList、AVLTree和TreeLinkedList相互协作的过程。为了降低对象间的耦合度,引入了一个中介者Mediator,负责协调它们之间的调用。我们可以在CircularLinkedList对象以及Layout对象中看到各有一个Mediator对象的引用。同时也可以看到Mediat...
阅读全文
摘要:十四、 CircularLinkedList的设计 CircularLinkedList类是整个程序的核心,所有搜索操作都由CircularLinkedList来触发。CircularLinkedList是一个环形链表,每个链表中的元素都含有下一元素的一个指针,元素与元素链接成封闭的环形。下面是该环型链表的节点定义: protected class LinkedListNode{ public...
阅读全文
摘要:十三、 TreeLinkedList的设计 在《华容道与数据结构 (2) 》中,设计了用于广度优先的树型链表。如下图: 链表是通过图中蓝颜色箭头链接起来的,而黑颜色箭头构成了树型结构。整个结构用来存储搜索结果,每一搜索步骤是一个层级,逐层深入直到找到结果。从图中可以看出,每个节点有两个指针,分别指向下一个节点与父节点。因此,在TreeLinkedList中定义节点类如下: protecte...
阅读全文
摘要:十二、 快速排序法 其实"快速排序法"不应当出现在华容道系列中,毕竟它是纯数据结构的内容。在这里我只简要介绍一下。以下内容来自D.S.Malik与P.S.Nair著的《Data Structures Using Java》一书。 关于快速排序法有以下要点: 1、 基于递归调用;2、 使用分而治之的方法对列表排序;3、 将要排序的列表分成两个子列表,然后被分别排序,并依次递归。最后合并成完成的排序列...
阅读全文
摘要:十一、 Layout的设计 Layout在我的程序中充当"布局",也就是说记录当前棋盘的状态。棋盘状态其实无外乎就是10个棋子的位置以及2个空格的位置而已。所以在Layout类中包含了两个成员: public class Layout{ private Chessman[] _chessmen = new Chessman[10]; private BlankPosition _blankP...
阅读全文
摘要:十、 Chessman的设计 整个程序中一个非常关键的环节就是Chessman(棋子)的设计以及Layout(棋盘布局)的设计。这次先说说Chessman的设计。 由于我的程序只针对10子布局,所以一个Layout应当包括10个棋子,分别归属于General、HChessman、VChessman与Soldier。下面是抽象Chessman类的部分定义: public abstract clas...
阅读全文
摘要:完整的程序代码可以从http://www2.cnblogs.com/Files/zhenyulu/HRD.rar下载 九、 代码设计 在看完了解题过程后,下面来看一看具体的代码设计方案: 我们首先从Core开始,在Core.dll里面定义了系统所需的最基本的数据类型以及相关的接口。其中枚举ChessmanType与MoveMethod分别定义了棋子的类型以及棋子移动的方法。 public enu...
阅读全文
摘要:八、 程序解题过程在这部分内容中,我们通过一个简化的实际例子来看看在华容道求解过程中,循环链表、AVL树以及树之间是如何相互协作的。首先我们假设所有的棋子只能向下移动(这样可以大大减少树中的节点数量),我们来看系统如何搜索所有可行步骤:首先,系统初始化各个部件。 环形链表中维护了三个指针:current指明当前运算到了哪个布局;last指针指向当前搜索层级的最后一个布局;allocate指针...
阅读全文
摘要:七、 AVL(平衡树) 平衡树其实就是一特殊结构的二叉树。由于二叉树的搜索算法的性能取决于二叉树的结构,如果二叉搜索树构造出来是线性的,搜索算法的效率不高。如果结构合理,则查找速度较快。实际上,树的高度越小,查找速度越快。大家可以比较一下下面两个二叉树在检索时,哪个效率更高一些: AVL树(也称作平衡树),在这种树型结构中,二叉树结构近似于平衡。AVL树具有如下特征: 1. 根的左子树和右子树...
阅读全文
摘要:华容道系列-开篇 华容道与数据结构 (1) 六、 数据结构设计 针对上面说到的解题方法,设计如下的数据结构: 1、广度优先的树型结构 由于整个棋局的可行解可以描述成一个树型结构,并且为了得到最少移动步数需要采用广度优先的搜索算法,因此考虑将链表与树型结构整合起来,便于进行广度搜索。如图,当我们试图搜索第三步可行解时,只需要顺着第二步的链表依次搜索便可以实现了。 2、堆栈结构输出最少步数 ...
阅读全文
摘要:续第一部分《华容道系列-开篇》 四、 棋盘布局存储方案 华容道棋盘布局经过优化后可以存储在4个字节中,确切的说是3字节零两个二进制位(10子)布局。经过简单调整后,也可以将12子布局存储在4个字节当中。不过12子布局的走法过于简单,所以在今后的文章中,布局全部指10子布局,软件只针对10子布局开发。设计方案如下: 上图演示了两种布局的存储结构。棋子总共分成5类,分别是最大子、横放、竖放、卒...
阅读全文
摘要:本系列内容将分成两大部分:《华容道与数据结构》以及《华容道与设计模式》,两者之间会有一些交叉。 一、 序言 这个学期给学生上《设计模式》的课程,有些学生提出找些题目练练手,增强一些实战经验,我决定让他们编写"华容道"游戏。说实在的,当时并没有深思熟虑。后来自己仔细想想,发现这里面东西还真不少,甚至包括下学期我才给他们开设的课程《数据结构》中的大量内容。所以我决定自己先来尝试一下。 其实编写"华容道...
阅读全文