improve search with combine specification
This commit is contained in:
@@ -6,6 +6,10 @@ import ru.trader.analysis.graph.Traversal;
|
|||||||
public interface RouteSpecification<T> {
|
public interface RouteSpecification<T> {
|
||||||
|
|
||||||
public boolean specified(Edge<T> edge, Traversal<T> entry);
|
public boolean specified(Edge<T> edge, Traversal<T> entry);
|
||||||
|
public default int lastFound(Edge<T> edge, Traversal<T> entry){
|
||||||
|
return specified(edge, entry) ? 0 : matchCount();
|
||||||
|
}
|
||||||
|
public default int matchCount(){return 1;}
|
||||||
public default boolean updateMutated(){return false;}
|
public default boolean updateMutated(){return false;}
|
||||||
public default boolean mutable(){return false;}
|
public default boolean mutable(){return false;}
|
||||||
public default void update(Traversal<T> entry){}
|
public default void update(Traversal<T> entry){}
|
||||||
@@ -17,6 +21,16 @@ public interface RouteSpecification<T> {
|
|||||||
return RouteSpecification.this.specified(edge, entry) && other.specified(edge, entry);
|
return RouteSpecification.this.specified(edge, entry) && other.specified(edge, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int lastFound(Edge<T> edge, Traversal<T> entry) {
|
||||||
|
return RouteSpecification.this.lastFound(edge, entry) + other.lastFound(edge, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int matchCount() {
|
||||||
|
return RouteSpecification.this.matchCount() + other.matchCount();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean updateMutated() {
|
public boolean updateMutated() {
|
||||||
return RouteSpecification.this.updateMutated() || other.updateMutated();
|
return RouteSpecification.this.updateMutated() || other.updateMutated();
|
||||||
@@ -42,6 +56,16 @@ public interface RouteSpecification<T> {
|
|||||||
return RouteSpecification.this.specified(edge, entry) || other.specified(edge, entry);
|
return RouteSpecification.this.specified(edge, entry) || other.specified(edge, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int lastFound(Edge<T> edge, Traversal<T> entry) {
|
||||||
|
return Math.min(RouteSpecification.this.lastFound(edge, entry), other.lastFound(edge, entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int matchCount() {
|
||||||
|
return Math.min(RouteSpecification.this.matchCount(), other.matchCount());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean updateMutated() {
|
public boolean updateMutated() {
|
||||||
return RouteSpecification.this.updateMutated() || other.updateMutated();
|
return RouteSpecification.this.updateMutated() || other.updateMutated();
|
||||||
|
|||||||
@@ -20,30 +20,46 @@ public class RouteSpecificationByTargets<T> implements RouteSpecification<T> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean specified(Edge<T> edge, Traversal<T> entry) {
|
public boolean specified(Edge<T> edge, Traversal<T> entry) {
|
||||||
|
return all ? containsAll(edge, entry) == 0 : containsAny(edge, entry) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int lastFound(Edge<T> edge, Traversal<T> entry) {
|
||||||
return all ? containsAll(edge, entry) : containsAny(edge, entry);
|
return all ? containsAll(edge, entry) : containsAny(edge, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean containsAll(Edge<T> edge, Traversal<T> entry) {
|
@Override
|
||||||
|
public int matchCount() {
|
||||||
|
return all ? targets.size() : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int containsAll(Edge<T> edge, Traversal<T> entry) {
|
||||||
T obj = edge.getTarget().getEntry();
|
T obj = edge.getTarget().getEntry();
|
||||||
Collection<T> set = new ArrayList<>(targets.size());
|
Collection<T> set = new ArrayList<>(targets.size());
|
||||||
set.add(obj);
|
set.add(obj);
|
||||||
entry.routeIterator().forEachRemaining(e -> set.add(e.getTarget().getEntry()));
|
entry.routeIterator().forEachRemaining(e -> set.add(e.getTarget().getEntry()));
|
||||||
return set.containsAll(targets);
|
int last = targets.size();
|
||||||
|
for (T target : targets) {
|
||||||
|
if (set.contains(target)){
|
||||||
|
last--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return last;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean containsAny(Edge<T> edge, Traversal<T> entry) {
|
private int containsAny(Edge<T> edge, Traversal<T> entry) {
|
||||||
T obj = edge.getTarget().getEntry();
|
T obj = edge.getTarget().getEntry();
|
||||||
if (targets.contains(obj)) return true;
|
if (targets.contains(obj)) return 0;
|
||||||
if (targetOnly){
|
if (targetOnly){
|
||||||
return false;
|
return 1;
|
||||||
}
|
}
|
||||||
Iterator<Edge<T>> iterator = entry.routeIterator();
|
Iterator<Edge<T>> iterator = entry.routeIterator();
|
||||||
while (iterator.hasNext()){
|
while (iterator.hasNext()){
|
||||||
if (targets.contains(iterator.next().getTarget().getEntry())){
|
if (targets.contains(iterator.next().getTarget().getEntry())){
|
||||||
return true;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> RouteSpecificationByTargets<T> all(Collection<T> targets){
|
public static <T> RouteSpecificationByTargets<T> all(Collection<T> targets){
|
||||||
|
|||||||
@@ -65,6 +65,10 @@ public class Crawler<T> {
|
|||||||
return specification.specified(edge, head);
|
return specification.specified(edge, head);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected int lastFound(Edge<T> edge, Traversal<T> head){
|
||||||
|
return specification.lastFound(edge, head);
|
||||||
|
}
|
||||||
|
|
||||||
private void updateState(Traversal<T> entry){
|
private void updateState(Traversal<T> entry){
|
||||||
if (specification.mutable()){
|
if (specification.mutable()){
|
||||||
specification.update(entry);
|
specification.update(entry);
|
||||||
@@ -511,8 +515,9 @@ public class Crawler<T> {
|
|||||||
CostTraversalEntry entry = curr.entry;
|
CostTraversalEntry entry = curr.entry;
|
||||||
if (skip()) continue;
|
if (skip()) continue;
|
||||||
LOG.trace("Check edge {}, entry {}, weight {}, curr {}", edge, entry, entry.weight, curr);
|
LOG.trace("Check edge {}, entry {}, weight {}, curr {}", edge, entry, entry.weight, curr);
|
||||||
boolean isTarget = isFound(edge, entry);
|
int lastFound = lastFound(edge, entry);
|
||||||
boolean canDeep = !entry.getTarget().isSingle() && deep < entry.getTarget().getLevel() && entry.size() < maxSize-1;
|
boolean isTarget = lastFound == 0;
|
||||||
|
boolean canDeep = !entry.getTarget().isSingle() && deep < entry.getTarget().getLevel() && entry.size()+lastFound < maxSize;
|
||||||
if (canDeep || isTarget){
|
if (canDeep || isTarget){
|
||||||
CostTraversalEntry nextEntry = travers(entry, edge);
|
CostTraversalEntry nextEntry = travers(entry, edge);
|
||||||
if (canDeep){
|
if (canDeep){
|
||||||
|
|||||||
Reference in New Issue
Block a user