2011-07-24 2 views
4

数独ボードを生成するためのアルゴリズムを書いていますが、失敗しています。私はthisに基づいてそれを書いていますが、私はこれに遭遇する前に多くのコードを書いていたので、それは異なります。数独ボードを生成するためのバックトラッキングアルゴリズムのヘルプが必要

コード

私はmatrixと呼ばれる値を保持するための設定多次元配列を持っています。 matrixは、行である9つの配列で構成され、それぞれが9つの列を保持します。 generatePossibleNumbersArray()matrixのように正確に多次元配列を作成するためだけのヘルパー関数です

var populateMatrix = function() { 
    var possibles = generatePossibleNumbersArray(); 
    var found = false; 
    for(var i=0; i< matrix.length; i++) { 
     for(var j=0; j< matrix[i].length; j++) { 
      while(possibles[i][j].length > 0) { 
       var rnd = Math.floor(Math.random() * possibles[i][j].length); 
       var num = possibles[i][j].splice(rnd, 1)[0]; 
       if(isValid(i, j, num)) { 
        matrix[i][j] = num; 
        found = true; 
        break; 
       } else { 
        found = false; 
        continue; 
       } 
      } 
      if(!found) { 
       possibles[i][j] = [1,2,3,4,5,6,7,8,9]; 
       j -= 2; 
      } 
     } 
    } 
} 

:だから私はすべての正方形を解決するための

matrix[3][6]; 

機能を使用することになり、行4列7の値を取得しますただし、各セルの整数1〜9の配列を保持するように初期化されています。 populateMatrix()機能の間、これらの可能な数字は各セルごとに縮小されます。

問題

j-1されて終わるので、それは行列を毎回完了する前に失敗しました。これは、より多くのセルが解決されるにつれて、アルゴリズムがセルの値を見つけ出してバックトラックするのがより困難になるからです。しかし、それは最終的にj == -1まで戻ってバックトラッキングを終わります。

私は本当にこのアルゴリズムが働くだろうと思って、私はこのまわりで私の頭を取得しようとしているすべての一日を過ごしてきましたが、私は誰もがこれに当てる可能性のある光は非常に高く評価されるだろうので困惑しています。

「私が知っていると思うと、私は数独を解決するためのjavascript関数を書いていきます。それはどれくらい難しいでしょうか? "私は間違っていた。


@ Steve314によってコメントに基づいて、[ソリューション]

(彼は今削除しています!)私はif(!found) { ...matrix[i][j] = undefinedを追加し、アルゴリズムが機能するようになりましたし、高速軽量化されます。

興味があれば、complete codeです。

+0

したがって、コードは適切な時間内に行列を解くか、または解きませんか? –

+0

@Joãoループカウンタ「j」が「-1」になり、 'matrix [i] [j]'が未定義になるため、コードは失敗します。 – MrMisterMan

+0

これは正常ではありませんか?それは、あなたが行き詰まったと言っているようなものです。以前のポジションは有効な値で埋めることができますが、現在のポジションを埋めることは不可能です。だから、あなたは前の充満した位置に行き、そこで次の有効な値を続けることを試みるべきです。 –

答えて

3

通常、バックトラッキングアルゴリズムは、分岐が失敗した場合に状態を復元し、次の可能な移動を行います。したがって、フィールドのランダムな塗りつぶしが失敗したブランチを作成した場合、最初に元のものを書き戻すだけです。

+0

これはバックトラッキングアルゴリズムのすべての種類の私の最初の試みですので、私はまだ少し混乱しているので、ダンスのリンクをチェックしたいかもしれません。私のコードのどの部分を元の場所に書き戻すことを検討すべきですか? – MrMisterMan

+0

くそー - 私は問題を混乱させていると思う - コメントが削除された。 – Steve314

+0

@ Steve314はちょうど2つのアプローチについて説明しました。再帰的には、関数はブール値を返し、フィールドに値を入力した後に自分自身を呼び出し、それが失敗した場合はfalseを返します。それが本当に戻ってきた場合は、すでに解決策があります。それらをすべて探していれば、それを復元して継続することができます...スタックのためにスタックを必要とすることは明らかです。バックトラックを学ぶだけでその解決策を回避できます。ところで、あなたはあなたがスキャンしなければならない葉(枝)の数を計算しましたか? –

関連する問題