转-C# A*算法实现8数或者15数问题
2007-03-25 16:37
471 查看
-、问题描述
8数或15数问题是同一个问题,其就是一个随机排列的8个或15个数在一个方正格子中移动到达规定的一个目标状态。由于只有一个空格子,故只有在空格附近的棋子可以移动。
二、算法描述
F 算法选择
此问题需要对所有可能的路径进行穷举,但是由于随着树的高度的加大,其子结点的增加宿舍剧增,所以对所有的子结点进行穷举是不大现实的。而根据当前的状态和目标状态进行对比可以用一个评估函数来评估当前状态的好坏情况。而在这里我们选择A*算法来进行求解,A*算法是一种最好优先的算法。f'(n) = g'(n) + h'(n),f'(n)是估价函数,g'(n)是起点到终点的最短路径值,这里就表示树的高度,h'(n)是n到目标的最断路经的启发值,其原理是把当前产生的状态和以前所以的状态的评估函数值进行对比,选择其中最小的评估函数继续进行下一步。这里我选择h'(n)的启发值为每个格子到达它的目标位置所需要经过的最少步数。
F 算法描述
需要说明的几点:
1. 用OpenArr表示初始节点列表(待扩展,此为一个动态数组)
2.ClosedArr保存已经访问过的结点
3.算法首先需要给出初始状态,由于随机产生的状态并不一定能够走到目标状态,因此这里采用从标准状态往回走产生一个被打乱的随机状态,这样可以保证有解。
算法实现:
1. OpenArr放置初始结点
2. 如果OpenArr为空集,则退出并给出失败信号
3. n取为OpenArr的第一个节点,并从OpenArr中删除节点n
4. 如果n为目标节点,则退出并给出成功信号
5. 否则,将产生n子节点,并对n的每个子结点n’ 进行如下操作:
1)如果n’ 不在OpenArr和ClosedArr表中,则把n’放入OpenArr表中
2)否则,如果在OpenArr表中,计算评估值,并且如果比表中的评估函数的值小,则更新表中的评估值为当前的值。
3)否则,如果在ClosedArr表中,计算评估值,并且如果比表中的评估函数的值小,则把表中的评估值更新为当前的值,并把该结点从表中删除,并在OpenArr表中加入该结点。
6、把n结点加入ClosedArr中
7、对OpenArr进行排序(根据评估函数从小到大),并转到2。
三、程序设计
算法使用C#语言来实现的。程序主要根据上面提供的广度优先算法的描述来对算法进行实现的。程序共有四个类:
StepNode类,用来描述产生的各个结点的属性以及方法等
Heuristic_15Num_Search类,算法实现类
Form1类,是界面设计的类。
这里分别提供了8数和15数问题的求解。并显示了所经历过的各个状态转移
以下主要对几个核心算法的程序实现进行说明介绍。
//StepNode类 以下几个方法主要是控制格子的左右上下的移动
//0 数字上移
private void MoveUp(Position p)
// 0 数字下移
private void MoveDown(Position p)
//0 数字左移
private void MoveLeft(Position p)
//0 数字右移
private void MoveRight(Position p)
//计算节点的启发函数的值
private void ComputeGeuristicGeneVal()
//Heuristic_15Num_Search类
//核心算法实现部分
//循环搜索匹配
private void LoopSearch(StepNode node)
四、试验结果
1)8数问题搜索路径如下图
Generate 是用来随机产生一个初始状态(46) 表示从标准状态见过随机的46步后产生的一个随机的初始状态。这里46是一个随机数,由于该数越大离目标越远,搜索越复杂故将此随机数控制在0-100之间。3表示3的方正即8数问题,4表示4的方正即表示15数问题。
2)15数问题搜索路径如下图
从以上结果来看,由于使用了启发式的搜索过程,因此大大加快的搜索的速度以及能尽可能经过最少的路径最快到达目标状态,由于8数问题比较简单因此搜索速度较快,而15数问题复杂度加大,当随机产生的数接近100的时候搜索的时间迅速变慢,故算法还待改进,主要是因为随着深度的加深,OpenArr和CloseArr表中的数据迅速扩大,故可以考虑把OpenArr表中的状态数进行选择性的排除一些,比如每次把OpenArr中表的数据经过排序后可以删除最后的几个最差的状态,这样在一定程度上提高了速度但是也减低了找到最优解的几率不过这种减低是非常小的,因为被排除的已经是最差的情况了。
8数或15数问题是同一个问题,其就是一个随机排列的8个或15个数在一个方正格子中移动到达规定的一个目标状态。由于只有一个空格子,故只有在空格附近的棋子可以移动。
二、算法描述
F 算法选择
此问题需要对所有可能的路径进行穷举,但是由于随着树的高度的加大,其子结点的增加宿舍剧增,所以对所有的子结点进行穷举是不大现实的。而根据当前的状态和目标状态进行对比可以用一个评估函数来评估当前状态的好坏情况。而在这里我们选择A*算法来进行求解,A*算法是一种最好优先的算法。f'(n) = g'(n) + h'(n),f'(n)是估价函数,g'(n)是起点到终点的最短路径值,这里就表示树的高度,h'(n)是n到目标的最断路经的启发值,其原理是把当前产生的状态和以前所以的状态的评估函数值进行对比,选择其中最小的评估函数继续进行下一步。这里我选择h'(n)的启发值为每个格子到达它的目标位置所需要经过的最少步数。
F 算法描述
需要说明的几点:
1. 用OpenArr表示初始节点列表(待扩展,此为一个动态数组)
2.ClosedArr保存已经访问过的结点
3.算法首先需要给出初始状态,由于随机产生的状态并不一定能够走到目标状态,因此这里采用从标准状态往回走产生一个被打乱的随机状态,这样可以保证有解。
算法实现:
1. OpenArr放置初始结点
2. 如果OpenArr为空集,则退出并给出失败信号
3. n取为OpenArr的第一个节点,并从OpenArr中删除节点n
4. 如果n为目标节点,则退出并给出成功信号
5. 否则,将产生n子节点,并对n的每个子结点n’ 进行如下操作:
1)如果n’ 不在OpenArr和ClosedArr表中,则把n’放入OpenArr表中
2)否则,如果在OpenArr表中,计算评估值,并且如果比表中的评估函数的值小,则更新表中的评估值为当前的值。
3)否则,如果在ClosedArr表中,计算评估值,并且如果比表中的评估函数的值小,则把表中的评估值更新为当前的值,并把该结点从表中删除,并在OpenArr表中加入该结点。
6、把n结点加入ClosedArr中
7、对OpenArr进行排序(根据评估函数从小到大),并转到2。
三、程序设计
算法使用C#语言来实现的。程序主要根据上面提供的广度优先算法的描述来对算法进行实现的。程序共有四个类:
StepNode类,用来描述产生的各个结点的属性以及方法等
Heuristic_15Num_Search类,算法实现类
Form1类,是界面设计的类。
这里分别提供了8数和15数问题的求解。并显示了所经历过的各个状态转移
以下主要对几个核心算法的程序实现进行说明介绍。
//StepNode类 以下几个方法主要是控制格子的左右上下的移动
//0 数字上移
private void MoveUp(Position p)
// 0 数字下移
private void MoveDown(Position p)
//0 数字左移
private void MoveLeft(Position p)
//0 数字右移
private void MoveRight(Position p)
//计算节点的启发函数的值
private void ComputeGeuristicGeneVal()
//Heuristic_15Num_Search类
//核心算法实现部分
//循环搜索匹配
private void LoopSearch(StepNode node)
四、试验结果
1)8数问题搜索路径如下图
Generate 是用来随机产生一个初始状态(46) 表示从标准状态见过随机的46步后产生的一个随机的初始状态。这里46是一个随机数,由于该数越大离目标越远,搜索越复杂故将此随机数控制在0-100之间。3表示3的方正即8数问题,4表示4的方正即表示15数问题。
2)15数问题搜索路径如下图
从以上结果来看,由于使用了启发式的搜索过程,因此大大加快的搜索的速度以及能尽可能经过最少的路径最快到达目标状态,由于8数问题比较简单因此搜索速度较快,而15数问题复杂度加大,当随机产生的数接近100的时候搜索的时间迅速变慢,故算法还待改进,主要是因为随着深度的加深,OpenArr和CloseArr表中的数据迅速扩大,故可以考虑把OpenArr表中的状态数进行选择性的排除一些,比如每次把OpenArr中表的数据经过排序后可以删除最后的几个最差的状态,这样在一定程度上提高了速度但是也减低了找到最优解的几率不过这种减低是非常小的,因为被排除的已经是最差的情况了。
相关文章推荐
- C# A*算法实现8数或者15数问题
- [导入]C# A*算法实现8数或者15数问题
- A*算法实现8数或者15数问题
- C# A*算法实现8数或者15数问题
- A*算法实现8数或者15数问题(C#实现)
- NP难Packing 问题的拟人拟物算法C#实现
- 八数码问题--A算法实现---C#实现---VS2008可以执行
- NP难Packing 问题的拟人拟物算法C#实现
- 关于算法—— 一维字符串数组之间组合问题的C#实现
- C#WPF实现回溯算法解决八皇后问题
- 常用算法C#实现:字符串包含问题
- 在C#中使用SerialPort类实现串口通信 遇到多线程问题
- 整数取反问题的算法实现(C/C++实现,极简5行代码)
- 在winform中隐藏或者去除c#的标题栏并实现窗体移动附代码
- 关于n!被整除的问题【算法实现】
- Python实现的基于优先等级分配糖果问题算法示例
- 【数据结构】有向图、无向图以及最短路(Dijkstra, Floyd)算法的C#实现(纯模板Template实现)
- 数据结构与算法(C#实现)系列---AVLTree(二)(外摘)
- 使用matlab实现遗传算法解决飞行员侦查问题
- 用C#实现的简单树型图生成算法!