use of edu.cmu.tetrad.graph.Node in project tetrad by cmu-phil.
the class FciOrientT method ruleR3.
/**
* Implements the double-triangle orientation rule, which states that if D*-oB, A*->B<-*C and A*-oDo-*C, then
* D*->B.
* <p>
* This is Zhang's rule R3.
*/
public void ruleR3(Graph graph) {
List<Node> nodes = graph.getNodes();
for (Node B : nodes) {
List<Node> intoBArrows = graph.getNodesInTo(B, Endpoint.ARROW);
List<Node> intoBCircles = graph.getNodesInTo(B, Endpoint.CIRCLE);
for (Node D : intoBCircles) {
if (intoBArrows.size() < 2) {
continue;
}
ChoiceGenerator gen = new ChoiceGenerator(intoBArrows.size(), 2);
int[] choice;
while ((choice = gen.next()) != null) {
Node A = intoBArrows.get(choice[0]);
Node C = intoBArrows.get(choice[1]);
if (graph.isAdjacentTo(A, C)) {
continue;
}
if (!graph.isAdjacentTo(A, D) || !graph.isAdjacentTo(C, D)) {
continue;
}
if (graph.getEndpoint(A, D) != Endpoint.CIRCLE) {
continue;
}
if (graph.getEndpoint(C, D) != Endpoint.CIRCLE) {
continue;
}
if (!isArrowpointAllowed(D, B, graph)) {
continue;
}
graph.setEndpoint(D, B, Endpoint.ARROW);
logger.log("impliedOrientations", SearchLogUtils.edgeOrientedMsg("Double triangle", graph.getEdge(D, B)));
System.out.println(SearchLogUtils.edgeOrientedMsg("Double triangle", graph.getEdge(D, B)));
changeFlag = true;
}
}
}
}
use of edu.cmu.tetrad.graph.Node in project tetrad by cmu-phil.
the class FciOrientT method ddpOrient.
/**
* a method to search "back from a" to find a DDP. It is called with a reachability list (first consisting only of
* a). This is breadth-first, utilizing "reachability" concept from Geiger, Verma, and Pearl 1990. </p> The body of
* a DDP consists of colliders that are parents of c.
*/
public void ddpOrient(Node a, Node b, Node c, Graph graph) {
Queue<Node> Q = new ArrayDeque<>();
Set<Node> V = new HashSet<>();
Node e = null;
int distance = 0;
Map<Node, Node> previous = new HashMap<>();
List<Node> cParents = graph.getParents(c);
Q.offer(a);
V.add(a);
V.add(b);
previous.put(a, b);
while (!Q.isEmpty()) {
Node t = Q.poll();
if (e == null || e == t) {
e = t;
distance++;
if (distance > 0 && distance > (maxPathLength == -1 ? 1000 : maxPathLength))
return;
}
final List<Node> nodesInTo = graph.getNodesInTo(t, Endpoint.ARROW);
for (Node d : nodesInTo) {
if (V.contains(d))
continue;
previous.put(d, t);
Node p = previous.get(t);
if (!graph.isDefCollider(d, t, p)) {
continue;
}
previous.put(d, t);
if (!graph.isAdjacentTo(d, c)) {
if (doDdpOrientation(d, a, b, c, previous, graph)) {
return;
}
}
if (cParents.contains(d)) {
Q.offer(d);
V.add(d);
}
}
}
}
use of edu.cmu.tetrad.graph.Node in project tetrad by cmu-phil.
the class FciOrientT method getUcPdPaths.
/**
* Gets a list of every uncovered partially directed path between two nodes in the graph.
* <p>
* Probably extremely slow.
*
* @param n1 The beginning node of the undirectedPaths.
* @param n2 The ending node of the undirectedPaths.
* @return A list of uncovered partially directed undirectedPaths from n1 to n2.
*/
private List<List<Node>> getUcPdPaths(Node n1, Node n2, Graph graph) {
List<List<Node>> ucPdPaths = new LinkedList<>();
LinkedList<Node> soFar = new LinkedList<>();
soFar.add(n1);
List<Node> adjacencies = graph.getAdjacentNodes(n1);
for (Node curr : adjacencies) {
getUcPdPsHelper(curr, soFar, n2, ucPdPaths, graph);
}
return ucPdPaths;
}
use of edu.cmu.tetrad.graph.Node in project tetrad by cmu-phil.
the class FciOrientT method findCollidersUsingSepsets.
/**
* 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 List<Triple> findCollidersUsingSepsets(SepsetProducer sepsetProducer, Graph graph, boolean verbose) {
TetradLogger.getInstance().log("details", "Starting Collider Orientation:");
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;
}
List<Node> sepset = sepsetProducer.getSepset(a, c);
//
if (sepset == null)
continue;
if (!sepset.contains(b)) {
if (verbose) {
System.out.println("Collider orientation <" + a + ", " + b + ", " + c + "> sepset = " + sepset);
}
colliders.add(new Triple(a, b, c));
TetradLogger.getInstance().log("colliderOrientations", SearchLogUtils.colliderOrientedMsg(a, b, c, sepset));
}
}
}
TetradLogger.getInstance().log("details", "Finishing Collider Orientation.");
return colliders;
}
use of edu.cmu.tetrad.graph.Node in project tetrad by cmu-phil.
the class FciOrientT method ruleR5.
/**
* Implements Zhang's rule R5, orient circle undirectedPaths: for any Ao-oB, if there is an uncovered circle path u =
* <A,C,...,D,B> such that A,D nonadjacent and B,C nonadjacent, then A---B and orient every edge on u undirected.
*/
public void ruleR5(Graph graph) {
List<Node> nodes = graph.getNodes();
for (Node a : nodes) {
List<Node> adjacents = graph.getNodesInTo(a, Endpoint.CIRCLE);
for (Node b : adjacents) {
if (!(graph.getEndpoint(a, b) == Endpoint.CIRCLE))
continue;
// We know Ao-oB.
List<List<Node>> ucCirclePaths = getUcCirclePaths(a, b, graph);
for (List<Node> u : ucCirclePaths) {
if (u.size() < 3)
continue;
Node c = u.get(1);
Node d = u.get(u.size() - 2);
if (graph.isAdjacentTo(a, d))
continue;
if (graph.isAdjacentTo(b, c))
continue;
// We know u is as required: R5 applies!
logger.log("colliderOrientations", SearchLogUtils.edgeOrientedMsg("Orient circle path", graph.getEdge(a, b)));
graph.setEndpoint(a, b, Endpoint.TAIL);
graph.setEndpoint(b, a, Endpoint.TAIL);
orientTailPath(u, graph);
changeFlag = true;
}
}
}
}
Aggregations