2

Xと0のゲーム(つまり、TIC TAC TOE(3X3))で、このためのプログラムを作成する場合は、コンピューターによって動きを生成するための高速な方法を提供します。つまり、これが可能な限り最速の方法であるはずです。

そのとき私が考えることができたのは、すべてのボード構成をハッシュに格納して、移動の最適な位置を取得することがO(1)操作になるようにすることだけです。
各ボードの正方形は、0、1、または2のいずれかになります
。0は空の正方形を表します。1はXを表し、2は0を表します。

したがって、すべての正方形は3つのいずれかで埋めることができます。約3^9のボード構成があります。

簡単に言うと、サイズ3^9のハッシュが必要です。ハッシュについては、ベース3の表現を使用できます。基数3の各数値は、各正方形に対応する各桁の長さが9桁になることを意味します。ハッシュで検索するには、この9桁の数値の10進表現を見つける必要があります。これで、各正方形を行番号と列番号に関連付けることができます。各正方形を一意に識別するために、ベース3の表現を再び利用できます。たとえば、SQ [1] [2]は基数3で12になり、10進数で5に相当します。

したがって、O(1)の次の動きを計算するのに十分高速なアルゴリズムを効果的に設計しました。

しかし、DOSシステムにはそれほど多くのメモリがないため、インタビュアーはスペースの複雑さを軽減することを主張しました。

時間の複雑さを変えずに、どうすれば空間の複雑さを減らすことができますか?
今後、このような質問を見逃さないように、私を助けてください。

4

4 に答える 4

3

このような小さなゲームの場合、別の方法として、潜在的なゲーム ツリーを事前に計算してテーブルに格納します。

まず人間がスタートする状況を見ると、彼女は明らかに 9 つの異なるスタート位置を持っています。ゲームプレイ テーブルには 9 つのエントリ ポイントが含まれ、それぞれが正しい応答を指しています。この質問で概説されているガイドラインを使用して応答を計算できます。また、人間の応答の次のレベルのテーブルも使用できます。今回は、可能な応答は 7 つだけです。次のレベルでは、5、次に 3、そして 1 になります。合計で、テーブルには 9 * 7 * 5 * 3 * 1 = 945 のエントリがありますが、対称性、つまり回転を実現することで圧縮できます。反転した色。

もちろん、コンピューターが開始する状況は原理的には似ていますが、コンピューターはおそらく中央の曲を再生することから開始するか、少なくとも特定のスポットを避けたいため、テーブルは実際には小さくなります。

于 2012-06-15T21:20:30.190 に答える
1

3^9 の異なるボード構成はありません。tomdemuyt が言うように、9 つあります。つまり、最初に 9 つの選択肢、次に 8 つの選択肢、その後に 7 つの選択肢、というように。

また、対称性を考慮することで、空間の複雑さをさらに軽減できます。たとえば、最初の手の場合、X を [0,0] に配置することは、[0,2]、[2,0]、および [2,2] に配置することと同じです。私はこれが9を減らすと信じています!9まで!/4

最終的な動き (9 回目の動き) の前にどのボード構成が勝っていたかを考慮することで、それを減らすことさえできます。番号はわかりませんが、詳細な説明は Stack Overflow のいとこhttp://en.wikipedia.org/wiki/Tic-tac-toeにあります。

于 2012-06-15T21:11:53.083 に答える
0

3^9の仮定は間違っています。これには、たとえば、両方のプレーヤーが各ターンにXまたはOを配置するため、不可能なXのみを持つボードが含まれます。

私の最初の考えは、(9 * 8 * 7 * 6 * 5 * 4 * 3 * 2)*2つの可能性があるということでした。最初のプレーヤーには9つの選択肢があり、2番目のプレーヤーには8つの選択肢があり、最初のプレーヤーには7つの選択肢があります。

現在、3 ^ 9は19863と9です!は362880であるため、これは明らかに優れたソリューションではありません。多くの「異なるシナリオ」は、実際にはまったく同じように見えます。それでも、19863ボードのセットアップの多くが無効であるという基本的な考えは残っています。

おそらく単純な数式で置き換えることができるこのコードは、これが移動したい位置の数であることを示しています。

<script>

a = permuteString( "X........" ); document.write( Object.keys(a).length + "<br>" );console.log( a );
a = permuteString( "XO......." ); document.write( Object.keys(a).length + "<br>" );console.log( a );
a = permuteString( "XOX......" ); document.write( Object.keys(a).length + "<br>" );console.log( a );
a = permuteString( "XOXO....." ); document.write( Object.keys(a).length + "<br>" );console.log( a );
a = permuteString( "XOXOX...." ); document.write( Object.keys(a).length + "<br>" );console.log( a );
a = permuteString( "XOXOXO..." ); document.write( Object.keys(a).length + "<br>" );console.log( a );
a = permuteString( "XOXOXOX.." ); document.write( Object.keys(a).length + "<br>" );console.log( a );

//Subset of the Array.prototype.slice() functionality for a string
function spliceString( s , i )
{
    var a = s.split("");
  a.splice( i , 1 );
    return a.join("");
}

//Permute the possibilities, throw away equivalencies
function permuteString( s )
{
    //Holds result
    var result = {};

    //Sanity
    if( s.length < 2 ) return [];

    //The atomic case, if AB is given return { AB : true , BA : true }
    if( s.length == 2 )
    {
        result[s] = true;
        result[s.charAt(1)+s.charAt(0)] = true;
        return result;
    }

    //Enumerate
    for( var head = 0 ; head < s.length ; head++ )
    {
        var o = permuteString( spliceString( s , head  ) );
        for ( key in o )
            result[ s.charAt( head ) + key ] = true;
    }
    return result;
}


</script>

これにより、次の数値が得られます。1番目の動き:9 2番目の動き:72 3番目の動き:252 4番目の動き:756 5番目の動き:1260 6番目の動き:1680 7番目の動き:1260

したがって、合計5289の動きで、これはすでに終了したゲームや対称性をチェックすることさえありません。

これらの数値を使用すると、配列内の動きを検索できます。可能なすべてのゲームをループすることで、この配列を自分で生成できます。

T。

于 2012-06-15T20:53:38.627 に答える
0

Tic Tac Toe のゲームは十分に単純なので、Tinker Toys (スティックとファスナーのブランド) から構築されたマシンによって最適なアルゴリズムが実装される可能性があります。このような構造によってカプセル化されたハードウェアの複雑さのレベルは、典型的な 1970 年代のマイクロプロセッサよりも低いため、ほとんどの場合、どの動きが行われたかを見つけるのに必要な時間は、次の動きを理解するのに必要な時間を超えます。おそらく最も単純なアプローチは、特定のプレーヤー (2^9、または 512 エントリ) のマーカーの有無に応じて、2 列が 3 列に変わる正方形を示す表を作成することです。行。移動中のプレーヤーが所有するピースを検索することから始めます。スリーインアラインを完了する正方形が対戦相手に取られなかった場合は、それを取ります。それ以外の場合は、対戦相手の駒の組み合わせを調べます。まだ占有されていないことが判明した正方形を取得する必要があります。それ以外の場合は、センターが利用可能な場合はそれを取ります。中央だけを取る場合は、角を取ります。それ以外の場合は、エッジを取ります。

質問を 4x4x4 Tic Tac Toe に広げる方が興味深いかもしれません。これは、1970 年代のコンピューターの実装では、多くの場合、1 回の移動に数秒かかることがある十分なレベルの複雑さを表しているからです。今日のコンピュータは、たとえば Atari 2600 よりも何千倍も高速ですが、計算のレベルは少なくとも些細なことではありません。

ゲームを 4x4x4 に拡張すると、速度、RAM、およびコード スペースをトレードオフする多くの可能性があります。8 つの勝利ラインがある元のゲームとは異なり、4x4x4 バージョンには (IIRC) 76 があります。各ラインが 8 つの状態のいずれかにあることを追跡すると [1 つが勝利をカウントする場合は 10]、各空いている正方形について 1 つが追跡されます。それを通過する勝者ラインのうち何本がどの状態にあるか、その情報に基づいて非常に高速なヒューリスティックを定式化できるはずです。ヒューリスティックが実際に勝つことを確実にするために、おそらく徹底的な検索アルゴリズムを使用する必要がありますが、ヒューリスティックが検証されると、徹底的な検索よりもはるかに高速に実行できるはずです。

于 2014-04-20T21:35:25.350 に答える