您的位置:首页 > 其它

使用ActionScript3基于Flex实现八数码问题启发式搜索

2009-11-20 21:08 573 查看




人工智能的实验题目总是比较有意思,花了一下午一直到现在,终于用ActionScript3基于Flex写出了程序可视化的展示八数码问题启发式搜索。 其实也没什么值得自豪的新思想,主要就是界面好看点儿吧。纪念一下。

主要设计了这几个类:

  NumBox  表示有数字和背景的一个格子 ,继承Canvas

  Board    表示含有9个数字的棋盘(空白是用0代表的,只是这个数字没显示出来),继承Canvas

  MoveDirection   定义和四个方向有观点的一些静态常量

  BoardState   很重要的一个类,代表状态空间中的一个状态

  

   主要看下BoardState的成员

   private var state:Array=[]; //数字序列表示的当前状态
   public var cost:uint=0; //该节点的总代价
  public var depth:uint=0; //该节点在状态空间树上的深度
  public var fromDirection:uint=0; //产生当前状态空白格子应该移动的方向
  public var forbiddenDirection:uint=0; //产生当前状态的方向的相反方向(防止循环)

效果DEMO:



SHOW一下CODE:



其实也没什么技术含量,就是按启发式搜索 f(n) = g(n) + h(n) ,设置了OPEN表,CLOSE表和VISITED表(用来记录已访问的状态节点)

本来想对OPEN表的排序用快速排序算法的实现,后来看了下as3文档发现不需要了,只要用Array的sortOn就行了主要贴一下main.mxml的as代码如下

// ActionScript file
import mx.states.State;

private var seq:Array=[
0, 1, 2,
3, 4, 5,
6, 7, 8
];

private var bds:Array=[];

private var tableOpen:Array=[];
private var tableClose:Array=[];
private var tableVisited:Array=[];

private var nowStep:uint=0;

private var queue:Array=[];
private var nowDepth:uint=0;
private var bsFirst:BoardState;
private var bsTarget:BoardState;

private var targetFinded:Boolean=false;

private function init():void {
bds=[
bd1, bd2, bd3, bd4,
bd5, bd6, bd7, bd8,
bd9, bd10, bd11, bd12,
bd13, bd14
];
for each (var bd:Board in bds) {
bd.visible=false;
}

boardBegin.init(seq);
boardEnd.init(seq);

this.title="八数码问题";
}

private function start():void {
//初始化
bsFirst = boardBegin.getBoardState(); //加入第一个节点
bsTarget = boardEnd.getBoardState(); //目标节点状态

if (bsFirst.diff(bsTarget)==0) {
debug("达到目标状态");
return;
}

bsFirst.caculateCost(0, bsTarget);

tableOpen.push(bsFirst); //加入OPEN表
tableVisited.push(bsFirst); //标记为已走过的节点
debug("ok, 初始化成功");
}

private function next():void {
debug("----------------------------------开始走第"+nowStep+"步");
//开始算法
if (tableOpen.length==0) {
debug("OPEN表空了,无法到达目标状态");
return;
}

if (targetFinded) {
debug("已经达到目标状态");
return;
}

var bsNow:BoardState=popBestFromOpen(); //从OPEN表中取出一个总代价最低的节点

if (nowStep<14) {
(bds[nowStep++] as Board).init(bsNow.toArray());
}

if (bsNow.diff(bsTarget)==0) {
debug("达到目标状态");
targetFinded=true;
return;
}

tableClose.push(bsNow); //加入CLOSE表
debug("OPEN表长度="+tableOpen.length);
debug("CLOSE表长度="+tableClose.length);
debug("VISIT表长度="+tableVisited.length);
debug("又产生了 "+bsNow.generateNextStates(tableVisited, tableOpen, bsTarget)+" 个新状态");
}

private function popBestFromOpen():BoardState {
var tmp:BoardState;
debug(">>>OPEN表排序前");
debug("排序前tableOpen.length="+tableOpen.length);
for (var i:uint=0; i<tableOpen.length; i++) {
tmp=tableOpen[i] as BoardState;
debug(tmp.dumpReadableString());
}

if (tableOpen.length==1) {
debug(">>>OPEN表长度为1不用排序");
return tableOpen.pop() as BoardState;

} else {

//根据cost排序

tableOpen.sortOn("cost", Array.NUMERIC | Array.DESCENDING);

debug(">>>OPEN表排序后");
debug("排序后tableOpen.length="+tableOpen.length);

for (var j:uint=0; j<tableOpen.length; j++) {
tmp=tableOpen[j] as BoardState;
debug(tmp.dumpReadableString());
}

//选择cost最小的,从OPEN表中删掉并返回
return tableOpen.pop() as BoardState;
}
}

private function debug(msg:String):void {
this.txtDebug.text=msg+"\n"+this.txtDebug.text;
}

//OPEN表快速排序算法的实现
private function quickSort(table:Array, lowBound:uint, hignBound:uint):void {
//不需要了,只要用Array的sortOn就行了
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐