值得注意的是,随着求解步数的增多(到 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个分支,都是使用了广度优先算法进行遍历计算,区别在于用于存储的节点使用的数据类型不一样
protocol SXNodeState {
var parentState: SXNodeState? { get set }
var data: [String] { get set }
var identifier: String { get set }
func childeStates() -> [SXNodeState]
}
protocol SXNodeState {
var parentState: SXNodeState? { get set }
var data: [Int] { get set }
var identifier: Int64 { get set }
func childeStates() -> [SXNodeState]
}
protocol SXNodeState {
var parentState: SXNodeState? { get set }
var identifier: Int64 { get set }
func childeStates() -> [SXNodeState]
}
通过 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
这部分不准备在这个项目继续更新了
鉴于华容道的特殊性,其最终状态是不确定的(只要曹操走到下部最中间即可),所以计算接近于最终状态的事情变得复杂了
如果非要使用也不是不可以 : 华容道现在有 400 多种初始布局,对应的有400多种最终布局,分别记录并增加权重即可。
本项目只是研究了一种布局,理论上可以添加一个最终布局,增加权重
还有一个问题,华容道有很多类似重复的来回走动,为了将一些子交换位置,所以加权的效果是有限的
上一条说过 :华容道有有限的布局
并且华容道是有 一横,二横,三横,四横等不同的解法步骤
所以如同魔方一样,一定有一些有限的中间布局,只需要从初始转换为中间布局,即可根据既定步骤求出解。
广度优先求解 15 步以内在 0.5 秒以内,如果再加上加权,0.5秒能解出更多的步骤。
最简单的方式应该是下边的样子
利用一个个关键点(木桩)的记录,使用搜索(跳)求解
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )