First we try, then we trust

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

十六、 WinHRD的设计

基本组件的编写工作完成后,我们设计一个程序测试一下。在提供的源代码中提供了两个例子。一个是ConsoleHRD(DOS环境下的求解程序),比较简单。另外一个是Windows界面的WinHRD。

 

我们这里来看看WinHRD的设计:首先主窗口要实现IResultHandler接口以处理华容道组件提供的信息。例如当前搜索到了多少层级,以及求解的结果是什么。用户可以自己单独设计一个实现IResultHandler接口的类来处理这些事情。只要将该类的实例提供给Mediator对象就行了。

public class frmMain : Form, IResultHandler
{
  …………
  
public void HandleResult(ChessStep[] steps)
  
{
    
// 处理搜索结果
    …………
    
return;
  }


  
public void HandleInfo(int currentStep)
  
{
    
// 处理搜索中的信息
    this.lblInfo.Text = "搜索深度: " + currentStep.ToString();
    
this.lblInfo.Refresh();
  }

}

在窗体的初始化代码中初始化各个组件:

public frmMain()
{
  InitializeComponent();

  
// 初始化自动求解程序
  mediator = new Mediator();
  mediator.avlTree 
= new AVLTree();
  mediator.treeList 
= new TreeLinkedList();
  mediator.resultHandler 
= this;
}

为了确保程序的运行效率,我们在单独的线程中运行主处理程序。因此,我们将主要的处理程序封装到一个Process方法中,并将其运行在单独的线程中,线程的优先性设置为BelowNormal,IsBackground设置为true。代码如下(部分简化):

private void btnBegin_Click(object sender, System.EventArgs e)
{
  layoutFactory.mediator 
= mediator;
  mediator.circleList 
= new CircularLinkedList(layoutFactory);
  mediator.resultHandler 
= this;

  mediator.Init(
1000);

  Thread trd 
= new Thread(new ThreadStart(this.Process));
  trd.Priority 
= ThreadPriority.BelowNormal;
  trd.IsBackground 
= true;
  trd.Start();
}


private void Process()
{
  
if(!mediator.BeginProcess())
    
this.txtResult.Text = "此题无解!";

  mediator.Release();  
// 及时释放内存;
}


private void btnStop_Click(object sender, System.EventArgs e)
{
  mediator.Stop();
}

至此,我们就完成了客户端的设计。主运算运行在单独的线程中,并可以随时被终止。不会给用户带来任何停滞的感觉。


十七、 性能大比拼

完成了程序的主体工作后,就需要对效率进行一下评价了。我将自己的程序与河北石家庄李智广的"华容道全能版 V1.1"进行了效率对比。在我的机器上(P4 2.0G、512M DDR400内存)得到如下测试结果:

 

从表中可以看出,在一些比较简单的布局中,"华容道全能版"拥有比较高的运算效率。但当搜索的节点数超过40000时,"华容道全能版"的搜索效率急剧下降。运算时间均在10秒甚至15秒以上。本程序在运算上效率较高,尤其是在复杂布局的求解上也拥有令人满意的效率。究其原因,本人认为有以下几点:

1、本程序将布局转换为4字节整数消耗了过多的CPU时间(需要排序操作),因此为了节省内存而损失了效率。

2、AVLTree带来了良好搜索性能。即使搜索节点超过40000节点,AVLTree也能确保最多在16次比较后就能判断出是否有重复布局(2^16=65532)。

3、种种迹象表明,"华容道全能版"在判断下一步可行走法时,仅仅判断了四种情况:上、下、左、右。而本程序判断了九种情况,除上下左右外还包括上移两步、下移两步、左移两步、右移两步以及转弯(专门针对卒)。因此"华容道全能版"在一步的判断上速度要快很多,但增加了搜索深度(从表中的数据也可以看出来),并且不能正确求得华容道求解的最小步数。

"智能算法爱好者"的结论是:走一格尽管深度增加,但一个递归层的节点宽度比走两格的节点宽度窄了很多,比较的有效节点差不多,但比较的总节点数少了很多,所以走一格比走两格要少很多时间,大约为走两格的70%(用我的同一程序测试),并且只有走两格才能找到最少步数(最优解)。

如果对内存的使用可以放宽松一些的化,我们可以考虑采用其它的方式存储棋盘布局(不再使用4字节表示),这样虽会使AVLTree的构建过程有所减慢,但华容道求解速度会有所提升(不再需要执行排序操作了)。总体来说,对布局搜索速度会有提升(这只是我的猜测,未经验证)。




关于《华容道与数据结构》的内容到此就全部完成。本文中的最终程序代码可以从http://www2.cnblogs.com/Files/zhenyulu/HRD.rar下载。如果时间允许,我会继续完成《华容道与设计模式》,给这个程序添加一个更丰富的客户端界面,允许更好的人机交互,实践并应用一些设计模式在里面。

(全文完)

posted on 2005-02-11 22:23  吕震宇  阅读(5823)  评论(13编辑  收藏  举报