0

反復的な深化 (増分ツリー構築) を実装したい。これは、私が尋ねる私のコードの一部です:

        ExecutorService executorService = Executors.newSingleThreadExecutor();

        Set<Callable<Integer>> callables = new HashSet<Callable<Integer>>();

        callables.add(new Callable<Integer>() {
            public Integer call() throws Exception {
                iterativeDeepening(depthLimit, board);
                return -1;
            }
        });
        callables.add(new Callable<Integer>() {
            public Integer call() throws Exception {
                Thread.sleep(500);
                return 1;
            }
        });
        try{
            executorService.invokeAny(callables, 1000, TimeUnit.MILLISECONDS);
        }catch(TimeoutException | InterruptedException ex){
            executorService.shutdown();
        }

        executorService.shutdown();

時間制限のある invokeAny() について読んだことから、期限に達するとすぐに Callable オブジェクトの実行を終了する必要があります。関数 iterativeDeepening(depthLimit, board) の代わりにロングスリープを設定すると機能します。私の機能でそれを機能させるにはどうすればよいですか?以下に、この関数にコードを貼り付けます。

    public void iterativeDeepening(byte depthLimit, byte[] board){

    for(byte depth=1;depth<depthLimit;depth++){
        GameTree gameTree= new GameTree();
        byte[] tempBoard = new byte[14];
        for(byte i=0;i<14;i++){
            tempBoard[i] = board[i];
        }
        Node <byte[]> root= new Node<byte[]>(tempBoard, player);
        try {
            gameTree.buildGameTree(depth, root);
        } catch (OutOfMemoryError E) {
            gameTree.eraseGameTree(depth,root);
            System.gc();
        }

        MiniMax minimax = new MiniMax(player);
        move= minimax.selectMove(depth, root);

    }
}

それを行うためのより良い方法を知っているか、関数の実行を正常に停止する方法を知っている場合は、お知らせください。このトピックで言及されているRunnable Interfaceも試しました: Javaで特定の時間後に実行を停止する方法は? しかし、それは同じように機能しました。

4

1 に答える 1

1

タイムアウトに達すると、ExecutorServiceは現在実行中のすべてのタスクを呼び出して中断しようとThread.interrupt()します。これにより、各スレッドが中断状態になります。sleep()この状態が設定されると終了します。

したがって、このチェックを追加します。

if(Thread.currentThread().interrupted()) {
    return;
}

関数内で仕事をする必要があります。

スレッド終了のヒント:

try{
    executorService.invokeAny(callables, 1000, TimeUnit.MILLISECONDS);
} catch(TimeoutException | InterruptedException ex){
    //... ignore
} finally {
    executorService.shutdown();
    executorService.awaitTermination(); <-- add this line if you want to wait for the computation to end
}

アップデート

ループ内に関数 gameTree.buildGameTree(depth, root); があるため、これは解決策ではありません。それ自体が重要な締め切りよりも長くかかることがあります。

私の知る限り、そのような機能を外部から中断する方法はありません。この関数は、その状態を時々チェックする必要があります。ループの場合は、繰り返しの一部またはすべてで状態を確認することを検討してください。

于 2013-10-26T19:01:16.527 に答える