2012-03-14 22 views
1

私はチェスのようなゲームのAIを8 x 8グリッド上の2つのタイプのピースに基づいてプログラミングしています。このJavaツリーはどのように1000倍高速化できますか?

私はゲームでの可能な移動を表すminmaxツリーの種類を作りたいと思っています。白いプレイヤーが最初にプレイし、黒いプレイヤーが2番目にプレイしました。

私はこの呼び出しを再帰的に呼び出すgenerate()メソッドを持っています。私は可能な動きの約8レベルを表示することができる必要があります。最適化がなければ、この3つは8^8リーフです。

私は、グリッドが実際に計算されたかどうかを判断する単純なシステムを実装しました。そのシステムでは、計算された子参照を子が指すだけです。

私は私の説明が明確であるならば、私はあなたが理解することができるはずのコードの一部に参加するかわかりません。

実際には、私はすべての可能性の約3または4レベルを生成することができます。私はこれまで私が5秒未満でそれを計算できるようにしたいと思います8.

..

だから、みんなの思い、あなたは私のアルゴリズムを最適化するためのソリューションを見ていますか?

これはgenerate関数です。leftDiagonalMove()、rightDiagonalMove()およびfrontMove()は、移動が不正である場合はfalseを返し、移動が合法である場合はグリッド内のピースを移動してtrueを返します。

クローン()、それの「親」の同じプロパティを持つ新しいインスタンスを作成し、backMove()戻ったばかりの最後に移動するステップ。

public void generate(Node root, boolean white, int index) { 

    Grid grid = root.getGrid(); 

    Stack<Piece> whitePieces = grid.getPiecesByColor(WHITE); 
    Stack<Piece> blackPieces = grid.getPiecesByColor(BLACK); 
    Node node; 

    String serial = ""; 
    // white loop 
    for (int i = 0; i < whitePieces.size() && white; i++) { 
     Piece wPiece = whitePieces.get(i); 

     if (grid.leftDiagonalMove(wPiece)) { 
      serial = grid.getSerial(); 
      if(!allGrids.containsKey(serial)){ 
       node = new Node(grid.clone()); 
       node.setMove(grid.getLastMove()); 
       root.addChild(node); // add modified grid 
       allGrids.put(serial, node); 
       //actualGrid.display(); 
       if (index < 5 && grid.getPosition(wPiece).x > 0) 
        generate(node, !white, index + 1); 
       actualGrid.backMove(); // back step to initial grid 
      } 
      else{ 
       root.addChild(allGrids.get(serial)); 
      } 
     } 

     if (grid.frontMove(wPiece)) { 
      // same code as leftMove 
     } 

     if (grid.rightDiagonalMove(wPiece)) { 
      // same code as leftMove 
     } 

    } 

    // black loop 
    for (int i = 0; i < blackPieces.size() && !white; i++) { 
     Piece bPiece = blackPieces.get(i); 

     if (grid.leftDiagonalMove(bPiece)) { 
      // same code as white loop and replacing wPiece by bPiece 
     } 

     if (grid.frontMove(bPiece)) { 
      // same code as white loop and replacing wPiece by bPiece 
     } 

     if (grid.rightDiagonalMove(bPiece)) { 
      // same code as white loop and replacing wPiece by bPiece 
     } 

    } 

} 
+1

アプリケーションのプロファイルを作成するときに、ほとんどの時間を費やすのは何ですか? –

+0

これにニューラルネットワークを使用してみませんか? – formatc

+1

私が気づく一つの事は、あなたが 'ArrayList'からそれを引っ張っているたびに新しいオブジェクトを再作成することです。ピースの宣言をループ外に移動すると、メモリのフットプリントが削減され、ランタイムがいくらか改善されます。それ以外の場合は、Javaコードプロファイラを使用して、コードがどこからどのような理由で呼び出されているかを確認する方が良いでしょう。 – Makoto

答えて

3

あなたは動きのあなたの生成MinMax treesAlphaBeta pruningと呼ばれるものを使用する必要があります。ここでは、この上の詳細: http://en.wikipedia.org/wiki/Alpha-beta_pruning
http://www.progtools.org/games/tutorials/ai_contest/minmax_contest.pdf

は、基本的には、分岐の1つのレベルを行い、その後、あなたが早期に悪い枝を取り除く剪定使用します。次に、削除されていないブランチから、それぞれ別のレベルを計算します。あなたは望みの深さに達するまで、もう一度剪定します。この1つはチェスのゲームのための剪定を最適化することにある

2. MinMax trees - when Min can win in two steps


1. http://en.wikipedia.org/wiki/Alpha-beta_pruning#Heuristic_improvements
2ここで

あなたはMINMAX上に読むことのために、いくつかのより多くのリンクありhttp://en.wikipedia.org/wiki/Refutation_table#Related_techniques

+0

しかし、悪い枝を取り除くことによって、私はすべての可能性を計算しませんか? –

+0

@ Pier-alexandreBouchardもしあなたが失った支部で外出することを知っていたら、なぜあなたは失った動きを計算したいのですか?この孤独は早い段階で悪い枝を切る(私はあなたがすべての動きを見つけ出すことではなく、良い動きに興味があると思った)。 – Adrian

+0

あなたは正しいです。私はあなたの文書を読むでしょう。 –

0

要素にランダムアクセスするときにスタックを使用する理由がわかりません。低レベルでは、代わりにPiece []配列を使用することで改善が得られます。

関連する問題