【问题标题】:Break out of a recursion in java when the time run out当时间用完时,在java中打破递归
【发布时间】:2011-05-05 15:59:02
【问题描述】:

我正在为类似国际象棋的游戏实施 AI。我打算使用递归来尝试棋盘的所有可能状态并选择“最佳走法”。

由于每次移动的时间限制,每当达到时间限制时,我需要有一些机制来打破这些递归过程。当然,我可以在进行递归调用之前继续检查时间,如果当前时间接近限制,我可以中断,但这是与我的程序性能的权衡。

如果有一种方法可以在计时器结束时打破这些递归过程,那就太好了。但是,由于我是 Java 新手,我不知道在 Java 中是否有任何方法可以做到这一点?你能给出一个示例代码吗? :)

【问题讨论】:

标签: java recursion timer break chess


【解决方案1】:

检查时间,例如System.currentTimeMillis() 每次调用花费大约 200 ns。但是,如果这对你来说太多了,你可以让另一个线程设置一个标志来停止。

已经有一种机制可以做到这一点。

ExecutorService es = Executors.newSingleThreadExecutor();
Future f = es.submit(new Runnable() {
    @Override
    public void run() {
        long start = System.nanoTime();
        while(!Thread.interrupted()) {
            // busy wait.
        }
        long time = System.nanoTime() - start;
        System.out.printf("Finished task after %,d ns%n", time);
    }
});
try {
    f.get(1, TimeUnit.SECONDS); // stops if the task completes.
} catch (TimeoutException e) {
    f.cancel(true);
}
es.shutdown();

打印

Finished task after 1,000,653,574 ns

注意:您不需要每次都启动/停止 ExecutorService。

【讨论】:

  • 啊,这看起来是个不错的方法……我没怎么用过Futures,看起来有一个很好的中断机制。
  • ExecutorService 可以做更多的事情,例如:返回一个值,跨多个线程运行/排队多个任务。如果您可以拆分搜索,您可能可以使用机器中的所有内核。 ;)
【解决方案2】:

我认为没有任何不涉及检查是否可以继续的好方法。

即使您确实检查了时间...如果您还剩下 8 milliseconds 会发生什么。你能保证你的递归调用会在那段时间内完成吗?你会在每一步之后检查时间吗(这可能会增加很多额外的开销)?

一种方法是让您的执行(递归)逻辑在一个线程中运行,而计时器在另一个线程中运行。当计时器完成时,它会在您的执行线程上调用interrupt()。在您的工作线程中,每次完成递归时,您都会保存所需的状态。然后如果被中断,返回上次保存的状态。

这只是对一种方法的简要描述.. 绝不是最好的方法

【讨论】:

    【解决方案3】:

    您可以使用布尔标志来设置 AI 任务何时必须停止。

    创建一个将运行 AI 任务的线程,该线程将在每次递归调用之前检查一个布尔变量。检查布尔变量比调用方法来获取时间更有效。让父线程在有限的时间内休眠。唤醒后,设置布尔标志停止子线程。

    【讨论】:

      猜你喜欢
      • 2017-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-24
      • 2014-08-22
      • 1970-01-01
      相关资源
      最近更新 更多