package org.aksw.isomorphism; import java.util.Collections; import java.util.function.BinaryOperator; import java.util.stream.Stream; import org.aksw.combinatorics.solvers.Problem; /** * Default implementation of the core algorithm for solving problems. * TODO Give it some fancy name * * @author Claus Stadler * * @param <S> The solution type */ public class ProblemSolver<S> { protected ProblemContainer<S> problemContainer; protected S baseSolution; protected BinaryOperator<S> solutionCombiner; public ProblemSolver(ProblemContainer<S> problemContainer, S baseSolution, BinaryOperator<S> solutionCombiner) { super(); this.problemContainer = problemContainer; this.baseSolution = baseSolution; this.solutionCombiner = solutionCombiner; } public Stream<S> streamSolutions() { ProblemContainerPick<S> pick = problemContainer.pick(); Problem<S> picked = pick.getPicked(); ProblemContainer<S> remaining = pick.getRemaining(); Stream<S> result = picked .generateSolutions() .flatMap(solutionContribution -> { S partialSolution = solutionCombiner.apply(baseSolution, solutionContribution); Stream<S> r; // If the partial solution is null, then indicate the // absence of a solution by returning a stream that yields // null as a 'solution' if (partialSolution == null) { r = Collections.<S> singleton(null).stream(); } else { // This step is optional: it refines problems // based on the current partial solution // Depending on your setting, this can give a // performance boost or penalty //ProblemContainerImpl<S> openProblems = remaining; ProblemContainer<S> openProblems = remaining.refine(partialSolution); if (openProblems.isEmpty()) { r = Collections.<S> emptySet().stream(); } else { ProblemSolver<S> nextState = new ProblemSolver<S>(openProblems, baseSolution, solutionCombiner); r = nextState.streamSolutions(); } } return r; }); return result; } public static <S> Stream<S> solve(ProblemContainer<S> problemContainer, S baseSolution, BinaryOperator<S> solutionCombiner) { ProblemSolver<S> problemSolver = new ProblemSolver<S>(problemContainer, baseSolution, solutionCombiner); Stream<S> result = problemSolver.streamSolutions(); return result; } }