public boolean equals(Object obj) { ReachabilityEdge edge = (ReachabilityEdge) obj; if (!(edge.getFrom().equals(this.getFrom()))) { return false; } return edge.getTo().equals(this.getTo()); }
/** * Returns the set of nodes reachable from the given set of initial nodes in the given graph * according to the criteria in the given legal pairs object. * * <p>A variable V is reachable from initialNodes iff for some variable X in initialNodes thers is * a path U [X, Y1, ..., V] such that legalPairs.isLegalFirstNode(X, Y1) and for each [H1, H2, H3] * as subpaths of U, legalPairs.isLegalPairs(H1, H2, H3). * * <p>The algorithm used is a variant of Algorithm 1 from Geiger, Verma, & Pearl (1990). * * @param initialNodes The nodes that reachability paths start from. * @param legalPairs Specifies initial edges (given initial nodes) and legal edge pairs. * @param c a set of vertices (intuitively, the set of variables to be conditioned on. * @param d a set of vertices (intuitively to be used in tests of legality, for example, the set * of ancestors of c). * @param graph the graph with respect to which reachability is determined. */ public static Set<Node> getReachableNodes( List<Node> initialNodes, LegalPairs legalPairs, List<Node> c, List<Node> d, Graph graph) { HashSet<Node> reachable = new HashSet<Node>(); MultiKeyMap visited = new MultiKeyMap(); List<ReachabilityEdge> nextEdges = new LinkedList<ReachabilityEdge>(); for (Node x : initialNodes) { List<Node> adjX = graph.getAdjacentNodes(x); for (Node y : adjX) { if (legalPairs.isLegalFirstEdge(x, y)) { reachable.add(y); nextEdges.add(new ReachabilityEdge(x, y)); visited.put(x, y, Boolean.TRUE); } } } while (nextEdges.size() > 0) { List<ReachabilityEdge> currEdges = nextEdges; nextEdges = new LinkedList<ReachabilityEdge>(); for (ReachabilityEdge edge : currEdges) { Node x = edge.getFrom(); Node y = edge.getTo(); List<Node> adjY = graph.getAdjacentNodes(y); for (Node z : adjY) { if ((visited.get(y, z)) == Boolean.TRUE) { continue; } if (legalPairs.isLegalPair(x, y, z, c, d)) { reachable.add(z); nextEdges.add(new ReachabilityEdge(y, z)); visited.put(y, z, Boolean.TRUE); } } } } return reachable; }