All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.vangj.jbayes.inf.exact.graph.Dag Maven / Gradle / Ivy

The newest version!
package com.github.vangj.jbayes.inf.exact.graph;

import static com.github.vangj.jbayes.inf.exact.graph.util.PotentialUtil.getPotential;

import com.github.vangj.jbayes.inf.exact.graph.lpd.Potential;
import com.github.vangj.jbayes.inf.exact.graph.traversal.DagShortestPath;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * A directed acylic graph (DAG).
 */
public class Dag extends Graph {

  protected Map> parents;
  protected Map> children;

  public Dag() {
    parents = new HashMap<>();
    children = new HashMap<>();
  }

  /**
   * Initializes the potential for each node.
   *
   * @return Dag.
   */
  public Dag initializePotentials() {
    nodes().forEach(node -> {
      Potential potential = getPotential(node, parents(node));
      node.setPotential(potential);
    });
    return this;
  }

  @Override
  protected Graph instance() {
    return new Dag();
  }

  @Override
  public Graph addEdge(Edge edge) {
    edge.type = Edge.Type.DIRECTED;

    if (DagShortestPath.exists(this, edge.right, edge.left, null)) {
      //if right -> -> -> left path alrady exists
      //then adding left -> right will form cycle!
      //do not add it
      return this;
    }

    super.addEdge(edge);
    Node n1 = edge.left;
    Node n2 = edge.right;

    List parents = parents(n2);
    if (!parents.contains(n1)) {
      parents.add(n1);
    }

    List children = children(n1);
    if (!children.contains(n2)) {
      children.add(n2);
    }
    return this;
  }

  /**
   * Gets the parent of the specified node.
   *
   * @param node Node.
   * @return List of parents.
   */
  public List parents(Node node) {
    List parents = this.parents.get(node.id);
    if (null == parents) {
      parents = new ArrayList<>();
      this.parents.put(node.id, parents);
    }
    return parents;
  }

  /**
   * Gets the children of the specified node.
   *
   * @param node Node.
   * @return List of children.
   */
  public List children(Node node) {
    List children = this.children.get(node.id);
    if (null == children) {
      children = new ArrayList<>();
      this.children.put(node.id, children);
    }
    return children;
  }

  /**
   * Gets the coparents of the specified node. Coparents are parents of the specified node's
   * children.
   *
   * @param node Node.
   * @return List of coparents.
   */
  public List coparents(Node node) {
    Set copas = new HashSet<>();
    children(node).forEach(n -> {
      copas.addAll(parents(n));
    });
    copas.remove(node);
    return new ArrayList<>(copas);
  }

  /**
   * Gets the Markov blanket for the specified node. The Markov blanket is specified as the union of
   * parents, children, and coparents.
   *
   * @param node Node.
   * @return List of nodes in the Markov blanket.
   */
  public List markovBlanket(Node node) {
    Set blanket = new HashSet<>();
    blanket.addAll(parents(node));
    blanket.addAll(children(node));
    blanket.addAll(coparents(node));
    blanket.remove(node);
    return new ArrayList<>(blanket);
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy