use of ai.grakn.graql.internal.gremlin.spanningtree.graph.Node in project grakn by graknlabs.
the class GreedyTraversalPlan method greedyTraversal.
private static void greedyTraversal(List<Fragment> plan, Arborescence<Node> arborescence, Map<NodeId, Node> nodes, Map<Node, Map<Node, Fragment>> edgeFragmentChildToParent) {
Map<Node, Set<Node>> edgesParentToChild = new HashMap<>();
arborescence.getParents().forEach((child, parent) -> {
if (!edgesParentToChild.containsKey(parent)) {
edgesParentToChild.put(parent, new HashSet<>());
}
edgesParentToChild.get(parent).add(child);
});
Node root = arborescence.getRoot();
Set<Node> reachableNodes = Sets.newHashSet(root);
while (!reachableNodes.isEmpty()) {
Optional<Node> optionalNodeWithMinCost = reachableNodes.stream().min(Comparator.comparingDouble(node -> branchWeight(node, arborescence, edgesParentToChild, edgeFragmentChildToParent)));
assert optionalNodeWithMinCost.isPresent() : "reachableNodes is never empty, so there is always a minimum";
Node nodeWithMinCost = optionalNodeWithMinCost.get();
// add edge fragment first, then node fragments
getEdgeFragment(nodeWithMinCost, arborescence, edgeFragmentChildToParent).ifPresent(plan::add);
addNodeFragmentToPlan(nodeWithMinCost, plan, nodes, true);
reachableNodes.remove(nodeWithMinCost);
if (edgesParentToChild.containsKey(nodeWithMinCost)) {
reachableNodes.addAll(edgesParentToChild.get(nodeWithMinCost));
}
}
}
use of ai.grakn.graql.internal.gremlin.spanningtree.graph.Node in project grakn by graknlabs.
the class GreedyTraversalPlan method processFragmentWithDependencies.
private static void processFragmentWithDependencies(Map<NodeId, Node> allNodes, Fragment fragment) {
// it's either neq or value fragment
Node start = Node.addIfAbsent(NodeId.NodeType.VAR, fragment.start(), allNodes);
Node other = Node.addIfAbsent(NodeId.NodeType.VAR, fragment.dependencies().iterator().next(), allNodes);
start.getFragmentsWithDependency().add(fragment);
other.getDependants().add(fragment);
// check whether it's value fragment
if (fragment.varProperty() instanceof ValueProperty) {
// as value fragment is not symmetric, we need to add it again
other.getFragmentsWithDependency().add(fragment);
start.getDependants().add(fragment);
}
}
use of ai.grakn.graql.internal.gremlin.spanningtree.graph.Node in project grakn by graknlabs.
the class GreedyTraversalPlan method addNodeFragmentToPlan.
private static void addNodeFragmentToPlan(Node node, List<Fragment> plan, Map<NodeId, Node> nodes, boolean visited) {
if (!visited) {
node.getFragmentsWithoutDependency().stream().min(Comparator.comparingDouble(Fragment::fragmentCost)).ifPresent(firstNodeFragment -> {
plan.add(firstNodeFragment);
node.getFragmentsWithoutDependency().remove(firstNodeFragment);
});
}
node.getFragmentsWithoutDependency().addAll(node.getFragmentsWithDependencyVisited());
plan.addAll(node.getFragmentsWithoutDependency().stream().sorted(Comparator.comparingDouble(Fragment::fragmentCost)).collect(Collectors.toList()));
node.getFragmentsWithoutDependency().clear();
node.getFragmentsWithDependencyVisited().clear();
node.getDependants().forEach(fragment -> {
Node otherNode = nodes.get(new NodeId(NodeId.NodeType.VAR, fragment.start()));
if (node.equals(otherNode)) {
otherNode = nodes.get(new NodeId(NodeId.NodeType.VAR, fragment.dependencies().iterator().next()));
}
otherNode.getDependants().remove(fragment.getInverse());
otherNode.getFragmentsWithDependencyVisited().add(fragment);
});
node.getDependants().clear();
}
use of ai.grakn.graql.internal.gremlin.spanningtree.graph.Node in project grakn by graknlabs.
the class Fragment method directedEdges.
final Set<Weighted<DirectedEdge<Node>>> directedEdges(Var edge, Map<NodeId, Node> nodes, Map<Node, Map<Node, Fragment>> edgeToFragment) {
Node start = Node.addIfAbsent(NodeId.NodeType.VAR, start(), nodes);
Node end = Node.addIfAbsent(NodeId.NodeType.VAR, end(), nodes);
Node middle = Node.addIfAbsent(NodeId.NodeType.VAR, edge, nodes);
middle.setInvalidStartingPoint();
addEdgeToFragmentMapping(middle, start, edgeToFragment);
return Sets.newHashSet(weighted(DirectedEdge.from(start).to(middle), -fragmentCost()), weighted(DirectedEdge.from(middle).to(end), 0));
}
use of ai.grakn.graql.internal.gremlin.spanningtree.graph.Node in project grakn by graknlabs.
the class Fragment method directedEdges.
final Set<Weighted<DirectedEdge<Node>>> directedEdges(NodeId.NodeType nodeType, Map<NodeId, Node> nodes, Map<Node, Map<Node, Fragment>> edgeToFragment) {
Node start = Node.addIfAbsent(NodeId.NodeType.VAR, start(), nodes);
Node end = Node.addIfAbsent(NodeId.NodeType.VAR, end(), nodes);
Node middle = Node.addIfAbsent(nodeType, Sets.newHashSet(start(), end()), nodes);
middle.setInvalidStartingPoint();
addEdgeToFragmentMapping(middle, start, edgeToFragment);
return Sets.newHashSet(weighted(DirectedEdge.from(start).to(middle), -fragmentCost()), weighted(DirectedEdge.from(middle).to(end), 0));
}
Aggregations