Пример #1
0
  public List<Triple> getUnshieldedCollidersFromGraph(Graph graph) {
    List<Triple> colliders = new ArrayList<>();

    List<Node> nodes = graph.getNodes();

    for (Node b : nodes) {
      List<Node> adjacentNodes = graph.getAdjacentNodes(b);

      if (adjacentNodes.size() < 2) {
        continue;
      }

      ChoiceGenerator cg = new ChoiceGenerator(adjacentNodes.size(), 2);
      int[] combination;

      while ((combination = cg.next()) != null) {
        Node a = adjacentNodes.get(combination[0]);
        Node c = adjacentNodes.get(combination[1]);

        // Skip triples that are shielded.
        if (graph.isAdjacentTo(a, c)) {
          continue;
        }

        if (graph.isDefCollider(a, b, c)) {
          colliders.add(new Triple(a, b, c));
        }
      }
    }

    return colliders;
  }
Пример #2
0
  ////////////////////////////////////////////////
  // collect in rTupleList all unshielded tuples
  ////////////////////////////////////////////////
  private List<Node[]> getRTuples() {
    List<Node[]> rTuples = new ArrayList<Node[]>();
    List<Node> nodes = graph.getNodes();

    for (Node j : nodes) {
      List<Node> adjacentNodes = graph.getAdjacentNodes(j);

      if (adjacentNodes.size() < 2) {
        continue;
      }

      ChoiceGenerator cg = new ChoiceGenerator(adjacentNodes.size(), 2);
      int[] combination;

      while ((combination = cg.next()) != null) {
        Node i = adjacentNodes.get(combination[0]);
        Node k = adjacentNodes.get(combination[1]);

        // Skip triples that are shielded.
        if (!graph.isAdjacentTo(i, k)) {
          Node[] newTuple = {i, j, k};
          rTuples.add(newTuple);
        }
      }
    }

    return (rTuples);
  }
Пример #3
0
  public Graph orient() {
    Graph skeleton = GraphUtils.undirectedGraph(getPattern());
    Graph graph = new EdgeListGraph(skeleton.getNodes());

    List<Node> nodes = skeleton.getNodes();
    //        Collections.shuffle(nodes);

    if (isR1Done()) {
      ruleR1(skeleton, graph, nodes);
    }

    for (Edge edge : skeleton.getEdges()) {
      if (!graph.isAdjacentTo(edge.getNode1(), edge.getNode2())) {
        graph.addUndirectedEdge(edge.getNode1(), edge.getNode2());
      }
    }

    if (isR2Done()) {
      ruleR2(skeleton, graph);
    }

    if (isMeekDone()) {
      new MeekRules().orientImplied(graph);
    }

    return graph;
  }
  /** Get a graph and direct only the unshielded colliders. */
  public static void basicPattern(Graph graph) {
    Set<Edge> undirectedEdges = new HashSet<Edge>();

    NEXT_EDGE:
    for (Edge edge : graph.getEdges()) {
      Node head = null, tail = null;

      if (edge.getEndpoint1() == Endpoint.ARROW && edge.getEndpoint2() == Endpoint.TAIL) {
        head = edge.getNode1();
        tail = edge.getNode2();
      } else if (edge.getEndpoint2() == Endpoint.ARROW && edge.getEndpoint1() == Endpoint.TAIL) {
        head = edge.getNode2();
        tail = edge.getNode1();
      }

      if (head != null) {
        for (Node node : graph.getParents(head)) {
          if (node != tail && !graph.isAdjacentTo(tail, node)) {
            continue NEXT_EDGE;
          }
        }

        undirectedEdges.add(edge);
      }
    }

    for (Edge nextUndirected : undirectedEdges) {
      Node node1 = nextUndirected.getNode1(), node2 = nextUndirected.getNode2();

      graph.removeEdge(nextUndirected);
      graph.addUndirectedEdge(node1, node2);
    }
  }
Пример #5
0
  private Graph condense(Graph mimStructure, Graph mimbuildStructure) {
    //        System.out.println("Uncondensed: " + mimbuildStructure);

    Map<Node, Node> substitutions = new HashMap<Node, Node>();

    for (Node node : mimbuildStructure.getNodes()) {
      for (Node _node : mimStructure.getNodes()) {
        if (node.getName().startsWith(_node.getName())) {
          substitutions.put(node, _node);
          break;
        }

        substitutions.put(node, node);
      }
    }

    HashSet<Node> nodes = new HashSet<Node>(substitutions.values());
    Graph graph = new EdgeListGraph(new ArrayList<Node>(nodes));

    for (Edge edge : mimbuildStructure.getEdges()) {
      Node node1 = substitutions.get(edge.getNode1());
      Node node2 = substitutions.get(edge.getNode2());

      if (node1 == node2) continue;

      if (graph.isAdjacentTo(node1, node2)) continue;

      graph.addEdge(new Edge(node1, node2, edge.getEndpoint1(), edge.getEndpoint2()));
    }

    //        System.out.println("Condensed: " + graph);

    return graph;
  }
Пример #6
0
  /**
   * Step C of PC; orients colliders using specified sepset. That is, orients x *-* y *-* z as x *->
   * y <-* z just in case y is in Sepset({x, z}).
   */
  public Map<Triple, Double> findCollidersUsingSepsets(
      SepsetProducer sepsetProducer, Graph graph, boolean verbose, IKnowledge knowledge) {
    TetradLogger.getInstance().log("details", "Starting Collider Orientation:");
    Map<Triple, Double> colliders = new HashMap<>();

    System.out.println("Looking for colliders");

    List<Node> nodes = graph.getNodes();

    for (Node b : nodes) {
      List<Node> adjacentNodes = graph.getAdjacentNodes(b);

      if (adjacentNodes.size() < 2) {
        continue;
      }

      ChoiceGenerator cg = new ChoiceGenerator(adjacentNodes.size(), 2);
      int[] combination;

      while ((combination = cg.next()) != null) {
        Node a = adjacentNodes.get(combination[0]);
        Node c = adjacentNodes.get(combination[1]);

        // Skip triples that are shielded.
        if (graph.isAdjacentTo(a, c)) {
          continue;
        }

        List<Node> sepset = sepsetProducer.getSepset(a, c);

        if (sepset == null) continue;

        //                if (sepsetProducer.getPValue() < 0.5) continue;

        if (!sepset.contains(b)) {
          if (verbose) {
            //                        boolean dsep = this.dsep.isIndependent(a, c);
            //                        System.out.println("QQQ p = " + independenceTest.getPValue() +
            // " " + dsep);

            System.out.println(
                "\nCollider orientation <" + a + ", " + b + ", " + c + "> sepset = " + sepset);
          }

          colliders.put(new Triple(a, b, c), sepsetProducer.getPValue());

          TetradLogger.getInstance()
              .log("colliderOrientations", SearchLogUtils.colliderOrientedMsg(a, b, c, sepset));
        }
      }
    }

    TetradLogger.getInstance().log("details", "Finishing Collider Orientation.");

    System.out.println("Done finding colliders");

    return colliders;
  }
  public static boolean meekR1Locally2(
      Graph graph, Knowledge knowledge, IndependenceTest test, int depth) {
    List<Node> nodes = graph.getNodes();
    boolean changed = true;

    while (changed) {
      changed = false;

      for (Node a : nodes) {
        List<Node> adjacentNodes = graph.getAdjacentNodes(a);

        if (adjacentNodes.size() < 2) {
          continue;
        }

        ChoiceGenerator cg = new ChoiceGenerator(adjacentNodes.size(), 2);
        int[] combination;

        while ((combination = cg.next()) != null) {
          Node b = adjacentNodes.get(combination[0]);
          Node c = adjacentNodes.get(combination[1]);

          // Skip triples that are shielded.
          if (graph.isAdjacentTo(b, c)) {
            continue;
          }

          if (graph.getEndpoint(b, a) == Endpoint.ARROW && graph.isUndirectedFromTo(a, c)) {
            if (existsLocalSepsetWithoutDet(b, a, c, test, graph, depth)) {
              continue;
            }

            if (isArrowpointAllowed(a, c, knowledge)) {
              graph.setEndpoint(a, c, Endpoint.ARROW);
              TetradLogger.getInstance()
                  .edgeOriented(SearchLogUtils.edgeOrientedMsg("Meek R1", graph.getEdge(a, c)));
              changed = true;
            }
          } else if (graph.getEndpoint(c, a) == Endpoint.ARROW && graph.isUndirectedFromTo(a, b)) {
            if (existsLocalSepsetWithoutDet(b, a, c, test, graph, depth)) {
              continue;
            }

            if (isArrowpointAllowed(a, b, knowledge)) {
              graph.setEndpoint(a, b, Endpoint.ARROW);
              TetradLogger.getInstance()
                  .edgeOriented(SearchLogUtils.edgeOrientedMsg("Meek R1", graph.getEdge(a, b)));
              changed = true;
            }
          }
        }
      }
    }

    return changed;
  }
  /**
   * Performs step C of the algorithm, as indicated on page xxx of CPS, with the modification that
   * X--W--Y is oriented as X-->W<--Y if W is *determined by* the sepset of (X, Y), rather than W
   * just being *in* the sepset of (X, Y).
   */
  public static void pcdOrientC(
      SepsetMap set, IndependenceTest test, Knowledge knowledge, Graph graph) {
    TetradLogger.getInstance().log("info", "Staring Collider Orientation:");

    List<Node> nodes = graph.getNodes();

    for (Node y : nodes) {
      List<Node> adjacentNodes = graph.getAdjacentNodes(y);

      if (adjacentNodes.size() < 2) {
        continue;
      }

      ChoiceGenerator cg = new ChoiceGenerator(adjacentNodes.size(), 2);
      int[] combination;

      while ((combination = cg.next()) != null) {
        Node x = adjacentNodes.get(combination[0]);
        Node z = adjacentNodes.get(combination[1]);

        // Skip triples that are shielded.
        if (graph.isAdjacentTo(x, z)) {
          continue;
        }

        List<Node> sepset = set.get(x, z);

        if (sepset == null) {
          continue;
        }

        List<Node> augmentedSet = new LinkedList<Node>(sepset);
        augmentedSet.add(y);

        if (test.determines(sepset, y)) {
          continue;
        }
        //
        if (!test.splitDetermines(sepset, x, z) && test.splitDetermines(augmentedSet, x, z)) {
          continue;
        }

        if (!isArrowpointAllowed(x, y, knowledge) || !isArrowpointAllowed(z, y, knowledge)) {
          continue;
        }

        graph.setEndpoint(x, y, Endpoint.ARROW);
        graph.setEndpoint(z, y, Endpoint.ARROW);

        TetradLogger.getInstance()
            .log("colliderOriented", SearchLogUtils.colliderOrientedMsg(x, y, z));
      }
    }

    TetradLogger.getInstance().log("info", "Finishing Collider Orientation.");
  }
  /** Meek's rule R3. If a--b, a--c, a--d, c-->b, c-->b, then orient a-->b. */
  public static boolean meekR3(Graph graph, Knowledge knowledge) {

    List<Node> nodes = graph.getNodes();
    boolean changed = false;

    for (Node a : nodes) {
      List<Node> adjacentNodes = graph.getAdjacentNodes(a);

      if (adjacentNodes.size() < 3) {
        continue;
      }

      for (Node b : adjacentNodes) {
        List<Node> otherAdjacents = new LinkedList<Node>(adjacentNodes);
        otherAdjacents.remove(b);

        if (!graph.isUndirectedFromTo(a, b)) {
          continue;
        }

        ChoiceGenerator cg = new ChoiceGenerator(otherAdjacents.size(), 2);
        int[] combination;

        while ((combination = cg.next()) != null) {
          Node c = otherAdjacents.get(combination[0]);
          Node d = otherAdjacents.get(combination[1]);

          if (graph.isAdjacentTo(c, d)) {
            continue;
          }

          if (!graph.isUndirectedFromTo(a, c)) {
            continue;
          }

          if (!graph.isUndirectedFromTo(a, d)) {
            continue;
          }

          if (graph.isDirectedFromTo(c, b) && graph.isDirectedFromTo(d, b)) {
            if (isArrowpointAllowed(a, b, knowledge)) {
              graph.setEndpoint(a, b, Endpoint.ARROW);
              TetradLogger.getInstance()
                  .edgeOriented(SearchLogUtils.edgeOrientedMsg("Meek R3", graph.getEdge(a, b)));
              changed = true;
              break;
            }
          }
        }
      }
    }

    return changed;
  }
Пример #10
0
  /** Returns true iif the given set forms a clique in the given graph. */
  private static boolean isClique(List<Node> nodes, Graph graph) {
    for (int i = 0; i < nodes.size() - 1; i++) {
      for (int j = i + 1; j < nodes.size(); j++) {
        if (!graph.isAdjacentTo(nodes.get(i), nodes.get(j))) {
          return false;
        }
      }
    }

    return true;
  }
  /**
   * Double checks a sepset map against a pattern to make sure that X is adjacent to Y in the
   * pattern iff {X, Y} is not in the domain of the sepset map.
   *
   * @param sepset a sepset map, over variables V.
   * @param pattern a pattern over variables W, V subset of W.
   * @return true if the sepset map is consistent with the pattern.
   */
  public static boolean verifySepsetIntegrity(SepsetMap sepset, Graph pattern) {
    for (Node x : pattern.getNodes()) {
      for (Node y : pattern.getNodes()) {
        if (x == y) {
          continue;
        }

        if ((pattern.isAdjacentTo(y, x)) != (sepset.get(x, y) == null)) {
          System.out.println("Sepset not consistent with graph for {" + x + ", " + y + "}");
          return false;
        }
      }
    }

    return true;
  }
Пример #12
0
  /**
   * Forward equivalence search.
   *
   * @param graph The graph in the state prior to the forward equivalence search.
   */
  private void fes(Graph graph, List<Node> nodes) {
    TetradLogger.getInstance().log("info", "** FORWARD EQUIVALENCE SEARCH");

    lookupArrows = new HashMap<OrderedPair, Set<Arrow>>();

    initializeArrowsForward(nodes);

    while (!sortedArrows.isEmpty()) {
      Arrow arrow = sortedArrows.first();
      sortedArrows.remove(arrow);

      Node x = arrow.getX();
      Node y = arrow.getY();

      clearArrow(x, y);

      if (graph.isAdjacentTo(x, y)) {
        continue;
      }

      if (!validInsert(x, y, arrow.getHOrT(), arrow.getNaYX(), graph)) {
        continue;
      }

      List<Node> t = arrow.getHOrT();
      double bump = arrow.getBump();

      Set<Edge> edges = graph.getEdges();

      insert(x, y, t, graph, bump);
      score += bump;
      rebuildPattern(graph);

      // Try to avoid duplicating scoring calls. First clear out all of the edges that need to be
      // changed,
      // then change them, checking to see if they're already been changed. I know, roundabout, but
      // there's
      // a performance boost.
      for (Edge edge : graph.getEdges()) {
        if (!edges.contains(edge)) {
          reevaluateForward(graph, nodes, edge.getNode1(), edge.getNode2());
        }
      }

      storeGraph(graph);
    }
  }
Пример #13
0
  /** Get all nodes that are connected to Y by an undirected edge and not adjacent to X. */
  private static List<Node> getTNeighbors(Node x, Node y, Graph graph) {
    List<Edge> yEdges = graph.getEdges(y);
    List<Node> tNeighbors = new ArrayList<Node>();

    for (Edge edge : yEdges) {
      if (!Edges.isUndirectedEdge(edge)) {
        continue;
      }

      Node z = edge.getDistalNode(y);

      if (graph.isAdjacentTo(z, x)) {
        continue;
      }

      tNeighbors.add(z);
    }

    return tNeighbors;
  }
Пример #14
0
  /**
   * Find all nodes that are connected to Y by an undirected edge that are adjacent to X (that is,
   * by undirected or directed edge).
   */
  private static List<Node> getNaYX(Node x, Node y, Graph graph) {
    List<Edge> yEdges = graph.getEdges(y);
    List<Node> nayx = new ArrayList<Node>();

    for (Edge edge : yEdges) {
      if (!Edges.isUndirectedEdge(edge)) {
        continue;
      }

      Node z = edge.getDistalNode(y);

      if (!graph.isAdjacentTo(z, x)) {
        continue;
      }

      nayx.add(z);
    }

    return nayx;
  }
  /**
   * Step C of PC; orients colliders using specified sepset. That is, orients x *-* y *-* z as x *->
   * y <-* z just in case y is in Sepset({x, z}).
   */
  public static void orientCollidersUsingSepsets(SepsetMap set, Knowledge knowledge, Graph graph) {
    TetradLogger.getInstance().log("info", "Starting Collider Orientation:");

    //        verifySepsetIntegrity(set, graph);

    List<Node> nodes = graph.getNodes();

    for (Node a : nodes) {
      List<Node> adjacentNodes = graph.getAdjacentNodes(a);

      if (adjacentNodes.size() < 2) {
        continue;
      }

      ChoiceGenerator cg = new ChoiceGenerator(adjacentNodes.size(), 2);
      int[] combination;

      while ((combination = cg.next()) != null) {
        Node b = adjacentNodes.get(combination[0]);
        Node c = adjacentNodes.get(combination[1]);

        // Skip triples that are shielded.
        if (graph.isAdjacentTo(b, c)) {
          continue;
        }

        List<Node> sepset = set.get(b, c);
        if (sepset != null
            && !sepset.contains(a)
            && isArrowpointAllowed(b, a, knowledge)
            && isArrowpointAllowed(c, a, knowledge)) {
          graph.setEndpoint(b, a, Endpoint.ARROW);
          graph.setEndpoint(c, a, Endpoint.ARROW);
          TetradLogger.getInstance()
              .log("colliderOriented", SearchLogUtils.colliderOrientedMsg(b, a, c, sepset));
        }
      }
    }

    TetradLogger.getInstance().log("info", "Finishing Collider Orientation.");
  }
Пример #16
0
  // Invalid if then nodes or graph changes.
  private void calculateArrowsBackward(Node x, Node y, Graph graph) {
    if (x == y) {
      return;
    }

    if (!graph.isAdjacentTo(x, y)) {
      return;
    }

    if (!knowledgeEmpty()) {
      if (!getKnowledge().noEdgeRequired(x.getName(), y.getName())) {
        return;
      }
    }

    List<Node> naYX = getNaYX(x, y, graph);

    clearArrow(x, y);

    List<Node> _naYX = new ArrayList<Node>(naYX);
    DepthChoiceGenerator gen = new DepthChoiceGenerator(_naYX.size(), _naYX.size());
    int[] choice;

    while ((choice = gen.next()) != null) {
      List<Node> H = GraphUtils.asList(choice, _naYX);

      if (!knowledgeEmpty()) {
        if (!validSetByKnowledge(y, H)) {
          continue;
        }
      }

      double bump = deleteEval(x, y, H, naYX, graph);

      if (bump > 0.0) {
        Arrow arrow = new Arrow(bump, x, y, H, naYX);
        sortedArrows.add(arrow);
        addLookupArrow(x, y, arrow);
      }
    }
  }
  public static void orientCollidersLocally(
      Knowledge knowledge, Graph graph, IndependenceTest test, int depth, Set<Node> nodesToVisit) {
    TetradLogger.getInstance().log("info", "Starting Collider Orientation:");

    if (nodesToVisit == null) {
      nodesToVisit = new HashSet<Node>(graph.getNodes());
    }

    for (Node a : nodesToVisit) {
      List<Node> adjacentNodes = graph.getAdjacentNodes(a);

      if (adjacentNodes.size() < 2) {
        continue;
      }

      ChoiceGenerator cg = new ChoiceGenerator(adjacentNodes.size(), 2);
      int[] combination;

      while ((combination = cg.next()) != null) {
        Node b = adjacentNodes.get(combination[0]);
        Node c = adjacentNodes.get(combination[1]);

        // Skip triples that are shielded.
        if (graph.isAdjacentTo(b, c)) {
          continue;
        }

        if (isArrowpointAllowed1(b, a, knowledge) && isArrowpointAllowed1(c, a, knowledge)) {
          if (!existsLocalSepsetWith(b, a, c, test, graph, depth)) {
            graph.setEndpoint(b, a, Endpoint.ARROW);
            graph.setEndpoint(c, a, Endpoint.ARROW);
            TetradLogger.getInstance()
                .log("colliderOriented", SearchLogUtils.colliderOrientedMsg(b, a, c));
          }
        }
      }
    }

    TetradLogger.getInstance().log("info", "Finishing Collider Orientation.");
  }
Пример #18
0
  // serial.
  private void insert(Node x, Node y, List<Node> t, Graph graph, double bump) {
    if (graph.isAdjacentTo(x, y)) {
      return; // The initial graph may already have put this edge in the graph.
      //            throw new IllegalArgumentException(x + " and " + y + " are already adjacent in
      // the graph.");
    }

    Edge trueEdge = null;

    if (trueGraph != null) {
      Node _x = trueGraph.getNode(x.getName());
      Node _y = trueGraph.getNode(y.getName());
      trueEdge = trueGraph.getEdge(_x, _y);
    }

    graph.addDirectedEdge(x, y);

    if (log) {
      String label = trueGraph != null && trueEdge != null ? "*" : "";
      TetradLogger.getInstance()
          .log(
              "insertedEdges",
              graph.getNumEdges()
                  + ". INSERT "
                  + graph.getEdge(x, y)
                  + " "
                  + t
                  + " "
                  + bump
                  + " "
                  + label);
    } else {
      int numEdges = graph.getNumEdges() - 1;
      if (verbose) {
        if (numEdges % 50 == 0) out.println(numEdges);
      }
    }

    if (verbose) {
      String label = trueGraph != null && trueEdge != null ? "*" : "";
      out.println(
          graph.getNumEdges()
              + ". INSERT "
              + graph.getEdge(x, y)
              + " "
              + t
              + " "
              + bump
              + " "
              + label);
    } else {
      int numEdges = graph.getNumEdges() - 1;
      if (verbose) {
        if (numEdges % 50 == 0) out.println(numEdges);
      }
    }

    for (Node _t : t) {
      Edge oldEdge = graph.getEdge(_t, y);

      if (oldEdge == null) throw new IllegalArgumentException("Not adjacent: " + _t + ", " + y);

      graph.removeEdge(_t, y);
      graph.addDirectedEdge(_t, y);

      if (log && verbose) {
        TetradLogger.getInstance()
            .log("directedEdges", "--- Directing " + oldEdge + " to " + graph.getEdge(_t, y));
        out.println("--- Directing " + oldEdge + " to " + graph.getEdge(_t, y));
      }
    }
  }
Пример #19
0
  ////////////////////////////////////////////
  // RFCI Algorithm 4.4 (Colombo et al, 2012)
  // Orient colliders
  ////////////////////////////////////////////
  private void ruleR0_RFCI(List<Node[]> rTuples) {
    List<Node[]> lTuples = new ArrayList<Node[]>();

    List<Node> nodes = graph.getNodes();

    ///////////////////////////////
    // process tuples in rTuples
    while (!rTuples.isEmpty()) {
      Node[] thisTuple = rTuples.remove(0);

      Node i = thisTuple[0];
      Node j = thisTuple[1];
      Node k = thisTuple[2];

      final List<Node> nodes1 = getSepset(i, k);

      if (nodes1 == null) continue;

      List<Node> sepSet = new ArrayList<Node>(nodes1);
      sepSet.remove(j);

      boolean independent1 = false;
      if (knowledge.noEdgeRequired(i.getName(), j.getName())) // if BK allows
      {
        try {
          independent1 = independenceTest.isIndependent(i, j, sepSet);
        } catch (Exception e) {
          independent1 = true;
        }
      }

      boolean independent2 = false;
      if (knowledge.noEdgeRequired(j.getName(), k.getName())) // if BK allows
      {
        try {
          independent2 = independenceTest.isIndependent(j, k, sepSet);
        } catch (Exception e) {
          independent2 = true;
        }
      }

      if (!independent1 && !independent2) {
        lTuples.add(thisTuple);
      } else {
        // set sepSets to minimal separating sets
        if (independent1) {
          setMinSepSet(sepSet, i, j);
          graph.removeEdge(i, j);
        }
        if (independent2) {
          setMinSepSet(sepSet, j, k);
          graph.removeEdge(j, k);
        }

        // add new unshielded tuples to rTuples
        for (Node thisNode : nodes) {
          List<Node> adjacentNodes = graph.getAdjacentNodes(thisNode);
          if (independent1) // <i, ., j>
          {
            if (adjacentNodes.contains(i) && adjacentNodes.contains(j)) {
              Node[] newTuple = {i, thisNode, j};
              rTuples.add(newTuple);
            }
          }
          if (independent2) // <j, ., k>
          {
            if (adjacentNodes.contains(j) && adjacentNodes.contains(k)) {
              Node[] newTuple = {j, thisNode, k};
              rTuples.add(newTuple);
            }
          }
        }

        // remove tuples involving either (if independent1) <i, j>
        // or (if independent2) <j, k> from rTuples
        Iterator<Node[]> iter = rTuples.iterator();
        while (iter.hasNext()) {
          Node[] curTuple = iter.next();
          if ((independent1 && (curTuple[1] == i) && ((curTuple[0] == j) || (curTuple[2] == j)))
              || (independent2 && (curTuple[1] == k) && ((curTuple[0] == j) || (curTuple[2] == j)))
              || (independent1 && (curTuple[1] == j) && ((curTuple[0] == i) || (curTuple[2] == i)))
              || (independent2
                  && (curTuple[1] == j)
                  && ((curTuple[0] == k) || (curTuple[2] == k)))) {
            iter.remove();
          }
        }

        // remove tuples involving either (if independent1) <i, j>
        // or (if independent2) <j, k> from lTuples
        iter = lTuples.iterator();
        while (iter.hasNext()) {
          Node[] curTuple = iter.next();
          if ((independent1 && (curTuple[1] == i) && ((curTuple[0] == j) || (curTuple[2] == j)))
              || (independent2 && (curTuple[1] == k) && ((curTuple[0] == j) || (curTuple[2] == j)))
              || (independent1 && (curTuple[1] == j) && ((curTuple[0] == i) || (curTuple[2] == i)))
              || (independent2
                  && (curTuple[1] == j)
                  && ((curTuple[0] == k) || (curTuple[2] == k)))) {
            iter.remove();
          }
        }
      }
    }

    ///////////////////////////////////////////////////////
    // orient colliders (similar to original FCI ruleR0)
    for (Node[] thisTuple : lTuples) {
      Node i = thisTuple[0];
      Node j = thisTuple[1];
      Node k = thisTuple[2];

      List<Node> sepset = getSepset(i, k);

      if (sepset == null) {
        continue;
      }

      if (!sepset.contains(j) && graph.isAdjacentTo(i, j) && graph.isAdjacentTo(j, k)) {

        if (!isArrowpointAllowed(i, j)) {
          continue;
        }

        if (!isArrowpointAllowed(k, j)) {
          continue;
        }

        graph.setEndpoint(i, j, Endpoint.ARROW);
        graph.setEndpoint(k, j, Endpoint.ARROW);

        printWrongColliderMessage(i, j, k, "R0_RFCI");
      }
    }
  }
Пример #20
0
  private void addRequiredEdges(Graph graph) {
    if (true) return;
    if (knowledgeEmpty()) return;

    for (Iterator<KnowledgeEdge> it = getKnowledge().requiredEdgesIterator(); it.hasNext(); ) {
      KnowledgeEdge next = it.next();

      Node nodeA = graph.getNode(next.getFrom());
      Node nodeB = graph.getNode(next.getTo());

      if (!graph.isAncestorOf(nodeB, nodeA)) {
        graph.removeEdges(nodeA, nodeB);
        graph.addDirectedEdge(nodeA, nodeB);
        TetradLogger.getInstance()
            .log("insertedEdges", "Adding edge by knowledge: " + graph.getEdge(nodeA, nodeB));
      }
    }
    for (Edge edge : graph.getEdges()) {
      final String A = edge.getNode1().getName();
      final String B = edge.getNode2().getName();

      if (knowledge.isForbidden(A, B)) {
        Node nodeA = edge.getNode1();
        Node nodeB = edge.getNode2();

        if (nodeA != null
            && nodeB != null
            && graph.isAdjacentTo(nodeA, nodeB)
            && !graph.isChildOf(nodeA, nodeB)) {
          if (!graph.isAncestorOf(nodeA, nodeB)) {
            graph.removeEdges(nodeA, nodeB);
            graph.addDirectedEdge(nodeB, nodeA);
            TetradLogger.getInstance()
                .log("insertedEdges", "Adding edge by knowledge: " + graph.getEdge(nodeB, nodeA));
          }
        }
        if (!graph.isChildOf(nodeA, nodeB)
            && getKnowledge().isForbidden(nodeA.getName(), nodeB.getName())) {
          if (!graph.isAncestorOf(nodeA, nodeB)) {
            graph.removeEdges(nodeA, nodeB);
            graph.addDirectedEdge(nodeB, nodeA);
            TetradLogger.getInstance()
                .log("insertedEdges", "Adding edge by knowledge: " + graph.getEdge(nodeB, nodeA));
          }
        }
      } else if (knowledge.isForbidden(B, A)) {
        Node nodeA = edge.getNode2();
        Node nodeB = edge.getNode1();

        if (nodeA != null
            && nodeB != null
            && graph.isAdjacentTo(nodeA, nodeB)
            && !graph.isChildOf(nodeA, nodeB)) {
          if (!graph.isAncestorOf(nodeA, nodeB)) {
            graph.removeEdges(nodeA, nodeB);
            graph.addDirectedEdge(nodeB, nodeA);
            TetradLogger.getInstance()
                .log("insertedEdges", "Adding edge by knowledge: " + graph.getEdge(nodeB, nodeA));
          }
        }
        if (!graph.isChildOf(nodeA, nodeB)
            && getKnowledge().isForbidden(nodeA.getName(), nodeB.getName())) {
          if (!graph.isAncestorOf(nodeA, nodeB)) {
            graph.removeEdges(nodeA, nodeB);
            graph.addDirectedEdge(nodeB, nodeA);
            TetradLogger.getInstance()
                .log("insertedEdges", "Adding edge by knowledge: " + graph.getEdge(nodeB, nodeA));
          }
        }
      }
    }
  }
Пример #21
0
  /** Do an actual deletion (Definition 13 from Chickering, 2002). */
  private void delete(Node x, Node y, List<Node> subset, Graph graph, double bump) {

    Edge trueEdge = null;

    if (trueGraph != null) {
      Node _x = trueGraph.getNode(x.getName());
      Node _y = trueGraph.getNode(y.getName());
      trueEdge = trueGraph.getEdge(_x, _y);
    }

    if (log && verbose) {
      Edge oldEdge = graph.getEdge(x, y);

      String label = trueGraph != null && trueEdge != null ? "*" : "";
      TetradLogger.getInstance()
          .log(
              "deletedEdges",
              (graph.getNumEdges() - 1)
                  + ". DELETE "
                  + oldEdge
                  + " "
                  + subset
                  + " ("
                  + bump
                  + ") "
                  + label);
      out.println(
          (graph.getNumEdges() - 1)
              + ". DELETE "
              + oldEdge
              + " "
              + subset
              + " ("
              + bump
              + ") "
              + label);
    } else {
      int numEdges = graph.getNumEdges() - 1;
      if (numEdges % 50 == 0) out.println(numEdges);
    }

    graph.removeEdge(x, y);

    for (Node h : subset) {
      Edge oldEdge = graph.getEdge(y, h);

      graph.removeEdge(y, h);
      graph.addDirectedEdge(y, h);

      if (log) {
        TetradLogger.getInstance()
            .log("directedEdges", "--- Directing " + oldEdge + " to " + graph.getEdge(y, h));
      }

      if (verbose) {
        out.println("--- Directing " + oldEdge + " to " + graph.getEdge(y, h));
      }

      if (Edges.isUndirectedEdge(graph.getEdge(x, h))) {
        if (!graph.isAdjacentTo(x, h))
          throw new IllegalArgumentException("Not adjacent: " + x + ", " + h);
        oldEdge = graph.getEdge(x, h);

        graph.removeEdge(x, h);
        graph.addDirectedEdge(x, h);

        if (log) {
          TetradLogger.getInstance()
              .log("directedEdges", "--- Directing " + oldEdge + " to " + graph.getEdge(x, h));
        }

        if (verbose) {
          out.println("--- Directing " + oldEdge + " to " + graph.getEdge(x, h));
        }
      }
    }
  }
Пример #22
0
  private void resolveOneEdgeMax(Graph graph, Node x, Node y, boolean strong, Graph oldGraph) {
    if (RandomUtil.getInstance().nextDouble() > 0.5) {
      Node temp = x;
      x = y;
      y = temp;
    }

    TetradLogger.getInstance().log("info", "\nEDGE " + x + " --- " + y);

    SortedMap<Double, String> scoreReports = new TreeMap<Double, String>();

    List<Node> neighborsx = graph.getAdjacentNodes(x);
    neighborsx.remove(y);

    double max = Double.NEGATIVE_INFINITY;
    boolean left = false;
    boolean right = false;

    DepthChoiceGenerator genx = new DepthChoiceGenerator(neighborsx.size(), neighborsx.size());
    int[] choicex;

    while ((choicex = genx.next()) != null) {
      List<Node> condxMinus = GraphUtils.asList(choicex, neighborsx);

      List<Node> condxPlus = new ArrayList<Node>(condxMinus);
      condxPlus.add(y);

      double xPlus = score(x, condxPlus);
      double xMinus = score(x, condxMinus);

      List<Node> neighborsy = graph.getAdjacentNodes(y);
      neighborsy.remove(x);

      DepthChoiceGenerator geny = new DepthChoiceGenerator(neighborsy.size(), neighborsy.size());
      int[] choicey;

      while ((choicey = geny.next()) != null) {
        List<Node> condyMinus = GraphUtils.asList(choicey, neighborsy);

        //                List<Node> parentsY = oldGraph.getParents(y);
        //                parentsY.remove(x);
        //                if (!condyMinus.containsAll(parentsY)) {
        //                    continue;
        //                }

        List<Node> condyPlus = new ArrayList<Node>(condyMinus);
        condyPlus.add(x);

        double yPlus = score(y, condyPlus);
        double yMinus = score(y, condyMinus);

        // Checking them all at once is expensive but avoids lexical ordering problems in the
        // algorithm.
        if (normal(y, condyPlus)
            || normal(x, condxMinus)
            || normal(x, condxPlus)
            || normal(y, condyMinus)) {
          continue;
        }

        double delta = 0.0;

        if (strong) {
          if (yPlus <= xPlus + delta && xMinus <= yMinus + delta) {
            double score = combinedScore(xPlus, yMinus);

            if (yPlus <= yMinus + delta && xMinus <= xPlus + delta) {
              StringBuilder builder = new StringBuilder();

              builder.append("\nStrong " + y + "->" + x + " " + score);
              builder.append("\n   Parents(" + x + ") = " + condxMinus);
              builder.append("\n   Parents(" + y + ") = " + condyMinus);

              scoreReports.put(-score, builder.toString());

              if (score > max) {
                max = score;
                left = true;
                right = false;
              }
            } else {
              StringBuilder builder = new StringBuilder();

              builder.append("\nNo directed edge " + x + "--" + y + " " + score);
              builder.append("\n   Parents(" + x + ") = " + condxMinus);
              builder.append("\n   Parents(" + y + ") = " + condyMinus);

              scoreReports.put(-score, builder.toString());
            }
          } else if (xPlus <= yPlus + delta && yMinus <= xMinus + delta) {
            double score = combinedScore(yPlus, xMinus);

            if (yMinus <= yPlus + delta && xPlus <= xMinus + delta) {
              StringBuilder builder = new StringBuilder();

              builder.append("\nStrong " + x + "->" + y + " " + score);
              builder.append("\n   Parents(" + x + ") = " + condxMinus);
              builder.append("\n   Parents(" + y + ") = " + condyMinus);

              scoreReports.put(-score, builder.toString());

              if (score > max) {
                max = score;
                left = false;
                right = true;
              }
            } else {
              StringBuilder builder = new StringBuilder();

              builder.append("\nNo directed edge " + x + "--" + y + " " + score);
              builder.append("\n   Parents(" + x + ") = " + condxMinus);
              builder.append("\n   Parents(" + y + ") = " + condyMinus);

              scoreReports.put(-score, builder.toString());
            }
          } else if (yPlus <= xPlus + delta && yMinus <= xMinus + delta) {
            double score = combinedScore(yPlus, xMinus);

            StringBuilder builder = new StringBuilder();

            builder.append("\nNo directed edge " + x + "--" + y + " " + score);
            builder.append("\n   Parents(" + x + ") = " + condxMinus);
            builder.append("\n   Parents(" + y + ") = " + condyMinus);

            scoreReports.put(-score, builder.toString());
          } else if (xPlus <= yPlus + delta && xMinus <= yMinus + delta) {
            double score = combinedScore(yPlus, xMinus);

            StringBuilder builder = new StringBuilder();

            builder.append("\nNo directed edge " + x + "--" + y + " " + score);
            builder.append("\n   Parents(" + x + ") = " + condxMinus);
            builder.append("\n   Parents(" + y + ") = " + condyMinus);

            scoreReports.put(-score, builder.toString());
          }
        } else {
          if (yPlus <= xPlus + delta && xMinus <= yMinus + delta) {
            double score = combinedScore(xPlus, yMinus);

            StringBuilder builder = new StringBuilder();

            builder.append("\nWeak " + y + "->" + x + " " + score);
            builder.append("\n   Parents(" + x + ") = " + condxMinus);
            builder.append("\n   Parents(" + y + ") = " + condyMinus);

            scoreReports.put(-score, builder.toString());

            if (score > max) {
              max = score;
              left = true;
              right = false;
            }
          } else if (xPlus <= yPlus + delta && yMinus <= xMinus + delta) {
            double score = combinedScore(yPlus, xMinus);

            StringBuilder builder = new StringBuilder();

            builder.append("\nWeak " + x + "->" + y + " " + score);
            builder.append("\n   Parents(" + x + ") = " + condxMinus);
            builder.append("\n   Parents(" + y + ") = " + condyMinus);

            scoreReports.put(-score, builder.toString());

            if (score > max) {
              max = score;
              left = false;
              right = true;
            }
          } else if (yPlus <= xPlus + delta && yMinus <= xMinus + delta) {
            double score = combinedScore(yPlus, xMinus);

            StringBuilder builder = new StringBuilder();

            builder.append("\nNo directed edge " + x + "--" + y + " " + score);
            builder.append("\n   Parents(" + x + ") = " + condxMinus);
            builder.append("\n   Parents(" + y + ") = " + condyMinus);

            scoreReports.put(-score, builder.toString());
          } else if (xPlus <= yPlus + delta && xMinus <= yMinus + delta) {
            double score = combinedScore(yPlus, xMinus);

            StringBuilder builder = new StringBuilder();

            builder.append("\nNo directed edge " + x + "--" + y + " " + score);
            builder.append("\n   Parents(" + x + ") = " + condxMinus);
            builder.append("\n   Parents(" + y + ") = " + condyMinus);

            scoreReports.put(-score, builder.toString());
          }
        }
      }
    }

    for (double score : scoreReports.keySet()) {
      TetradLogger.getInstance().log("info", scoreReports.get(score));
    }

    graph.removeEdges(x, y);

    if (left) {
      graph.addDirectedEdge(y, x);
    }

    if (right) {
      graph.addDirectedEdge(x, y);
    }

    if (!graph.isAdjacentTo(x, y)) {
      graph.addUndirectedEdge(x, y);
    }
  }