All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ai.libs.jaicore.search.probleminputs.builders.SearchProblemInputBuilder Maven / Gradle / Ivy

package ai.libs.jaicore.search.probleminputs.builders;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import org.api4.java.ai.graphsearch.problem.IPathSearchInput;
import org.api4.java.ai.graphsearch.problem.implicit.graphgenerator.IPathGoalTester;
import org.api4.java.datastructure.graph.ILabeledPath;
import org.api4.java.datastructure.graph.implicit.IGraphGenerator;
import org.api4.java.datastructure.graph.implicit.INewNodeDescription;
import org.api4.java.datastructure.graph.implicit.IRootGenerator;
import org.api4.java.datastructure.graph.implicit.ISingleRootGenerator;
import org.api4.java.datastructure.graph.implicit.ISuccessorGenerator;

import ai.libs.jaicore.search.model.other.SearchGraphPath;

public abstract class SearchProblemInputBuilder, B extends SearchProblemInputBuilder> {

	private IRootGenerator rootGenerator;
	private ISuccessorGenerator successorGenerator;
	private IPathGoalTester goalTester;
	private ILabeledPath prefixPath; // the path from the original root

	public B withGraphGenerator(final IGraphGenerator graphGenerator) {
		this.rootGenerator = graphGenerator.getRootGenerator();
		this.successorGenerator = graphGenerator.getSuccessorGenerator();
		return this.self();
	}

	public IGraphGenerator getGraphGenerator() {
		return new IGraphGenerator() {

			@Override
			public IRootGenerator getRootGenerator() {
				return SearchProblemInputBuilder.this.rootGenerator;
			}

			@Override
			public ISuccessorGenerator getSuccessorGenerator() {
				return SearchProblemInputBuilder.this.successorGenerator;
			}
		};
	}

	public B fromProblem(final IPathSearchInput problem) {
		this.withGraphGenerator(problem.getGraphGenerator());
		this.withGoalTester(problem.getGoalTester());
		return this.self();
	}

	public B withRoot(final N root) {
		this.rootGenerator = () -> Arrays.asList(root);
		return this.self();
	}

	public void withSuccessorGenerator(final ISuccessorGenerator successorGenerator) {
		this.successorGenerator = successorGenerator;
	}

	/**
	 * Replaces the current root by a new one based on the successor generator
	 * @throws InterruptedException
	 **/
	public B withOffsetRoot(final List indicesOfSuccessorsFromCurrentRoot) throws InterruptedException {
		if (this.rootGenerator == null) {
			throw new IllegalStateException("Cannot offset root when currently no root is set.");
		}
		if (this.successorGenerator == null) {
			throw new IllegalStateException("Cannot offset root when currently no successor generator is set.");
		}
		Collection roots = this.rootGenerator.getRoots();
		if (roots.size() > 1) {
			throw new IllegalStateException("Root offset is a function that is only reasonably defined for problems with one root!");
		}
		List prefixNodes = new ArrayList<>();
		List prefixArcs = new ArrayList<>();
		N current = roots.iterator().next();
		prefixNodes.add(current);
		for (int child : indicesOfSuccessorsFromCurrentRoot) {
			INewNodeDescription ned = this.successorGenerator.generateSuccessors(current).get(child);
			current = ned.getTo();
			prefixArcs.add(ned.getArcLabel());
			prefixNodes.add(current);
		}
		this.prefixPath = new SearchGraphPath<>(prefixNodes, prefixArcs);
		this.rootGenerator = new ISingleRootGenerator() {

			@Override
			public N getRoot() {
				return SearchProblemInputBuilder.this.prefixPath.getHead();
			}
		};
		return this.self();
	}

	public ILabeledPath getPrefixPath() {
		return this.prefixPath;
	}

	public B withGoalTester(final IPathGoalTester goalTester) {
		this.goalTester = goalTester;
		return this.self();
	}

	public IPathGoalTester getGoalTester() {
		return this.goalTester;
	}

	public abstract I build();

	protected abstract B self();
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy