Skip to content

Commit

Permalink
use intersection instead of union which makes way more sense
Browse files Browse the repository at this point in the history
  • Loading branch information
danthe1st committed Aug 2, 2024
1 parent efcd424 commit 6f49296
Showing 1 changed file with 6 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -163,16 +163,14 @@ private Set<GPNode> run(Map<GPNode, Set<GPNode>> incomingConflicts) {// returns
Set<N> currentNodeCandidates = candidates.get(currentNode);
Set<GPNode> exclusionConstraints = mutualExclusionConstraints.get(currentNode);
if(exclusionConstraints != null){
filterMutualExclusionConstraints(currentNode, currentNodeCandidates, exclusionConstraints, Objects.requireNonNullElse(incomingConflicts.get(currentNode), new HashSet<>()));
filterMutualExclusionConstraints(currentNodeCandidates, exclusionConstraints, Objects.requireNonNullElse(incomingConflicts.get(currentNode), new HashSet<>()));
}
for(N candidateNode : currentNodeCandidates){
Map<GPNode, Set<N>> newCandidates = candidates
.entrySet()
.stream()
.filter(entry -> !entry.getKey().equals(currentNode))
.collect(Collectors.toMap(Map.Entry::getKey, entry -> new HashSet<>(entry.getValue())));
// Map<GPNode, Set<N>> newCandidates = new HashMap<>(candidates);
// newCandidates.remove(currentNode);
Map<GPNode, N> newAssignments = new HashMap<>(assignments);
newAssignments.put(currentNode, candidateNode);
Map<GPNode, Set<GPNode>> newIncomingConflicts = incomingConflicts// deep copy
Expand Down Expand Up @@ -241,14 +239,14 @@ private GPNode pickNextNode() {
return candidate;
}

private void filterMutualExclusionConstraints(GPNode currentNode, Set<N> candidatesForNode, Set<GPNode> exclusionConstraints, Set<GPNode> incomingConflicts) {
private void filterMutualExclusionConstraints(Set<N> candidatesForNode, Set<GPNode> exclusionConstraints, Set<GPNode> incomingConflicts) {
for(Iterator<N> it = candidatesForNode.iterator(); it.hasNext();){
filterMutualExclusionConstraintWithSpecificCandidate(currentNode, exclusionConstraints, incomingConflicts, it);
filterMutualExclusionConstraintWithSpecificCandidate(exclusionConstraints, incomingConflicts, it);
}

}

private void filterMutualExclusionConstraintWithSpecificCandidate(GPNode currentNode, Set<GPNode> exclusionConstraints, Set<GPNode> incomingConflicts, Iterator<N> it) {
private void filterMutualExclusionConstraintWithSpecificCandidate(Set<GPNode> exclusionConstraints, Set<GPNode> incomingConflicts, Iterator<N> it) {
N graphCandidate = it.next();
for(GPNode exclusionConstraint : exclusionConstraints){
if(graphCandidate.equals(assignments.get(exclusionConstraint))){
Expand Down Expand Up @@ -277,25 +275,12 @@ private boolean forwardChecking(GPNode currentNode, Map<GPNode, Set<GPNode>> inc
otherNodeCandidates = new HashSet<>(neighbors);
candidates.put(otherNode, otherNodeCandidates);
}else{
otherNodeCandidates.addAll(neighbors);
otherNodeCandidates.retainAll(neighbors);
}
if(otherNodeCandidates.isEmpty()){
outgoingConflicts.add(otherNode);
return false;
}
}else{
// not in the paper
// It is possible that two candidates for different nodes in the graph pattern exclude each other via a necessary edge
// In that case, one can be assigned without the other being removed
// This also needs to be tested

N currentNodeInGraph = Objects.requireNonNull(assignments.get(currentNode));
List<GPNode> conflictingNodes = checkHasNecessaryEdgesFindConflict(currentNode, otherNode, currentNodeInGraph);
if(!conflictingNodes.isEmpty()){
incomingConflicts.computeIfAbsent(currentNode, n -> new HashSet<>()).addAll(conflictingNodes);
// outgoingConflicts.addAll(conflictingNodes);
return false;
}
}
}

Expand Down Expand Up @@ -328,47 +313,7 @@ private boolean satisfiesRequirements(RelevantEdge currentEdge, E graphEdge, N n
return currentEdge.edge.edgeType().equals(graphEdge.edgeType()) &&
currentEdge.otherNode.nodeType().equals(neighbor.nodeType()) &&
checkAttributeRequirements(pattern.edgeRequirements().get(currentEdge.edge), graphEdge) &&
checkAttributeRequirements(pattern.nodeRequirements().get(currentEdge.otherNode), neighbor)
// && checkHasNecessaryEdges(currentEdge.otherNode, null, neighbor)//the paper isn't exactly clear whether this is necessary
;
}

// private boolean checkHasNecessaryEdges(GPNode node, GPNode otherNodeFilter, N graphNode) {
// return checkHasNecessaryEdgesFindConflict(node, otherNodeFilter, graphNode).isEmpty();
// }

private List<GPNode> checkHasNecessaryEdgesFindConflict(GPNode node, GPNode otherNodeFilter, N graphNode) {
List<GPNode> conflictAccumulator = new ArrayList<>();
checkNecessaryEdgesOneDirection(
graph.findOutgoingEdges(graphNode), pattern.graph().outgoingEdges().get(node),
AttributedGraphEdge::target, GPEdge::target,
otherNodeFilter, conflictAccumulator
);

checkNecessaryEdgesOneDirection(
graph.findIncomingEdges(graphNode), pattern.graph().incomingEdges().get(node),
AttributedGraphEdge::source, GPEdge::source,
otherNodeFilter, conflictAccumulator
);
return conflictAccumulator;
}

private void checkNecessaryEdgesOneDirection(Collection<E> neighboringEdges, Collection<GPEdge> patternEdges, Function<E, N> edgeOtherNodeFinder, Function<GPEdge, GPNode> gpOtherNodeFinder, GPNode otherNodeFilter, List<GPNode> conflictAccumulator) {
for(GPEdge edge : Objects.requireNonNullElse(patternEdges, List.<GPEdge>of())){
boolean isSatisfied = false;
GPNode otherNode = gpOtherNodeFinder.apply(edge);
if(otherNodeFilter == null || otherNode.equals(otherNodeFilter)){
N otherGraphNode = assignments.get(otherNode);
for(E graphEdge : neighboringEdges){
if(edge.edgeType().equals(graphEdge.edgeType()) && (otherGraphNode == null || edgeOtherNodeFinder.apply(graphEdge).equals(otherGraphNode))){
isSatisfied = true;
}
}
if(!isSatisfied){
conflictAccumulator.add(otherNode);
}
}
}
checkAttributeRequirements(pattern.nodeRequirements().get(currentEdge.otherNode), neighbor);
}

private boolean checkAttributeRequirements(List<AttributeRequirement> requirements, AttributeAware graphElement) {
Expand Down

0 comments on commit 6f49296

Please sign in to comment.