주어진 입력이 하나의 리프에만 나타날 수 있다고 가정합니다. 그렇지 않으면 트리 구조와 제한된 연산자에도 불구하고 De Morgan의 법칙에 따라 boolean satisfiability이 다시 생깁니다.
데이터 구조가 없으면 대답을 계산할 수 있다고 생각합니다. 결국 솔루션을 열거 할 필요가 없습니다. 재귀 단계에는 두 개의 매개 변수가 필요합니다 : 처리 할 노드와 해당 노드가 생성하는 대상 출력이 있으며 두 값을 반환합니다 : 노드의 대상을 얻는 방법의 수와 아래의 총 수 노드 이 두 가지 방법은 트리를 가로 지르는 깊이 우선 탐색을 통해 얻을 수 있습니다. NOT 작업의
(int ways, int leaves) = recurse(Node n, bool target) {
//Base case of recursion:
if(n.type == LEAF) {
return (1, 1);
}
else if(n.type == NOT) {
//for a NOT, we just invert the target.
return recurse(n.child[0], !target)
}
else if (n.type == AND) {
//AND is more complicated. First, count the ways that we can make each
//sub-expression evaluate to true, and the total number of leaves under
//both the left and right child:
(int left_true, int left_leaves) = recurse(n.child[0], true);
(int right_true, int right_leaves) = recurse(n.child[1], true);
//the total number of ways to make a true AND result is the product of
//the number of ways to make the left true, and the number of ways to
//make the right true.
int total_true_ways = left_true * right_true;
//the total number of leaves under this node is the sum of leaves under
//the left and right subtrees.
int total_leaves = left_leaves + right_leaves;
if(target == true) {
//if this node's target is 'true' we've already computed the number of
//ways to satisfy that.
return (total_true_ways, total_leaves);
}
else {
//The number of ways to make a 'false' is the total number of possible
//input combinations, less the number of input combinations that make
//a 'true'.
//The total number of possible input combinations is given by 2 to the
//power of the number of boolean inputs, which is given by the
//number of leaves below the node:
int num_possible_inputs = pow(2, total_leaves);
return (num_possible_inputs - total_true_ways, total_leaves);
}
}
else {
throw internal error
}
}
당신의 나무를 배제하지 않기 때문에 불행하게도, 실행 시간이 엄격하게 잎의 숫자로 표현 될 수없는 임의의 길이의 체인 :
여기에 아이디어와 의사 코드의 . back-to-back NOT 사지가 없다고 가정하면, NOT과 AND의 레이어를 번갈아 가며, 2*ciel(log_2(n)+1)
개의 레이어와 2n + 2(n-1)
개의 노드가있는 트리로 이어지는 최대 심도 트리를 얻을 수 있습니다. (여기서 n
은 리프 노드의 수입니다.) 따라서 각 노드를 한번 만나는 깊이 우선 탐색은 연속적인 NOT 연산자가 없다는 가정하에 O(n)
에서 실행됩니다.
문제 설정에서 단일 리프 노드에서만 사용할 수있는 "입력"입니까? 즉, 부울 식에서 주어진 입력을 두 번 이상 사용할 수 없습니까? – lockcmpxchg8b