作为我目前的CS课程中的家庭作业,我们已被指示编写一个程序,为n-puzzle problem实现A *算法。为了解决这个问题,您必须从StdIn获取初始nxn板配置。捕获的是一些板可能无法解决。值得庆幸的是,如果你通过翻转任意两个非零方块创建一个“双胞胎”板并尝试解决这个问题,原始或双胞胎必须是可解决的。因此,为了实现该算法,我们有效地尝试同时解决两块板,原始和双块。
在单线程中执行此操作非常简单,这就是实际的分配。看看这个问题,似乎这是一个利用并行性的完美场所。我想从主线程我会尝试生成两个并发线程,每个线程试图解决自己的板。这有可能在java中没有太多疯狂的代码吗?就此而言,在多核芯片上运行速度会明显快于非多线程版本吗?我正在尝试阅读线程的java文档,但对于之前从未尝试过这个问题的人来说,它有点厚,我发现通过编写/查看示例而不是阅读更多文档,我学得更快。
有人可以给我一些示例代码,显示类型结构,类,重要语句等。这样做有必要吗?到目前为止,我认为我想实现一个私有类实现runnable并让主线程抛出一个中断,线程没有先完成,以确定哪一个是可解的,加上移动的数量和板的顺序到到那儿。
编辑: TL; DR这不是分级分配的一部分。任务是进行单线程实现。为了我自己的丰富和我自己的丰富,我想尝试让我的实现多线程。
答案 0 :(得分:3)
因为你不希望自己的线程实现(这可能会更复杂;转换表是并行A *实现的瓶颈 - 但在praxis并行IDA *算法无论如何都更容易实现并且通常优点)问题实际上非常简单。
只需将您的实现打包在一个可运行的类中并使用一个线程。为简单起见,您可以使用初始化为false的全局volatile布尔变量,并在一个线程找到解决方案后立即设置为true。 您现在只需在代码中的适当情况下检查标志,并在其他线程已找到解决方案时返回。你也可以使用中断,但保持简单不会造成伤害(最后它实际上非常相似,你只需检查变量有点发烧友。)
琐碎的例子:
public class Main implements Runnable {
private static volatile boolean finished = false;
public static void main(String[] args) {
new Thread(new Main()).start();
new Main().run();
}
@Override
public void run() {
while (!finished) {
// do stuff
if (solutionFound) {
finished = true;
// save result
}
}
return;
}
}
答案 1 :(得分:0)
忘记解决两块板,其中一块无法解决。我不知道它是如何有用的,但忽略了这一点,并行化不应该停留在两个处理器上。如果系统有更多这些,那么算法应该全部使用它们。顺便说一句,检查电路板是否可以解决是相当容易的。查看维基百科文章中的可解决性部分。
要并行处理事物,您的A *实现应具有某种优先级队列,该队列按启发式值对项目进行排序。在搜索树中扩展节点涉及从队列顶部删除节点,并将几个节点插回队列中,从而保持队列排序。当事情像这样组织时,添加更多线程来插入和删除东西是相当简单的。只需同步访问队列。