- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
如果这是一个很长的问题,我很抱歉,但我不确定我的 A* 8 拼图 Java 代码是否有效...我发现我的代码对于简单的输入(易于平均的情况)运行得很好,但是我不知道它是否适用于最坏的情况......
我尝试修改我的代码以使用每个节点的曼哈顿距离作为我的启发式函数,我的代码即使在最坏的情况下也能正常工作,但它花费的时间太长......当我使用“错位的瓷砖数量”时作为我的启发式函数,与使用曼哈顿距离相比,我的代码需要更长的时间来运行简单到平均的案例。即使在 15 分钟后,它也不会为最坏的情况生成解决方案......
注意:在最坏的情况下,一个 8 的谜题最多可以解决 31 步...
...这是我的代码的主要功能:
List<Node> nodeList = new ArrayList<Node>();
nodeList.add(startNode); //"Node startNode" contains the root node of the tree that will be produced
Node currentNode = null;
while (1 == 1) {
//THIS SECTION FINDS THE LEAF NODE WITH THE LEAST f(n)
currentNode = null;
for (Node pickNode : nodeList) {
if (pickNode.isLeaf == true) {
if (currentNode == null)
currentNode = pickNode;
else if (pickNode.fn < currentNode.fn){
currentNode = pickNode;
}
}
}
/*-----------------------------------------------------------*/
//BREAK THE LOOP WHEN THE SOLUTION IS FOUND
if (Arrays.deepEquals(currentNode.state, goalState))
break;
/*-----------------------------------------------------------*/
else {
int xcheck = currentNode.zeroX;
int ycheck = currentNode.zeroY;
int switcher;
int approve = 1;
/*-----------------------------------------------------------*/
//THE FOLLOWING LINES DETERMINES WHICH CHILDREN CAN BE PRODUCED BY A NODE
if ((ycheck - 1) >= 0) {
int subState[][] = new int [3][];
subState[0] = currentNode.state[0].clone();
subState[1] = currentNode.state[1].clone();
subState[2] = currentNode.state[2].clone();
switcher = subState[ycheck-1][xcheck];
subState[ycheck-1][xcheck] = 0;
subState[ycheck][xcheck] = switcher;
Node checkerNode = new Node();
checkerNode = currentNode;
while (checkerNode != null) {
if (Arrays.deepEquals(subState, checkerNode.state)) {
approve = 0;
break;
}
checkerNode = checkerNode.parentNode;
}
if (approve != 0) {
Node childNode = new Node();
childNode.state = subState;
childNode.totalPath = currentNode.totalPath + "*" + "up";
childNode.gn = currentNode.gn + 1;
childNode.hn = computeHn(childNode.state, goalState);
childNode.fn = childNode.gn + childNode.hn;
childNode.isLeaf = true;
childNode.parentNode = currentNode;
childNode.zeroX = xcheck;
childNode.zeroY = ycheck-1;
nodeList.add(childNode);
}
}
approve = 1;
/*-----------------------------------------------------------*/
if ((ycheck + 1) <= 2) {
//same logic with: if (ycheck-1 >= 0)
}
approve = 1;
/*-----------------------------------------------------------*/
if ((xcheck + 1) <= 2) {
//same logic with: if (ycheck-1 >= 0)
}
approve = 1;
/*-----------------------------------------------------------*/
if ((xcheck - 1) >= 0) {
//same logic with: if (ycheck-1 >= 0)
}
approve = 1;
}
currentNode.isLeaf = false;
}
这是为我的启发式计算的函数(错放的瓷砖数量而不是曼哈顿距离):
public static int computeHn (int checkStateH[][], int goalStateH[][]) {
int total = 0;
int rowC = 0;
int columnC = 0;
rowC = 0;
while (rowC < 3) {
columnC = 0;
while (columnC < 3) {
if (goalStateH[rowC][columnC] != checkStateH[rowC][columnC]) {
total++;
}
columnC++;
}
rowC++;
}
return total;
}
这是我的节点类:
public class Node {
int state[][]; //contains the matrix configuration of the node
String totalPath; //contains the path on how to get to this node from the root node
int gn; //contains the number of moves made to get to this node from the root node
int hn; //contains the heuristic (number of misplaced tiles per node)
int fn; // fn = gn + hn
boolean isLeaf; //states whether a node is a leaf or not. used so that I can know whether a node could still be expanded or not
Node parentNode; //points to the node's parent node
int zeroX; //the x position of the zero tile
int zeroY; //the y position of the zero tile
}
这是给定的矩阵,或“开始状态”矩阵(在最坏的情况下,这至少可以通过 31 次移动来回答):
...它应该达到这个最终状态:
...再次,当我使用“曼哈顿距离”作为我的启发式函数时,我的代码有效,但需要 30 秒才能为这种输入生成答案...但是当我使用“错放的瓷砖数量”时“作为我的启发式函数,即使在 15 分钟后它也不会生成解决方案,但当我改用此矩阵时会给出答案:
...感谢那些愿意提供帮助的人!...我很抱歉,如果它有点长,但我认为我应该发布我的代码而不是仅仅陈述我的代码的逻辑,因为我可能在实现过程中犯了错误我的逻辑...
最佳答案
曼哈顿距离会更快是有道理的,因为它是一种更好的启发式算法。 30 秒等待解决方案的时间有点长,尤其是对于 C++,但这并不是完全荒谬的。 >15 分钟是,虽然,即使是一个不太好的启发式。
如果我正确地解释了您的代码,checkerNode
循环会通过遍历整个路径来检查此状态是否已经存在于您当前正在探索的路径中。这是相当低效的(我认为是 O(log(n)ish))。如果您维护一个已经扩展的状态字典,则可以将其缩减为常数时间。
可能还有其他细微的低效问题,但我怀疑这会大大加快您的代码速度。
编辑解释字典:
字典是一种数据结构,可让您快速查找某个元素是否存在。
对于大多数数据结构,如果您想查找具有给定值的元素,则必须将该值与已存储在该结构中的每个元素进行比较(就像您将 checkerNode 与所有前导节点进行比较一样)。问题是,随着你在数据结构中存储的东西越来越多,这个过程需要的时间越来越长。字典不是这种情况,因为字典使用称为哈希表的东西立即转到给定元素(如果存在)的存储位置。然后,如果该元素存在,您就知道它在数据结构中,如果不存在,您就知道它不存在。
字典通常用于将给定的键映射到关联的值,但在这里我们并不真正关心该功能。我们只是想知道给定的键是否在字典中,所以我们可以将值设置为我们想要的任何值(通常我只存储 boolean 值“True”,或者如果您需要能够存储指向节点的指针重新找到它)。在 C++ 中,内置字典类是 std::map .
要在您的代码中使用它,您可以大致执行以下操作:
首先,初始化 map 对象
std::map<char,int> already_explored;
执行程序的开始,直到一个值刚刚分配给 currentNode。现在我们正在探索 currentNode,我们将它的状态添加到字典中。状态是键,“真”是值。
already_explored[currentNode.state] = True;
继续执行该程序,直到找到下一个状态(想知道它是否已经出现)。现在我们可以在字典中查找:
if (already_explored.count(subState) > 0){
approve = 0;
}
如果按此顺序执行操作,您甚至不必担心检查具有相同状态的其他节点的 f(n) 值。 A* 到达的第一个保证是到达该状态的最快方式。走更长的路到达同一状态永远不会有任何好处。
关于java - A* 8 拼图运行时间太长,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28600118/
我在某处遇到了以下难题 #include int main() { { /*Fill in something here to make this code compile
我正在尝试为 iOS 创建一个拼图游戏应用程序。从我在互联网上的搜索来看,确实没有任何关于这个主题的教程。有谁知道任何人都知道的好教程或游戏教程的链接?谢谢。顺便说一下,iOS4 将不胜感激。 最佳答
如果必须使用 Promises,您会如何编写以下代码? 这个想法是,“私有(private)”方法 p1 调用一个执行异步操作的函数,然后,当异步调用的结果准备就绪时,控制权将传递给“私有(priva
下面是其中一个 facebook 谜题:我无法理解如何进行此操作。 你有 C 个容器、B 个黑球和无限数量的白球。您希望以一种方式在容器之间分配球,即每个容器至少包含一个球,并且选择白球的概率大于或等
有 5 位成员围坐在一张 table 旁。关键值是坐在 table 周围的成员数量。所以现在关键值将是 5。一个恐怖分子告诉成员,因为你们是 5 个成员,所以我将从第一个成员开始数,数到 5 的人将被
你能在不抛出错误的情况下解决这个问题吗?答案是单线。这是来自一个死的职位发布,在回复中要求回答。我认为这是剔除受访者的聪明方法,但我似乎无法在不出错的情况下回答它。 显而易见的解决方案: f.moo(
此源输出 G'Day Mate. 这是怎么发生的? public static void main(String args[]) { System.out.println("Hello Wor
我正在 android 中开发一个 slider 拼图,它有一个图像被分解成小图像,我们需要对这些 fragment 进行排序以形成正确的图像。我使用了一个 3x3 的 GridView ,其中包含
我遇到了以下难题,无法在 Picat 中制定解决方案: You will generate 5-digit numbers, where each digit is in 1..5 and diffe
我是 Javascript 新手,并且正在努力解决 CodeWars 中的这个难题。 约翰想用壁纸装饰房间。房间的尺寸为:宽度(w)、高度(h)、长度(l)。一卷壁纸的尺寸为 52cm 宽,10m 长
我对 Java 还很陌生,尝试过 Best Before puzzle from Spotify昨天。当我发送它时,我收到“错误答案”错误。检查其他解决方案没有帮助,我无法弄清楚哪个输入给出了错误的答
我正在尝试恢复我拥有的一些旧代码,这是一个拼图游戏。它从文件夹中加载图像(拼图),将它们随机放置在页面周围,然后拖放到板上。这曾经有效,但当我今天尝试使用它时,它只是抛出错误(见下文)。 HTML:
这对你们来说可能是个愚蠢的问题。它是关于 CSS Sprites 的。我有一个包含 4 个菜单的导航,例如 .. HOME COMPANY SERVICES SUPPORT 尽管我使用了一个 css
我需要创建一个标题,可以根据正在构建的页面轻松添加或删除部分,但我在处理其中一部分时遇到了问题。 我有一个标题,看起来像这样将所有组件放在 如果导航被移除,它应该看起来像这样(垂直居中) 我的问题是如
我在 JS 中构建了一个 15 拼图,但我的随机拼图生成正在创建无法解决的拼图实例。这可能是因为我不是计算机科学专业的负责人,但我不确定如何计算代码排列中的反转次数。我想知道如何编写我的代码,以便我可
我正在寻找 8 Puzzle graphs tree generator,最好是 (php+) html+css+javascript。我需要的是类似 3 2 1 6 8 7 5 4 会生成所有可
我住在德国,在 Android Market 上发布“Last Call Widget”。随着时间的推移,我一直在稳步改进它,但一组用户仍然提示它无法在他们的设备上运行。 我的小部件监听“androi
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况相关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
我正在尝试制作一个看起来像这样的拼图游戏。我试过的看起来像这样。 https://jsfiddle.net/uccfb46z/ 现在如果我想改变碎片的形状我需要修改这部分 - outside: fu
首先,让我为缺少 SSCCE 表示歉意。我在这方面真的没有足够的专业知识来弄清楚什么是相关的,什么不是。 简而言之,问题是在两台运行相同分辨率 (1366x768) 的不同计算机上,我女朋友的 tum
我是一名优秀的程序员,十分优秀!