问题
I have a ANTLR expression parser which can evaluate expressions of the form ( A & ( B | C ) ) using the generated visitor. A , B and C can take any of the 2 values true
or false
. However I am faced with a challenge of finding all combinations of A,B and C for which the expression is true. I tried to solve this by the following method.
- Evaluate the expression for the 3 variables taking true and false each
- This comes to 8 combinations since 2 ^ 3 is 8
- I evaluate giving values like 000, 001, 010 ....... 111 to the variables and evaluate using the visitor
Though this works this method becomes compute intensive as the number of variables increases. Hence for an expression with 20 variables 1048576 computations are required. How can I optimise this complexity so that I get all the true expressions ? I hope this falls under Boolean satisfiabilty problem
回答1:
It does. If you are liimted to 20-30 variables, you can simply brute force a trial of all the combinations. If it takes 100ns per try (that's 500 machine instructions), it will run in about 100 seconds. That's faster than you.
If you want to solve much bigger equations than that, you need to build a real constraint solver.
EDIT due to OP remark about trying to go parallel to speed up a Java program that brute forces the answer:
I don't know how you represent your boolean formula. For brute force, you don't want to interpret a formula tree or do something else which is slow.
A key trick is to make evaluation of the boolean formula fast. For most programming languages, you should be able to code the formula to test as an native expression in that language by hand, wrap it N nested loops and compile the whole thing, e.g.,
A=false;
do {
B=false;
do {
C= false;
do {
if (A & (B | C) ) { printf (" %b %b %b\n",A,B,C);
C=~C;
} until C==false;
B=~B;
} until B==false;
A=~A;
} until A==false;
Compiled (or even JITted by Java), I'd expect the innner loop to take 1-2 machine instructions per boolean operation, touching only registers or a single cachec line, plus 2 for the loop. For 20 variables thats around 42 machine instructions, even better than my rough estimate in the first paragraph.
If one insists, one could convert the outermost loops (3 or 4) into parallel threads, but if all you want are the print statements I don't see how that will actually matter in terms of utility.
If you have many of these formulas, it is easy to write a code generator to produce this from whatever representation you have of the formula (e.g., ANTLR parse tree).
来源:https://stackoverflow.com/questions/40938745/antlr-boolean-satisfiabilty