web-dev-qa-db-ja.com

演算子が任意である方程式のすべての可能な解決策?

このようなものを考えると:

1 5 3 4 = 18

18になる演算子と角かっこの組み合わせがあるかどうかを(アルゴリズムを使用して)判断する必要があります。「+」と「*」および「(」と「)」のみが許可されます。

例:

1 + 5 +(3 * 4)= 18

ブルートフォースのほかに、妥当な時間ですべての可能なコンボを計算できる特定のアルゴリズムはありますか? RPNは、考えられる解決策をエンコードするのに役立つ場合がありますが、同じことがたくさんあります(4 ^ n?)。

5
incognita

無意味な計算を避ければ、ブルートフォースは実際には非常に高速です。

最悪の場合、2 ^(N-1)演算子とN!(N-1)!があります。 N-1演算の数値のペアを選択する方法。したがって、たとえば、N = 4の場合、これにより1,152の可能性が得られます。

ただし、これを大幅に削減できます。6+ 2と6 * 2を確認する場合は、2 +6と2 * 6を確認する必要はありません。最初に大きい数値を実行するだけです。これは2 ^(N-1)の因数を取り、可能性の数をN!(N-1)!に下げるので、N = 4の場合は144になります。

(20 + 6)+2は20+(6 + 2)と同じであるため、さらに節約できる可能性がありますが、Nが大きくなるまで、これを最適化する価値はないのではないかと思います。もう1つは、1を掛けてもあまり役に立たないということです。この種のことは、N = 4の場合は節約にならないかもしれませんが、たとえば除算も検討している場合はそうです(特に、小さい数がの因数または除数でない場合)。あなたがそれからたくさんの可能性を取り除くことができるので、より大きな数)。目標を超えたときに停止するというrzzzwilsonの提案も同様に機能しますが、すべての演算が減少しない場合にのみ機能します(つまり、加算と乗算であり、減算や除算ではありません)。

同様の例として、 my old Java applet 、6つの数値と4つの演算子を使用してみてください。独自の数値とターゲットをボックスに入れることができます。きれいにプログラムされていませんが、それでもかなり速いです。

5
Henry

興味深い問題。

私はコードを書いていませんが、ここに私の考えがあります。少しの「剪定」で、ブルートフォースを超えたアプローチを考えることができませんでした。

RPN表現を使用すると、ブラケットの処理が簡単になります(そのため、ブラケットはなくなります)。あなたの例を使用すると、RPNは15です。 3。 4。ここですべての「。」右端の「。」を除いて、演算子mightが存在する場所です。 RPNであるため、1つ以上の演算子が必要であることがわかっています。ほかのすべての '。'演算子が0個以上あります。もちろん、N値の場合、N-1演算子が必要です。

ここで、問題は次の部分に分かれます。1。N-1演算子(2 ^ N)のすべての組み合わせを生成します。2。演算子の組み合わせごとに、演算子点「。」のすべての「塗りつぶし」を生成します。つまり、演算子リストを次のようにグループ化します。 1s、2s、...、N-1s、演算子の順序を維持します(私の組み合わせ論-fuは弱いので、これを理解できません)3。組み合わせの組み合わせごとに、式を評価します。

剪定は最後のステップで行われます。評価時に、式の値が目的の結果を超える場合は、式の値を減らす可能性のある演算子がないため、失敗して停止します。

2
rzzzwilson

この問題はNP完全であるため、O(n!)未満で解決できるとは期待できません。ただし、すべてのNP完全問題と同様に、もちろん、18に近づくアルゴリズムを概算することも、18になる演算子を使用して同様の数値のリストを生成することもできます。

0
Neil