- 最后登录
- 2025-10-20
- 在线时间
- 951 小时
- 阅读权限
- 40
- 注册时间
- 2008-1-6
- 积分
- 1962
- 帖子
- 1077
- 精华
- 6
- UID
- 17579
- 性别
- 保密

- 积分
- 1962
- 帖子
- 1077
- 精华
- 6
- UID
- 17579
- 性别
- 保密
|
再重写这个程序的时候,会把以下模块分离出来:
3进制数同数组的转换
2机制数同数组的转换
以上两个合并起来
整数同排列的转换
整数同组合的转换
以上两个放在一起,是排列组合相关内容
已经有成熟的完美的算法,不用再自己设计了
以上是关于魔方状态数组与整数之间的转换,使用频率并不高
只在生成表的时候用一次
在每次搜索之前用一次
都是程序外围的非关键部分,效率高下与否不重要,
随便怎么设计都可以。
10.表的生成 movetabl.cpp 和 pruningt.cpp
这里的表,按照类型可以分两类:状态转移表和剪枝表
按照用途也可分两类:第一步骤的表和第二步骤的表
第一步骤的表
Flip.mtp 棱的方向状态转移表
Twist.mtp 角的方向状态转移表
Choice.mtb E层棱的位置选择状态转移表
FlipChce.ptb Flip和Choice的合并剪枝表
TwstFlip.ptb Twist和Flip合并的剪枝表
TwstChce.ptb Twist和Choice合并的剪枝表
第二步骤的表
CrnrPerm.mtb 角的排列状态转移表
EdgePerm.mtb 非E层棱的排列状态转移表
SlicePerm.mtb E层棱的排列状态转移表
CrnrSlic.ptb CrnrPerm和SlicePerm合并的剪枝表
EdgeSlic.ptb EdgePerm和SlicePerm合并的剪枝表
可以看到,每个步骤三个状态转移表。
两两合并,成三个剪枝表。
但第二个步骤,由于CornerPerm的表和EdgePerm的表乘起来太
大了,所以没有合并成剪枝表。
剪枝表的存在也是为了提高搜索的速度。
生成表的过程
状态转移表的生成
由于整数对应着魔方的状态(twist,flip,choice,perm等),
所以依次取这些整数,作为“老状态”,为每一个“老状态”分别作
18种(12种)基本操作,生成“新状态”,表存储:
Table[老状态][操作]=新状态
表查询 到达状态=Table[出发状态][操作];
分支表的生成
分支表是由两个状态转移表合并的
TB[表1中的状态][表2中状态]=还原态到达这个状态需要的步长
两个状态整数被合并了成一个整数,索引的时候用一个数字乘
表的宽度,再加另一个状态。
合并的状态是既满足表1的状态,也满足表2的状态。
存储的是步长,生成的时候采用的是多次扫描,为一层层的生成。
从初始态开始,一层一层向下扩展。
先取分支表的索引,分解成两个状态表中的状态,让这两个状态在
同一个操作的加工下,生成两个新状态,再把两个新状态合并成分支
表的索引。这个索引在第几层扫描的时候遇到,深度就填几。
以上是moveTable和pruningTable的生成过程。
在对应的文件中定义。
生成表的过程因为是只工作一次,所以,效率不高也没有关系。也可分离模块,
成为 基础支持,表的生成,表的应用。
生成的数据是为了配合高效率搜索的,IDA*的搜索到底是怎样使用这种表的呢?
[ 本帖最后由 aubell 于 2010-4-16 18:46 编辑 ] |
|