在二叉树中将 AND 分配给 OR(合取范式)

2023-11-30

我正在尝试转换二叉树,例如

OR (Implementation of Operator - a specialisation of TreeNode... see below)
|-A (Implementation of TreeNode... see below)
|-OR
  |-B
  |-AND (Implementation of Operator - a specialisation of TreeNode... see below)
    |-C
    |-OR
      |-D
      |-E

转换成其等效的联合范式(CND)表示形式。我相信,因为我只使用逻辑 OR + AND 运算符,所以我必须执行的唯一步骤是将 AND 分配给 OR。这将在 CNF 中生成以下树(对于我的目的来说仍然是二进制的):

AND
|-OR
| |-A
| |-OR
|   |-B
|   |-OR
|     |-E
|     |-D
|-OR
  |-A
  |-OR
    |-B
    |-OR
      |-E
      |-C

我在创建算法来执行此操作时遇到问题...到目前为止,我有以下骨架,它将自下而上地重写树(注意重构的递归调用):

public TreeNode reconstruct(TreeNode treeNode) {
  if(treeNode instanceof Operator) {
    TreeNode left = reconstruct(((Operator)treeNode).getLeft());
    TreeNode right = reconstruct(((Operator)treeNode).getRight());

    return distribute(treeNode, left, right);
  }
  else
    return node;
}

使用类:

 -----------
|  TreeNode | // Interface
 -----------
      ^
      |
 -----------
| Operator  | // Interface
 -----------
| getLeft() |
| getRight()|
| setLeft() |
| setRight()|
 -----------

有人可以建议一个将转换为 CNF 的 distribution 的实现吗?

// 编辑1(在nif回答之后)

private Node distribute(TreeNode node, TreeNode left, TreeNode right) {
  if (node instanceof Or) {
    if (left instanceof And) {
      // distribute right over left AND
      return 
        new And(
          new Or(((Operator)left).getLeft(), right),
          new Or(((Operator)left).getRight(), right)
        );
    } 
    else if (right instanceof And) {
      // distribute left over right AND
      return 
        new And(
          new Or(((Operator)right).getLeft(), left),
          new Or(((Operator)right).getRight(), left)
        );
    }
  }
  if(node instanceof Operator) {
    ((Operator)node).setLeft(left);
    ((Operator)node).setRight(right);
  }
  // default
  return node;
}

If AND and OR是您使用的唯一运算符,将您的树转换为 CNF 应该不难。您所要做的就是找到以下形式的结构OR(AND(X,Y), Z) or OR(Z, AND(X,Y))并利用分布律。

private static TreeNode distribute(TreeNode n, TreeNode left, TreeNode right) {
  if (n instanceof Or) {
    if (left instanceof And) {
      // distribute right over left AND
      return new And(new Or(left.getLeft(), right), 
                     new Or(left.getRight(), right));
    } else if (right instanceof And) {
      // distribute left over right AND
      return new And(new Or(right.getLeft(), left), 
                     new Or(right.getRight(), left));
    }
  }

  // no change
  return treeNode;
}

该算法必须应用于树的所有节点,直到树不再改变。将算法应用于节点的顺序并不重要。直观地说,重复应用该算法将pull up all AND节点超过OR节点,直到树处于 CNF 中。

TreeNode root = ....;
while (true) {
  TreeNode transformedRoot = reconstruct(root);
  if (root.equals(transformedRoot)) {
    break;
  }
  root = transformedRoot;
}
// root is now in CNF

Note:请注意,CNF 变换可能会使您的树的大小呈指数级增长。所示的实现非常原始,没有使用任何增强功能来减少计算时间。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在二叉树中将 AND 分配给 OR(合取范式) 的相关文章

  • Hashmap并发问题

    我有一个哈希图 出于速度原因 我希望不需要锁定 假设我不介意过时的数据 同时更新它和访问它会导致任何问题吗 我的访问是获取 而不是迭代 删除是更新的一部分 是的 这会导致重大问题 一个例子是向散列映射添加值时可能发生的情况 这可能会导致表重
  • JavaFX 图像未在舞台中显示

    我尝试了很多次 尝试了很多方法 但都无法让自己的形象在舞台上如我所愿 我认为这可能与java寻找资源的路径有关 但我不确定 因为我刚刚开始使用视觉库 在本例中为JavaFX 这是我的目录结构 MyProject assets img myI
  • 无法在类对象的 ArrayList 中存储值。 (代码已编辑)

    这基本上是一个 Java 代码转换器 它涉及一个 GUI 让用户输入类类型 名称和方法 为了存储值 我创建了一个类VirtualClass与ArrayList
  • Google App Engine with Java - 运行 javac.exe 编译器时出错

    在 Windows XP 上 刚刚下载并解压谷歌应用程序引擎java sdk to C Program Files appengine java sdk 我已经安装了jdk C Program Files Java jdk1 6 0 20
  • URL.setURLStreamHandlerFactory

    我正在使用带有嵌入式 Jetty 的可执行 jar 开发一个 Web 应用程序 我的jar包含一个依赖jar jar in jar 我参考了JarRsrcLoader and RsrcURLStreamHandlerFactory由 Ecl
  • Java、Oracle 中索引处缺少 IN 或 OUT 参数:: 1 错误

    您好 我使用 Netbeans 8 0 2 和 Oracle 11g Express Edition 在 JSF 2 2 中编写了一个图书馆管理系统 我有几个名为 书籍 借阅者 等的页面 以及数据库中一些名为相同名称的表 我的问题是这样的
  • 使用 ChannelExec 的命令未执行 - Jsch

    我正在使用 Jsch 在服务器中创建一个文件并执行一些命令 对于文件创建 它工作正常 但是对于命令执行 则不然 它保持状态 1 仍在处理它 并永远保持该状态 这种情况发生在 shell 执行或我尝试成为 root 时 请按照以下方法操作 p
  • 请参阅 Java EE eclipse 调试中的 POST 参数

    我在调试 Java EE 方面没有经验 我更像是一个 javascript 人 我需要查看哪些 HTTP POST 参数到达服务器端 我在表单将其操作指向的 jsp 文件中放置了一个断点 现在我在调试变量窗口中找不到 POST 内容 他们在
  • 如何拦截 REST 端点以接收所有标头?

    我当前的代码是 Path login RequestScoped public class LoginResource GET SecurityChecked public Response getUser HeaderParam AUTH
  • 定期更新 SWT 会导致 GUI 冻结

    Problem 当 GUI 字段定期更新时 SWT 会冻结 我想要一个基于 SWT 的 GUI 其中文本字段的值会定期递增 最初我从单独的线程访问 textField 导致抛出异常 线程 Thread 0 org eclipse swt S
  • 如何导入 org.apache.commons.lang3.ArrayUtils;进入 Eclipse [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我如何导入 org apache commons lang3 ArrayUtils 将库添加到 Ecl
  • 所有平台上的java

    如果您想用 java 为 Windows Mac 和 Linux 编写桌面应用程序 那么所有这些代码都相同吗 您只需更改 GUI 即可使 Windows 应用程序更像 Windows 等等 如果不深入细节 它是如何工作的 Java 的卖点之
  • 从 @JsonProperty 值获取枚举常量

    我有一个标有 JsonProperty 的枚举 用于使用 Jackson 进行 JSON 序列化 反序列化 并且希望获取给定字符串 JsonProperty 的枚举值 public enum TimeBucket JsonProperty
  • 如何找到被点击的JLabel并从中显示ImageIcon?

    这是我的代码 我想知道哪个l单击 然后在新框架中显示该 ImageIcon e getSource 不起作用 final JFrame shirts new JFrame T shirts JPanel panel new JPanel n
  • Java中的回调接口是什么?

    SetObserver 接口的代码片段取自有效的Java 避免过度同步第67条 public interface SetObserver
  • Java:由 HTTP 连接创建的等待连接线程存活时间很长

    我有一个服务器端代码 用于检查 SOAP 服务是否已启动 代码如下 String response while response length 0 try final URL url new URL DummySoapServiceURL
  • 使用 JAD 反编译 java - 限制

    我正在尝试使用 Java 中的 JAD 反编译几个 jar 文件 我也尝试过 JD GUI 但运气更差 但出现了很多错误 一种类型 易于修复 似乎是内部类 但我也发现了这段代码 static int SWITCH TABLE atp com
  • 为什么这个私人浮动字段变为零?

    我有一些奇怪的行为 我很难向自己解释 称为 textureScale 的浮点字段变为零 如果某些代码正在更改该值 则可以解释这一点 然而 我希望能够通过将其设置为 私有最终浮点 来导致构建失败 或者至少是运行时异常 那么无论更改该值都将失败
  • 失败时石英重试

    假设我有一个这样配置的触发器
  • Java、Spring、Hibernate找不到org.springframework.orm.hibernate3.LocalSessionFactoryBean

    我正在尝试制作 spring hibernate ant 项目 目前我收到此错误 HTTP Status 500 type Exception report message description The server encountere

随机推荐