【问题标题】:Boolean Expression [closed]布尔表达式
【发布时间】:2010-09-21 21:55:37
【问题描述】:

如何用布尔逻辑表示 X 中的 Y 为真?像以下 2 条规则必须为真(A、B、C、D、E、F) 它是乘法还是集合运算的一种形式?
最终结果是所有排列,如 AB OR AC OR AD,如果你说 3 跟随它就像 ABC、ABD、ABE 等。所以它就像 (A,B,C)^2?

谢谢!

【问题讨论】:

    标签: boolean logic


    【解决方案1】:

    在布尔逻辑中(v 是 OR,谓词后面的 ' 是 NOT):

    A B C'D'E'F' v
    A B'C'D'E'F  v
    A'B C'D'E'F' v
    : : : : : :
    <absolute bucketload of boolean expressions>
    : : : : : :
    A'B'C'D'E F
    

    使用排列,您需要编写大量子表达式。

    当然,如果这是一个编程问题,您可以将布尔值转换为 0 或 1,将它们全部相加并确保结果为 2。

    【讨论】:

      【解决方案2】:

      假设 C# 或其他某种语言,其中 bool != int:

      bool nOf(int n, bool[] bs)
      {
          foreach(bool b in bs)
          {
            if((n -= b ? 1 : 0) <= 0) break;
          }
          return n == 0;
      }
      

      【讨论】:

        【解决方案3】:

        Python:

        expressions = [A, B, C, D, E, F, G ]
        numTrue = len(filter(None, expressions)
        

        PHP:

        $expressions = array(A, B, C, D, E, F, G);
        $numTrue = count(array_filter($expressions));
        

        【讨论】:

          【解决方案4】:

          你已经明白了。要表达“n 中的 k 个”,您将需要列举所有 k 的情况。所以,如果我们有变量 A B C D E,而你想要 3 of 5,你需要

          (A  &  B &  C & ~D & ~E) |
          (A  &  B & ~C &  D & ~E) |
          (A  &  B & ~C & ~D &  E) | ...
          (~A & ~B &  C &  D &  E)
          

          & 是“和”,|是“或”,~ 是“非”。

          【讨论】:

            【解决方案5】:

            假设“A 或更多”

            你可以通过建造一棵树做得更好

            2 : a&(b|c|d|e|f) | b&(c|d|e|f) | c&(d|e|f) | d&(e|f) | e*f
            3 : a&(b&(c|d|e|f) | c&(d|e|f) | d&(e|f) | e*f) | b&(c&(d|e|f) | d&(e|f) | e*f) | c&(d&(e|f) | e*f) | d&e&f
            

            或作为代码

            bool AofB(int n, bool[] bs)
            {
               if(bs.length == 0) return false;
               if(n == 0) return true;
            
               foreach(int i, bool b; b[0..$-n])
                  if(b && AofB(n-1,b[i+1..$]) return true;
            
               return false;
            }
            

            更好

            bool AofB(int n, bool[] bs)
            {
               foreach(bool b; bs) if(b && --n == 0) return true;
               return false;
            }
            

            【讨论】:

              【解决方案6】:

              我会数一数。 但是,如果您必须仅使用布尔运算生成谓词,那么您可以将输入视为加法器系统中的位。

              Basic Half-Adder
              
              A, B : 1st 2nd bits
              O, C : unit output and carry to next unit
              
              O := A xor B;
              C := A and B;
              

              您可以在 [Wikipedia][http://en.wikipedia.org/wiki/Half_adder (Half-Adder)] 找到更多示例和链接

              然后您可以将这六个变量分成 3 对,然后弄清楚如何使用这些输出来更接近答案并自己解决其余的问题。

              另一种选择是使用电路来查找弹出计数(横向添加)并检查是否唯一的位与 2 匹配。 组装而不是逻辑门的著名例子是 [Hakmem 169][http://home.pipeline.com/~hbaker1/hakmem/hacks.html#item169 (popcount)]。

              【讨论】:

                【解决方案7】:

                您的意思是“恰好两个必须为真”还是“至少两个必须为真”会有所不同。

                对于变量集 {A..F},Pax 和 Charlie Martin 的回答涵盖了“正好两个”的情况(两个为真,其余为假),而您问题中的表达式似乎处理“至少两个”的情况:

                (A && B) || (A && C) || ... || (D && E) || (D && F) || (E && F)
                

                是一个表达式,例如,当 A 和 B 为真且其余变量为任意值(真或假)时为真。

                如果您要求的是一个类似于集合论的表达式来描述上述情况,您可以这样表达:

                #{x | x <- {A, B, C, D, E, F} | x} = 2
                

                符号以这种方式工作的地方:

                #{...}
                

                表示封闭集合的大小,以及集合本身:

                {x | x <- {A, B, C, D, E, F} | x}
                

                读取“x 的集合,其中xAF 之一,x 为真”。换句话说,给定变量集AF,由具有真值的变量组成的子集正好有两个元素。 (使用 &lt;= 而不是 '=' 来表达对您问题的其他解释。)

                【讨论】:

                  猜你喜欢
                  • 2012-04-18
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-03-17
                  • 2015-04-29
                  • 2016-07-13
                  相关资源
                  最近更新 更多