long[]
配列内のビットとして保存された真/偽の結果がたくさんあります。私はこれらの膨大な数を持っています(何百万ものロング)。
たとえば、結果が 5 つしかない場合、次のようになります。
+----- condition 5 is true
|
|+---- condition 4 is false
||
||+--- condition 3 is true
|||
|||+-- condition 2 is true
||||
||||+- condition 1 is false
10110
次のようなステートメントを表すツリーもいくつかあります。
condition1 AND (condition2 OR (condition3 AND condition 4))
木はとてもシンプルですが、とても長いです。それらは基本的に次のようになります (以下では、私が持っているものを示すために単純化しすぎています)。
class Node {
int operator();
List<Node> nodes;
int conditionNumber();
}
基本的に、Node がリーフであり、条件番号 (long[] 配列のビットの 1 つに一致) を持つか、Node がリーフではないため、いくつかのサブノードを参照します。
シンプルですが、複雑なブール式を表現できます。それはうまくいきます。
これまでのところ、すべてがうまく機能しています。ただし、問題があります。多くの式を評価して、それらが真か偽かを判断する必要があります。基本的に、ブルートフォースよりも優れた解決策がわからない問題に対して、ブルートフォース計算を行う必要があります。
そのため、ツリーをたどってtrue
、false
ツリーの内容とlong[]
.
最適化する必要があるメソッドは次のようになります。
boolean solve( Node node, long[] trueorfalse ) {
...
}
ここで、最初の呼び出しでnode
は がルート ノードであり、次に明らかにサブノードです (再帰的であるため、そのsolve
メソッドはそれ自体を呼び出します)。
少数の木 (おそらく最大で 100 程度) しかなく、何百万ものツリーlong[]
をチェックすることを知っている場合、これを最適化するためにどのような手順を実行できますか?
明らかな再帰的な解決策は、パラメーター ((サブ) ツリーと long[]、パラメーターとして渡さないことで取り除くことができlong[]
ます) を渡し、すべての再帰呼び出しなどで非常に遅くなります。 (AND または OR または NOT など) が使用され、非常に多くの if/else または switch ステートメントが含まれます。
私は別のアルゴリズムを探しているわけではありません (存在しません) ので、y が x よりも小さい O(x) から O(y) に移動することを探していません。
私が探しているのは、「x 倍」のスピードアップです。5 倍速く実行されるコードを記述できれば、5 倍のスピードアップが得られ、それで十分であり、非常に満足しています。
現時点で私が見ている唯一の拡張機能は、現在のものと比較して「x」倍の大幅な高速化になると思いますが、すべてのツリーのバイトコードを生成し、すべてのツリーのロジックをクラスにハードコーディングすることです。 . 100本ほどの木しかないので、うまくいくはずです(ただし、木は固定されていません。木がどのように見えるかを事前に知ることはできません。そうでなければ、すべての木を手動でハードコーディングするのは簡単です)。
すべてのツリーのバイトコードを生成する以外に何か考えはありますか?
バイトコード生成ルートを試してみたい場合は、どうすればよいですか?