1 Star 1 Fork 1

ShownBie / HuaRongDao

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

HuaRongDao

看一下 三个分支 效果

值得注意的是,随着求解步数的增多(到 20 步),使用二进制位的 Ultimate 分支效率开始变慢了

以下展示的初始状态最终都要转换为这个最终状态
卒卒张赵
关关张赵
马马黄黄
〇曹曹卒
〇曹曹卒


//////////////////    master      /////////////////////////

----当前查询个数----3506-------已经存储的节点数----79000-----
----当前查询个数----3506-------已经存储的节点数----79000-----
--------success------------查询节点---3527---------记录节点---80541----
----------success----!----用时----35.91596698760986----s--------------
卒卒张赵
关关张赵
曹曹马马
曹曹黄黄
卒卒〇〇

...
----求解步数----11----!----------

//////////////////      Preview      /////////////////////////

----当前查询个数----106-------已经存储的节点数----223-----
----当前查询个数----172-------已经存储的节点数----892-----
--------success------------查询节点---178---------记录节点---927----
----------success----!--用时--0.22210407257080078------
卒卒张赵
关关张赵
曹曹〇〇
曹曹马马
卒卒黄黄

...
----求解步数----13----!----------


//////////////////      Ultimate      /////////////////////////

--------success------------已经查询节点---230---------记录未查询节点---1154----
----------success----!--用时--0.0885307788848877------
单单纵纵
横横纵纵
曹曹横横
曹曹〇〇
单单横横

...
----求解步数----13----!----------

介绍

制定通用的协议来处理类似的情形,状态点,权重,搜索协议

//某个状态
protocol SXNodeState {
    var parentState: SXNodeState? { get set }

    var data: [Int] { get set }

    var identifier: Int64 { get set }

    func childeStates() -> [SXNodeState]
}

//某个状态的权重 暂未使用
protocol SXAStarState {
    var fromValue: Int { get set }

    var toValue: Int { get set }

    var totalValue: Int { get set }

    func toTargetStatus(_ from: SXNodeState) -> Int
}

//搜索器
protocol SXSeacher {
    var startState: SXNodeState { get set }

    var targetState: SXNodeState { get set }

    var successComparator: (SXNodeState, SXNodeState) -> Bool { get set }

    func search() -> Bool

    func pathWithState() -> [SXNodeState]
}

关于三个分支的优化

华容道的求解算法:

项目分3个分支,都是使用了广度优先算法进行遍历计算,区别在于用于存储的节点使用的数据类型不一样

  • master: 采用字符串作为标识记录和存储节点
protocol SXNodeState {
    var parentState: SXNodeState? { get set }

    var data: [String] { get set }

    var identifier: String { get set }

    func childeStates() -> [SXNodeState]
}
  • Preview: 使用[Int]记录数据,使用 Int64 记录状态,区分重复
protocol SXNodeState {
    var parentState: SXNodeState? { get set }

    var data: [Int] { get set }

    var identifier: Int64 { get set }

    func childeStates() -> [SXNodeState]
}
  • Ultimate: 只使用了 Int64 记录当前状态,并且作为唯一标识
protocol SXNodeState {
    var parentState: SXNodeState? { get set }

    var identifier: Int64 { get set }

    func childeStates() -> [SXNodeState]
}

关于 Ultimate

通过 0(曹操) 1(横将) 2(纵将) 3(单个)来使用二进制位记录当前状态,在分别使用两个5位的数据用来表示两个空格的位置

例如如下布局的表示为:

卒卒张赵
关关张赵
曹曹马马
曹曹黄黄
卒卒〇〇

-------十进制如下----------
3322
1122
0011
0011
3333

其空格分别为18,19
--------二进制即是---------
11 11 10 10
01 01 10 10
00 00 01 01
00 00 01 01
11 11 11 11

其空格分别为10010,10011
--------所以其最终 id 为 50 位的二进制数---------

let identifier: Int64 = 0b11111010010110100000010100000101111111111001010011

关于效率

  1. 无疑最慢
  2. 使用 Set 记录历史之后快了很多,得益于 swift 数组的性能,运算速度是目前最快的
  3. identifier 即数据,内存占用大大优化;虽然位运算速度快很多,但是大量的位移和判断拉低的性能

更进一步的优化

这部分不准备在这个项目继续更新了

  1. 增加权重

鉴于华容道的特殊性,其最终状态是不确定的(只要曹操走到下部最中间即可),所以计算接近于最终状态的事情变得复杂了

如果非要使用也不是不可以 : 华容道现在有 400 多种初始布局,对应的有400多种最终布局,分别记录并增加权重即可。

本项目只是研究了一种布局,理论上可以添加一个最终布局,增加权重

还有一个问题,华容道有很多类似重复的来回走动,为了将一些子交换位置,所以加权的效果是有限的

  1. 最快解法

上一条说过 :华容道有有限的布局

并且华容道是有 一横,二横,三横,四横等不同的解法步骤

所以如同魔方一样,一定有一些有限的中间布局,只需要从初始转换为中间布局,即可根据既定步骤求出解。

  1. 结合资料和算法

广度优先求解 15 步以内在 0.5 秒以内,如果再加上加权,0.5秒能解出更多的步骤。

最简单的方式应该是下边的样子

利用一个个关键点(木桩)的记录,使用搜索(跳)求解

空文件

简介

暂无描述 展开 收起
Swift
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
Swift
1
https://gitee.com/poos/HuaRongDao.git
git@gitee.com:poos/HuaRongDao.git
poos
HuaRongDao
HuaRongDao
master

搜索帮助

53164aa7 5694891 3bd8fe86 5694891