私は数独ソルバーに取り組んでいます。現在のソルバーはバックトラッキングアルゴリズムを使用していますが、それでも時間がかかりすぎます。
ほとんどの場合、1秒未満に短縮したいと思っています。そのため、ダンスリンクアルゴリズムを使用して書き直すことにしました。これは、特に数独パズルなどの制約問題でうまく機能する、より優れたブルートフォース手法の1つであることを理解しています。
私はWikiと Knuthの論文 を読んでみましたが、どちらも理解するのが少し難しく、非常に冗長です。
数独のバージョンも読んだのですが、数独の実装になると抽象的になりすぎたようです。
誰かがDancingLinksアルゴリズムをその派生ではなく、その実装の観点から説明しようとすることはできますか? (例として数独を使用すると素晴らしいでしょう)
ありがとう!
あなたは興味があるかもしれません javascriptでの私の実装 。
まず、正確なカバーを理解する必要があります。正確なカバーの問題は、多数の選択肢が与えられ、一連の制約があり、すべての制約を1回だけ満たす一連の選択肢を選択することが課題である問題です。
たとえば、誰かがアイスダンスのルーチンを作成している場合を考えてみましょう。彼らはジャッジに見せるために必要な多くのトリックを持っており、トリックを2回以上実行したくない。それらには、まとめることができるトリックのグループであるシーケンスがいくつかあり、すべてのトリックを一度にカバーするための理想的なシーケンスの選択を選択したいと考えています。この例では、すべてのトリックを実行する必要があるという制約があります。選択肢は、ルーチンに組み込むことができる可能なシーケンスです。
この種の問題を表す良い方法は、制約が列で選択肢が行であり、特定の選択肢がその制約を満たすセルに大きなXがあるテーブルを描画することです。
結局のところ、適切な制約と選択があれば、数独は正確なカバーの問題として説明できます。
さて、あなたがそれを持っていると仮定すると、今あなたはアルゴリズムXを理解する必要があります。クヌースはそれについて言いました。「アルゴリズムXは単に明白な試行錯誤のアプローチのステートメントです。一般的に、仕事をする方法。)」。だからここにアルゴリズムXの私の説明があります:
これを理解したので、ダンスリンクを理解できます。 Dancing Linksは、そのアルゴリズムを効率的に実装する方法です。リンクを踊る上で重要な点は、リンクリストでノードを削除すると(隣接するノードのポインターを変更することで効率的に実行できます)、削除したノードには、追加するために必要なすべての情報が含まれていることです。リンクリストに(それが解決策の一部であると推測したときに間違っていたことが判明した場合)。これに加えて、すべてのリンクリストを循環させると、突然多くの特殊なケースが失われるという事実は、ほとんどすべてのダンスリンクです。
この質問は非常に古いものですが、私は次のように付け加えたいと思いました。
このページでは、アルゴリズムを非常に理解しやすくしています: Zendoku writeup 。そのリンクでそれについて読むまで、これは超高度なアルゴリズムであるに違いないと思っていましたが、実際に視覚化できれば、それは本当に独創的ですが単純な解決策です。
また、 私の実装 C#ではかなり読みやすいはずです...さまざまなクラスをさまざまなファイルに分割するのに役立つと確信しています。
これは主にKnuthのpdfからの直接の実装ですが、いくつかのオブジェクト指向の最適化があります(実際、数か月前にこれを行ったので、pdfからどれだけ外れたかはよく覚えていません)