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

ai.libs.jaicore.search.landscapeanalysis.GenericLandscapeAnalyzer Maven / Gradle / Ivy

package ai.libs.jaicore.search.landscapeanalysis;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.api4.java.ai.graphsearch.problem.IPathSearchWithPathEvaluationsInput;
import org.api4.java.ai.graphsearch.problem.implicit.graphgenerator.IPathGoalTester;
import org.api4.java.ai.graphsearch.problem.pathsearch.pathevaluation.PathEvaluationException;
import org.api4.java.datastructure.graph.ILabeledPath;
import org.api4.java.datastructure.graph.implicit.INewNodeDescription;
import org.api4.java.datastructure.graph.implicit.ISuccessorGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

public class GenericLandscapeAnalyzer {

	private static Logger logger = LoggerFactory.getLogger("testers");

	private final IPathSearchWithPathEvaluationsInput problem;
	private final N root;
	private final ISuccessorGenerator successorGenerator;
	private final IPathGoalTester goalTester;
	private double min = Double.MAX_VALUE;

	public GenericLandscapeAnalyzer(final IPathSearchWithPathEvaluationsInput problem) {
		super();
		this.problem = problem;
		this.root = problem.getGraphGenerator().getRootGenerator().getRoots().iterator().next();
		this.successorGenerator = problem.getGraphGenerator().getSuccessorGenerator();
		this.goalTester = problem.getGoalTester();
	}

	public double[] getValues(final Number probeSize) throws InterruptedException, PathEvaluationException {
		return this.getValues(probeSize, LandscapeAnalysisCompletionTechnique.RANDOM);
	}

	public double[] getValues(final Number probeSize, final LandscapeAnalysisCompletionTechnique technique) throws InterruptedException, PathEvaluationException {
		return this.getValues(new SearchGraphPath<>(this.root), probeSize, technique);
	}

	public double[] getValues(final List decisions, final int probeSize, final LandscapeAnalysisCompletionTechnique technique) throws InterruptedException, PathEvaluationException {
		List nodes = new ArrayList<>(decisions.size() + 1);
		List arcs = new ArrayList<>(decisions.size());
		N current = this.root;
		nodes.add(current);
		for (int child : decisions) {
			INewNodeDescription ned = this.successorGenerator.generateSuccessors(current).get(child);
			current = ned.getTo();
			nodes.add(current);
			arcs.add(ned.getArcLabel());
		}
		ILabeledPath path = new SearchGraphPath<>(nodes, arcs);
		return this.getValues(path, probeSize, technique);
	}

	public double[] getValues(final ILabeledPath path, final Number probeSize, final LandscapeAnalysisCompletionTechnique technique) throws InterruptedException, PathEvaluationException {
		List values = this.probeUnderPath(path, probeSize, technique);
		int n = values.size();
		double[] valuesAsArray = new double[n];
		for (int i = 0; i < n; i++) {
			valuesAsArray[i] = values.get(i);
		}
		return valuesAsArray;
	}

	private List probeUnderPath(final ILabeledPath path, final Number limit, final LandscapeAnalysisCompletionTechnique technique) throws InterruptedException, PathEvaluationException {
		N node = path.getHead();
		int cLimit = limit.intValue();
		List scoresUnderChildren = new ArrayList<>(cLimit);
		if (this.goalTester.isGoal(path)) {
			double score = this.problem.getPathEvaluator().evaluate(path);
			if (score < this.min) {
				this.min = score;
			}
			scoresUnderChildren.add(score);
			return scoresUnderChildren;
		}
		List> successors = this.successorGenerator.generateSuccessors(node);
		int n = successors.size();

		/* if we cannot delve into all successors, order them by the defined technique */
		if (n > cLimit) {
			switch (technique) {
			case FIRST:

				/* do nothing */
				break;
			case LAST:
				Collections.reverse(successors);
				break;
			case RANDOM:
				Collections.shuffle(successors);
				break;
			}
		}

		int limitPerChild = (int)Math.floor(cLimit * 1.0 / n);
		int numberOfChildrenWithExtra = cLimit % n;
		for (int child = 0; child < n; child++) {
			int limitForThisChild = limitPerChild + (child < numberOfChildrenWithExtra ? 1 : 0);
			if (limitForThisChild <= 0) {
				return scoresUnderChildren;
			}
			ILabeledPath newPath = new SearchGraphPath<>(path, successors.get(child).getTo(), successors.get(child).getArcLabel());
			scoresUnderChildren.addAll(this.probeUnderPath(newPath, limitForThisChild, technique));
		}
		return scoresUnderChildren;
	}

	public List> getIterativeProbeValuesAlongRandomPath(final Number probSizePerLevelAndChild) throws PathEvaluationException, InterruptedException {
		ILabeledPath currentPath = new SearchGraphPath<>(this.root);
		while (!this.goalTester.isGoal(currentPath)) {
			List> nedList = this.problem.getGraphGenerator().getSuccessorGenerator().generateSuccessors(currentPath.getHead());
			Collections.shuffle(nedList);
			currentPath = new SearchGraphPath<>(currentPath, nedList.get(0).getTo(), nedList.get(0).getArcLabel());
		}
		logger.info("Drew path {}: {}" , currentPath.getArcs(), currentPath.getHead());
		return this.getIterativeProbeValues(currentPath, probSizePerLevelAndChild);
	}

	public List> getIterativeProbeValues(final ILabeledPath path, final Number probSizePerLevelAndChild) throws PathEvaluationException, InterruptedException {
		List> iterativeProbes = new ArrayList<>();
		for (int depth = 0; depth < path.getNumberOfNodes() - 1; depth++) {
			logger.info("Probing on level {}", depth);

			/* compute sub-path of the relevant depth */
			ILabeledPath subPath = path;
			while (subPath.getNumberOfNodes() > depth + 1) {
				subPath = subPath.getPathToParentOfHead();
			}

			/* compute successors in that depth */
			List> nedList = this.problem.getGraphGenerator().getSuccessorGenerator().generateSuccessors(subPath.getHead());

			/* sample under each of the nodes */
			List probesOnLevel = new ArrayList<>(nedList.size());
			for (INewNodeDescription ned : nedList) {
				ILabeledPath extendedPath = new SearchGraphPath<>(subPath, ned.getTo(), ned.getArcLabel());
				double[] landscape = this.getValues(extendedPath, probSizePerLevelAndChild, LandscapeAnalysisCompletionTechnique.RANDOM);
				probesOnLevel.add(landscape);
			}
			iterativeProbes.add(probesOnLevel);
		}
		return iterativeProbes;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy