|
|
1
7
好的,所以你的计划花费的时间比预期的要长。首先,我们想知道它是卡在无限循环中,还是只是缓慢。为此,让程序通过向主循环添加以下内容来打印其进度:
然后我们看到该计划每秒访问了数千个州。由于我们的处理器每秒执行几十亿条指令,这意味着处理一个状态需要大约一百万条cpu指令。应该不会那么高吧?那么是什么导致了这一点呢? 一般来说,我们现在会使用分析器来测量代码的哪一部分花费了这么多时间,但由于程序太短,我们可以先猜测一下。我的第一个猜测是,打印我们访问的每一个州都可能相当昂贵。为了验证这一点,让我们只打印每1000个状态:
我们注意到,前5000个州在不到一秒钟的时间内就被访问了,所以印刷确实很重要。我们还注意到了一些奇怪的事情:虽然前5000个州在一秒钟内就被访问了,但由于某些原因,该计划似乎越来越慢。在访问了20000个州时,访问1000个州大约需要一秒钟,而且情况还在恶化。这是意外的,因为处理状态不应该变得越来越昂贵。因此,我们知道我们回路中的某些操作越来越昂贵。让我们回顾一下我们的代码,以确定它可能是哪个操作。 无论集合的大小,推送和弹出都需要恒定的时间。但您也可以使用Stack.search和LinkedList.contains。这两个操作都需要在整个堆栈或列表上进行迭代。因此,让我们输出这些集合的大小:
等了一会儿,我们看到:
因此OPEN包含25000个元素,CLOSED包含近40000个元素。这解释了为什么处理状态越来越慢。因此,我们希望选择具有更有效的包含操作的数据结构,例如
它几乎立即打印“SUCCESS”。 |
|
|
2
2
我建议你使用 Hipster library 使用BFS、DFS、A*、IDA*等轻松解决8难题 full example here (这可能有助于您设计搜索策略)。
如果您感兴趣,解决问题的基本步骤是首先定义允许您遍历状态空间搜索问题的函数,然后选择一个算法来搜索状态空间问题。为了创建搜索问题,可以使用
一旦有了问题定义,就可以选择任何算法来解决问题:
在本演示中,您可以阅读更多关于8道难题的详细信息,以及如何使用Hipster解决它 https://speakerdeck.com/pablormier/hipster-an-open-source-java-library-for-heuristic-search |
|
|
3
1
您不应该将已经添加到其中的开放堆栈组合推入。(另外,ArrayDeque会更好,Stack是一个旧类,请参见javadoc http://docs.oracle.com/javase/7/docs/api/java/util/Stack.html
为了避免无数次探索相同的状态,必须使用Set作为关闭列表,并验证您试图添加到打开列表中的状态从未添加到关闭列表中。 此外,使用byte[]数组(而不是int[]来节省内存)而不是字符串来执行操作可能会更舒服。 总之,您可以这样构造代码:
这具有对图形中的任何类型的搜索都通用的优点。如果您想解决另一个难题,只需修改我没有实现的方法(实际上是Node接口的一部分)。如果你想改变算法,例如A星,它通常用于8个谜题,你只需要改变求解方法。我希望这段代码对您有所帮助。 |