From d239ff5d82587220c7e157d18936351256bccffe Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Mon, 8 Apr 2019 23:19:31 +0200 Subject: Fix solution store for optimization --- .../application/execution/SolverLoader.xtend | 1 + .../viatrasolver/reasoner/ViatraReasoner.xtend | 13 +++++++--- .../SurelyViolatedObjectiveGlobalConstraint.xtend | 2 +- .../reasoner/dse/ViatraReasonerSolutionSaver.xtend | 30 ++++++++++++++++++---- .../optimization/ThreeValuedCostObjective.xtend | 1 - .../configs/generation.vsconfig | 4 +-- .../inputs/FamPatterns.vql | 4 +-- 7 files changed, 40 insertions(+), 15 deletions(-) diff --git a/Application/hu.bme.mit.inf.dslreasoner.application/src/hu/bme/mit/inf/dslreasoner/application/execution/SolverLoader.xtend b/Application/hu.bme.mit.inf.dslreasoner.application/src/hu/bme/mit/inf/dslreasoner/application/execution/SolverLoader.xtend index f769d46f..1139080b 100644 --- a/Application/hu.bme.mit.inf.dslreasoner.application/src/hu/bme/mit/inf/dslreasoner/application/execution/SolverLoader.xtend +++ b/Application/hu.bme.mit.inf.dslreasoner.application/src/hu/bme/mit/inf/dslreasoner/application/execution/SolverLoader.xtend @@ -150,6 +150,7 @@ class SolverLoader { } else { packageName + "." + pattern.name } + element.weight = costEntry.weight costObjectiveConfig.elements += element } } else { diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend index 6898550d..c022beac 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend @@ -88,7 +88,7 @@ class ViatraReasoner extends LogicReasoner { wf2ObjectiveConverter.createCompletenessObjective(method.unfinishedWF) )) - val extermalObjectives = Lists.newArrayListWithExpectedSize(viatraConfig.costObjectives.size) + val extremalObjectives = Lists.newArrayListWithExpectedSize(viatraConfig.costObjectives.size) for (entry : viatraConfig.costObjectives.indexed) { val objectiveName = '''costObjective«entry.key»''' val objectiveConfig = entry.value @@ -111,13 +111,18 @@ class ViatraReasoner extends LogicReasoner { objectiveConfig.threshold, 3) dse.addObjective(costObjective) if (objectiveConfig.findExtremum) { - extermalObjectives += costObjective + extremalObjectives += costObjective } } - val solutionStore = new SolutionStore(configuration.solutionScope.numberOfRequiredSolutions) + val numberOfRequiredSolutions = configuration.solutionScope.numberOfRequiredSolutions + val solutionStore = if (extremalObjectives.empty) { + new SolutionStore(numberOfRequiredSolutions) + } else { + new SolutionStore() + } solutionStore.registerSolutionFoundHandler(new LoggerSolutionFoundHandler(viatraConfig)) - val solutionSaver = new ViatraReasonerSolutionSaver(newArrayList(extermalObjectives)) + val solutionSaver = new ViatraReasonerSolutionSaver(newArrayList(extremalObjectives), numberOfRequiredSolutions) val solutionCopier = solutionSaver.solutionCopier solutionStore.withSolutionSaver(solutionSaver) dse.solutionStore = solutionStore diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SurelyViolatedObjectiveGlobalConstraint.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SurelyViolatedObjectiveGlobalConstraint.xtend index 7fd494a0..f54a31ca 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SurelyViolatedObjectiveGlobalConstraint.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SurelyViolatedObjectiveGlobalConstraint.xtend @@ -24,6 +24,6 @@ class SurelyViolatedObjectiveGlobalConstraint implements IGlobalConstraint { override checkGlobalConstraint(ThreadContext context) { val bestFitness = DseUtils.caclulateBestPossibleFitness(context) - bestFitness.satisifiesHardObjectives && !solutionSaver.isFitnessDominated(bestFitness) + bestFitness.satisifiesHardObjectives && solutionSaver.fitnessMayBeSaved(bestFitness) } } diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ViatraReasonerSolutionSaver.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ViatraReasonerSolutionSaver.xtend index 5877778e..17df6c55 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ViatraReasonerSolutionSaver.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ViatraReasonerSolutionSaver.xtend @@ -18,14 +18,16 @@ import org.eclipse.xtend.lib.annotations.Accessors class ViatraReasonerSolutionSaver implements ISolutionSaver { @Accessors val solutionCopier = new SolutionCopier val boolean hasExtremalObjectives + val int numberOfRequiredSolutions val ObjectiveComparatorHelper comparatorHelper val Map trajectories = new HashMap @Accessors(PUBLIC_SETTER) var Map solutionsCollection - new(IObjective[][] leveledExtremalObjectives) { + new(IObjective[][] leveledExtremalObjectives, int numberOfRequiredSolutions) { comparatorHelper = new ObjectiveComparatorHelper(leveledExtremalObjectives) hasExtremalObjectives = leveledExtremalObjectives.exists[!empty] + this.numberOfRequiredSolutions = numberOfRequiredSolutions } override saveSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory) { @@ -49,6 +51,9 @@ class ViatraReasonerSolutionSaver implements ISolutionSaver { dominatedTrajectories += entry.key } } + if (dominatedTrajectories.size == 0 && !needsMoreSolutionsWithSameFitness) { + return false + } // We must save the new trajectory before removing dominated trajectories // to avoid removing the current solution when it is reachable only via dominated trajectories. val solutionSaved = basicSaveSolution(context, id, solutionTrajectory) @@ -86,14 +91,29 @@ class ViatraReasonerSolutionSaver implements ISolutionSaver { } solutionSaved } - - def isFitnessDominated(Fitness fitness) { + + def fitnessMayBeSaved(Fitness fitness) { + if (!hasExtremalObjectives) { + return true + } + var boolean mayDominate for (existingFitness : trajectories.values) { val isNewFitnessBetter = comparatorHelper.compare(fitness, existingFitness) if (isNewFitnessBetter < 0) { - return true + return false } + if (isNewFitnessBetter > 0) { + mayDominate = true + } + } + mayDominate || needsMoreSolutionsWithSameFitness + } + + private def boolean needsMoreSolutionsWithSameFitness() { + if (solutionsCollection === null) { + // The solutions collection will only be initialized upon saving the first solution. + return true } - false + solutionsCollection.size < numberOfRequiredSolutions } } diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend index 362ef4a3..e2585c83 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend @@ -69,7 +69,6 @@ class ThreeValuedCostObjective extends AbstractThreeValuedObjective { if (matcher.weight <= 0) { cost += matcher.weight * matcher.mustMatcher.countMatches } else if (matcher.mayMatcher.countMatches > 0) { - // TODO Count may matches. return Double.POSITIVE_INFINITY } } diff --git a/Tests/hu.bme.mit.inf.dslreasoner.application.FAMTest/configs/generation.vsconfig b/Tests/hu.bme.mit.inf.dslreasoner.application.FAMTest/configs/generation.vsconfig index c29d234a..72def8c5 100644 --- a/Tests/hu.bme.mit.inf.dslreasoner.application.FAMTest/configs/generation.vsconfig +++ b/Tests/hu.bme.mit.inf.dslreasoner.application.FAMTest/configs/generation.vsconfig @@ -7,11 +7,11 @@ generate { partial-model = { "inputs/FamInstance.xmi"} solver = ViatraSolver scope = { - #node = 5 + #node = 10 } objectives = { minimize cost { - hu.bme.mit.inf.dslreasoner.domains.fam::informationLink = 1 + hu.bme.mit.inf.dslreasoner.domains.fam::functionalOutput = 1 } } diff --git a/Tests/hu.bme.mit.inf.dslreasoner.application.FAMTest/inputs/FamPatterns.vql b/Tests/hu.bme.mit.inf.dslreasoner.application.FAMTest/inputs/FamPatterns.vql index 31b9286e..96bb5f3a 100644 --- a/Tests/hu.bme.mit.inf.dslreasoner.application.FAMTest/inputs/FamPatterns.vql +++ b/Tests/hu.bme.mit.inf.dslreasoner.application.FAMTest/inputs/FamPatterns.vql @@ -11,6 +11,6 @@ pattern terminatorAndInformation(T : FAMTerminator, I : InformationLink) = { FunctionalInput.terminator(In,T); } -pattern informationLink(I : InformationLink) { - InformationLink(I); +pattern functionalOutput(O : FunctionalOutput) { + FunctionalOutput(O); } -- cgit v1.2.3-70-g09d2