布尔表达式到阈值表达式

时间:2017-02-25 08:06:09

标签: java

我正在寻找一种将Boolean表达式转换为threshold表达式的可能方法。

例如,我得到了boolean表达式:

((A & B)|(C & D)) | ((A | B) & (C | D))

它实际上意味着从以下集合中选择任意两个:

 {A,B,C,D}

如果我们使用阈值表达式,我们可以将其表示为:

A,B,C,D 2outof4

但我找不到办法让这项工作。

有可能的方法吗?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~

实际上,我想知道的是:

给出一个布尔表达式,如:

((A & B)|(C & D)) | ((A | B) & (C | D))

是否可以识别表达式实际上是从集合中选择2个元素{A,B,C,D}

然后输出类似

的内容
A,B,C,D 2outof4

2 个答案:

答案 0 :(得分:0)

您可以使用Streamfilter,然后使用count元素

if (Stream.of(A, B, C, D).filter(x -> x).count() >= 2)

答案 1 :(得分:0)

好的,总而言之,您要确定布尔表达式是否为组合生成器。

我相信下面列出的代码可以实现这一目标。您可以看到它包含一个与您的示例结构相同的表达式:

or(
    or(
        and(value("A"), value("B")),
        and(value("C"), value("D"))
    ), and(
        or(value("A"), value("B")),
        or(value("C"), value("D"))
    )
);

然后用作DSL来生成组合:

{A,B}
{A,C}
{A,D}
{B,C}
{B,D}
{C,D}

然后检查生成的组合以查看它们是否满足以下条件:

  1. 每组必须具有相同的长度 - 称之为 r
  2. 确定集合中包含的唯一值(例如" A"," B"等)的超集大小,称之为 N
  3. 集合的数量是否等于二项式(N,r) - 从 N 中选择 r 值的方式的数量。< / LI>

    如果组合满足这些要求,那么布尔表达式必须是从 N 中选择 r 值的生成器。

    最后一行输出是:

    Optional[{A,B,C,D} 2 of 4]
    

    表示表达式是一个用于从4中选择2个值的生成器。

    以下是完整的实施:

    import java.util.*;
    
    import static java.util.Collections.singleton;
    import static java.util.stream.Collectors.joining;
    import static java.util.stream.Collectors.toSet;
    
    class Combinations {
    
        static <T> Set<T> union(Collection<T> lhs, Collection<T> rhs) {
            final Set<T> result = new HashSet<>(lhs);
            result.addAll(rhs);
            return result;
        }
    
        static <T> String collToString(Collection<T> l) {
            return l.stream()
                .map(Object::toString)
                .collect(joining(",", "{", "}"));
        }
    
        static <T> Set<Set<T>> value(T value) {
            return singleton(singleton(value));
        }
    
        static <T> Set<Set<T>> or(Set<Set<T>> lhs, Set<Set<T>> rhs) {
            return union(lhs, rhs);
        }
    
        static <T> Set<Set<T>> and(Set<Set<T>> lhs, Set<Set<T>> rhs) {
            return lhs.stream()
                .flatMap(ls -> rhs.stream().map(rs -> union(ls, rs)))
                .collect(toSet());
        }
    
        static class Choose<T> {
            private static int binomial(final int n, final int r) {
                int ret = 1;
                for (int k = 0; k < r; k++) {
                    ret = ret * (n-k) /(k+1);
                }
                return ret;
            }
    
            static <T> Optional<Choose<T>> of(Set<Set<T>> sst) {
                final Set<Integer> sizes = sst.stream().map(Set::size).collect(toSet());
                if (sizes.size() != 1) {
                    return Optional.empty();
                } else {
                    final int r = sizes.iterator().next();
                    final Set<T> values = sst.stream().flatMap(Set::stream).collect(toSet());
                    final int n = values.size();
                    final int ncr = binomial(n, r);
                    if (sst.size() == ncr) {
                        return Optional.of(new Choose<>(values, r));
                    } else {
                        return Optional.empty();
                    }
                }
            }
    
            public final Set<T> values;
    
            public final int r;
    
            Choose(Set<T> values, int r) {
                this.values = values;
                this.r = r;
            }
    
            @Override
            public String toString() {
                return collToString(values) + " " + r + " of " + values.size();
            }
        }
    
        public static void main(String[] args) {
            // Generate the combinations.
            final Set<Set<String>> combos =
                or(
                    or(
                        and(value("A"), value("B")),
                        and(value("C"), value("D"))
                    ), and(
                        or(value("A"), value("B")),
                        or(value("C"), value("D"))
                    )
                );
    
            // Print the combinations to stdout.
            combos.stream()
                .map(ss -> collToString(ss))
                .forEach(System.out::println);
    
            Optional<Choose<String>> choose = Choose.of(combos);
            System.out.println(choose);
        }
    }