aboutsummaryrefslogtreecommitdiffstats
path: root/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ViatraReasonerSolutionSaver.xtend
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <marussy@mit.bme.hu>2020-11-02 02:02:40 +0100
committerLibravatar Kristóf Marussy <marussy@mit.bme.hu>2020-11-02 02:02:40 +0100
commitf06427cd7375551582461f91b3458339a8227f9b (patch)
tree97bc6ec85f4c384e5080a6611b492caf460b6ce9 /Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ViatraReasonerSolutionSaver.xtend
parentMust unit propagation (diff)
downloadVIATRA-Generator-f06427cd7375551582461f91b3458339a8227f9b.tar.gz
VIATRA-Generator-f06427cd7375551582461f91b3458339a8227f9b.tar.zst
VIATRA-Generator-f06427cd7375551582461f91b3458339a8227f9b.zip
Optimizing generator with linear objective functions
Diffstat (limited to 'Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ViatraReasonerSolutionSaver.xtend')
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ViatraReasonerSolutionSaver.xtend112
1 files changed, 105 insertions, 7 deletions
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 c0b5008c..e00f76ff 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
@@ -1,5 +1,9 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse 1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2 2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.Bounds
4import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.DirectionalThresholdObjective
5import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.IObjectiveBoundsProvider
6import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveThreshold
3import java.util.HashMap 7import java.util.HashMap
4import java.util.Map 8import java.util.Map
5import org.eclipse.viatra.dse.api.DSEException 9import org.eclipse.viatra.dse.api.DSEException
@@ -18,24 +22,32 @@ import org.eclipse.xtend.lib.annotations.Accessors
18 * Will also automatically fill any missing numerical values in the saved solutions 22 * Will also automatically fill any missing numerical values in the saved solutions
19 * using the supplied {@link NumericSolver}. 23 * using the supplied {@link NumericSolver}.
20 */ 24 */
21class ViatraReasonerSolutionSaver implements ISolutionSaver { 25class ViatraReasonerSolutionSaver implements ISolutionSaver, IObjectiveBoundsProvider {
26 static val TOLERANCE = 1e-10
27
22 @Accessors val SolutionCopier solutionCopier 28 @Accessors val SolutionCopier solutionCopier
23 val NumericSolver numericSolver
24 @Accessors val DiversityChecker diversityChecker 29 @Accessors val DiversityChecker diversityChecker
30 val IObjective[][] leveledExtremalObjectives
25 val boolean hasExtremalObjectives 31 val boolean hasExtremalObjectives
26 val int numberOfRequiredSolutions 32 val int numberOfRequiredSolutions
27 val ObjectiveComparatorHelper comparatorHelper 33 val ObjectiveComparatorHelper comparatorHelper
28 val Map<SolutionTrajectory, Fitness> trajectories = new HashMap 34 val Map<SolutionTrajectory, Fitness> trajectories = new HashMap
29 35
30 @Accessors(PUBLIC_SETTER) var Map<Object, Solution> solutionsCollection 36 @Accessors var NumericSolver numericSolver
37 @Accessors var Map<Object, Solution> solutionsCollection
31 38
32 new(IObjective[][] leveledExtremalObjectives, int numberOfRequiredSolutions, DiversityChecker diversityChecker, NumericSolver numericSolver) { 39 new(IObjective[][] leveledExtremalObjectives, int numberOfRequiredSolutions, DiversityChecker diversityChecker) {
33 this.diversityChecker = diversityChecker 40 this.diversityChecker = diversityChecker
34 comparatorHelper = new ObjectiveComparatorHelper(leveledExtremalObjectives) 41 comparatorHelper = new ObjectiveComparatorHelper(leveledExtremalObjectives)
42 this.leveledExtremalObjectives = leveledExtremalObjectives
35 hasExtremalObjectives = leveledExtremalObjectives.exists[!empty] 43 hasExtremalObjectives = leveledExtremalObjectives.exists[!empty]
36 this.numberOfRequiredSolutions = numberOfRequiredSolutions 44 this.numberOfRequiredSolutions = numberOfRequiredSolutions
37 this.solutionCopier = new SolutionCopier(numericSolver) 45 this.solutionCopier = new SolutionCopier
46 }
47
48 def setNumericSolver(NumericSolver numericSolver) {
38 this.numericSolver = numericSolver 49 this.numericSolver = numericSolver
50 solutionCopier.numericSolver = numericSolver
39 } 51 }
40 52
41 override saveSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory) { 53 override saveSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory) {
@@ -51,6 +63,7 @@ class ViatraReasonerSolutionSaver implements ISolutionSaver {
51 if (!shouldSaveSolution(fitness, context)) { 63 if (!shouldSaveSolution(fitness, context)) {
52 return false 64 return false
53 } 65 }
66 println("Found: " + fitness)
54 val dominatedTrajectories = newArrayList 67 val dominatedTrajectories = newArrayList
55 for (entry : trajectories.entrySet) { 68 for (entry : trajectories.entrySet) {
56 val isLastFitnessBetter = comparatorHelper.compare(fitness, entry.value) 69 val isLastFitnessBetter = comparatorHelper.compare(fitness, entry.value)
@@ -99,7 +112,7 @@ class ViatraReasonerSolutionSaver implements ISolutionSaver {
99 } 112 }
100 113
101 private def shouldSaveSolution(Fitness fitness, ThreadContext context) { 114 private def shouldSaveSolution(Fitness fitness, ThreadContext context) {
102 return fitness.satisifiesHardObjectives && numericSolver.currentSatisfiable 115 fitness.satisifiesHardObjectives && (numericSolver === null || numericSolver.currentSatisfiable)
103 } 116 }
104 117
105 private def basicSaveSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory, 118 private def basicSaveSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory,
@@ -145,8 +158,93 @@ class ViatraReasonerSolutionSaver implements ISolutionSaver {
145 } 158 }
146 solutionsCollection.size < numberOfRequiredSolutions 159 solutionsCollection.size < numberOfRequiredSolutions
147 } 160 }
148 161
149 def getTotalCopierRuntime() { 162 def getTotalCopierRuntime() {
150 solutionCopier.totalCopierRuntime 163 solutionCopier.totalCopierRuntime
151 } 164 }
165
166 override computeRequiredBounds(IObjective objective, Bounds bounds) {
167 if (!hasExtremalObjectives) {
168 return
169 }
170 if (objective instanceof DirectionalThresholdObjective) {
171 switch (threshold : objective.threshold) {
172 case ObjectiveThreshold.NO_THRESHOLD: {
173 // No threshold to set.
174 }
175 ObjectiveThreshold.Exclusive: {
176 switch (kind : objective.kind) {
177 case HIGHER_IS_BETTER:
178 bounds.tightenLowerBound(Math.floor(threshold.threshold + 1) as int)
179 case LOWER_IS_BETTER:
180 bounds.tightenUpperBound(Math.ceil(threshold.threshold - 1) as int)
181 default:
182 throw new IllegalArgumentException("Unknown objective kind" + kind)
183 }
184 if (threshold.clampToThreshold) {
185 return
186 }
187 }
188 ObjectiveThreshold.Inclusive: {
189 switch (kind : objective.kind) {
190 case HIGHER_IS_BETTER:
191 bounds.tightenLowerBound(Math.ceil(threshold.threshold) as int)
192 case LOWER_IS_BETTER:
193 bounds.tightenUpperBound(Math.floor(threshold.threshold) as int)
194 default:
195 throw new IllegalArgumentException("Unknown objective kind" + kind)
196 }
197 if (threshold.clampToThreshold) {
198 return
199 }
200 }
201 default:
202 throw new IllegalArgumentException("Unknown threshold: " + threshold)
203 }
204 for (level : leveledExtremalObjectives) {
205 switch (level.size) {
206 case 0: {
207 // Nothing to do, wait for the next level.
208 }
209 case 1: {
210 val primaryObjective = level.get(0)
211 if (primaryObjective != objective) {
212 // There are no worst-case bounds for secondary objectives.
213 return
214 }
215 }
216 default:
217 // There are no worst-case bounds for Pareto front calculation.
218 return
219 }
220 }
221 val fitnessIterator = trajectories.values.iterator
222 if (!fitnessIterator.hasNext) {
223 return
224 }
225 val fitness = fitnessIterator.next.get(objective.name)
226 while (fitnessIterator.hasNext) {
227 val otherFitness = fitnessIterator.next.get(objective.name)
228 if (Math.abs(fitness - otherFitness) > TOLERANCE) {
229 throw new IllegalStateException("Inconsistent fitness: " + objective.name)
230 }
231 }
232 switch (kind : objective.kind) {
233 case HIGHER_IS_BETTER:
234 if (needsMoreSolutionsWithSameFitness) {
235 bounds.tightenLowerBound(Math.floor(fitness) as int)
236 } else {
237 bounds.tightenLowerBound(Math.floor(fitness + 1) as int)
238 }
239 case LOWER_IS_BETTER:
240 if (needsMoreSolutionsWithSameFitness) {
241 bounds.tightenUpperBound(Math.ceil(fitness) as int)
242 } else {
243 bounds.tightenUpperBound(Math.ceil(fitness - 1) as int)
244 }
245 default:
246 throw new IllegalArgumentException("Unknown objective kind" + kind)
247 }
248 }
249 }
152} 250}