aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kris7topher@gmail.com>2019-04-09 23:11:20 +0200
committerLibravatar Kristóf Marussy <kris7topher@gmail.com>2019-04-09 23:11:20 +0200
commitec11efe9e0c3863be32e740b28e124499ad653f9 (patch)
tree7e4c5b1c6d501aa3ac53e66546a1625f91d11572
parentFix solution store for optimization (diff)
downloadVIATRA-Generator-ec11efe9e0c3863be32e740b28e124499ad653f9.tar.gz
VIATRA-Generator-ec11efe9e0c3863be32e740b28e124499ad653f9.tar.zst
VIATRA-Generator-ec11efe9e0c3863be32e740b28e124499ad653f9.zip
Make diversity checking work with optimization
Proof of concept implementation, mixing diversity checking and optimization may not be very effective in practice
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/ViatraReasoner.xtend11
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java19
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DiversityChecker.xtend184
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithDiversityDescriptor.xtend120
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ViatraReasonerSolutionSaver.xtend28
5 files changed, 216 insertions, 146 deletions
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 c022beac..edcca676 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
@@ -19,6 +19,7 @@ import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.par
19import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.IdentifierBasedStateCoderFactory 19import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.IdentifierBasedStateCoderFactory
20import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.NeighbourhoodBasedStateCoderFactory 20import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.NeighbourhoodBasedStateCoderFactory
21import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.BestFirstStrategyForModelGeneration 21import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.BestFirstStrategyForModelGeneration
22import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.DiversityChecker
22import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.LoggerSolutionFoundHandler 23import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.LoggerSolutionFoundHandler
23import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.ModelGenerationCompositeObjective 24import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.ModelGenerationCompositeObjective
24import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.PartialModelAsLogicInterpretation 25import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse.PartialModelAsLogicInterpretation
@@ -122,7 +123,9 @@ class ViatraReasoner extends LogicReasoner {
122 new SolutionStore() 123 new SolutionStore()
123 } 124 }
124 solutionStore.registerSolutionFoundHandler(new LoggerSolutionFoundHandler(viatraConfig)) 125 solutionStore.registerSolutionFoundHandler(new LoggerSolutionFoundHandler(viatraConfig))
125 val solutionSaver = new ViatraReasonerSolutionSaver(newArrayList(extremalObjectives), numberOfRequiredSolutions) 126 val diversityChecker = DiversityChecker.of(viatraConfig.diversityRequirement)
127 val solutionSaver = new ViatraReasonerSolutionSaver(newArrayList(extremalObjectives), numberOfRequiredSolutions,
128 diversityChecker)
126 val solutionCopier = solutionSaver.solutionCopier 129 val solutionCopier = solutionSaver.solutionCopier
127 solutionStore.withSolutionSaver(solutionSaver) 130 solutionStore.withSolutionSaver(solutionSaver)
128 dse.solutionStore = solutionStore 131 dse.solutionStore = solutionStore
@@ -197,14 +200,14 @@ class ViatraReasoner extends LogicReasoner {
197 it.name = "SolutionCopyTime" 200 it.name = "SolutionCopyTime"
198 it.value = (solutionCopier.getTotalCopierRuntime / 1000000) as int 201 it.value = (solutionCopier.getTotalCopierRuntime / 1000000) as int
199 ] 202 ]
200 if (strategy.solutionStoreWithDiversityDescriptor.isActive) { 203 if (diversityChecker.isActive) {
201 it.entries += createIntStatisticEntry => [ 204 it.entries += createIntStatisticEntry => [
202 it.name = "SolutionDiversityCheckTime" 205 it.name = "SolutionDiversityCheckTime"
203 it.value = (strategy.solutionStoreWithDiversityDescriptor.sumRuntime / 1000000) as int 206 it.value = (diversityChecker.totalRuntime / 1000000) as int
204 ] 207 ]
205 it.entries += createRealStatisticEntry => [ 208 it.entries += createRealStatisticEntry => [
206 it.name = "SolutionDiversitySuccessRate" 209 it.name = "SolutionDiversitySuccessRate"
207 it.value = strategy.solutionStoreWithDiversityDescriptor.successRate 210 it.value = diversityChecker.successRate
208 ] 211 ]
209 } 212 }
210 ] 213 ]
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java
index 1234d54b..6ff867d7 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java
@@ -75,7 +75,6 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
75 // Running 75 // Running
76 private PriorityQueue<TrajectoryWithFitness> trajectoiresToExplore; 76 private PriorityQueue<TrajectoryWithFitness> trajectoiresToExplore;
77 private SolutionStore solutionStore; 77 private SolutionStore solutionStore;
78 private SolutionStoreWithDiversityDescriptor solutionStoreWithDiversityDescriptor;
79 private volatile boolean isInterrupted = false; 78 private volatile boolean isInterrupted = false;
80 private ModelResult modelResultByInternalSolver = null; 79 private ModelResult modelResultByInternalSolver = null;
81 private Random random = new Random(); 80 private Random random = new Random();
@@ -96,9 +95,6 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
96 this.method = method; 95 this.method = method;
97 } 96 }
98 97
99 public SolutionStoreWithDiversityDescriptor getSolutionStoreWithDiversityDescriptor() {
100 return solutionStoreWithDiversityDescriptor;
101 }
102 public int getNumberOfStatecoderFail() { 98 public int getNumberOfStatecoderFail() {
103 return numberOfStatecoderFail; 99 return numberOfStatecoderFail;
104 } 100 }
@@ -117,8 +113,6 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
117 matchers.add(matcher); 113 matchers.add(matcher);
118 } 114 }
119 115
120 this.solutionStoreWithDiversityDescriptor = new SolutionStoreWithDiversityDescriptor(configuration.diversityRequirement);
121
122 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper(); 116 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper();
123 this.comparator = new Comparator<TrajectoryWithFitness>() { 117 this.comparator = new Comparator<TrajectoryWithFitness>() {
124 @Override 118 @Override
@@ -142,7 +136,7 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
142 } 136 }
143 137
144 final Fitness firstfitness = context.calculateFitness(); 138 final Fitness firstfitness = context.calculateFitness();
145 checkForSolution(firstfitness); 139 solutionStore.newSolution(context);
146 140
147 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper(); 141 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper();
148 final Object[] firstTrajectory = context.getTrajectory().toArray(new Object[0]); 142 final Object[] firstTrajectory = context.getTrajectory().toArray(new Object[0]);
@@ -215,7 +209,7 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
215 context.backtrack(); 209 context.backtrack();
216 } else { 210 } else {
217 final Fitness nextFitness = context.calculateFitness(); 211 final Fitness nextFitness = context.calculateFitness();
218 checkForSolution(nextFitness); 212 solutionStore.newSolution(context);
219 if (context.getDepth() > configuration.searchSpaceConstraints.maxDepth) { 213 if (context.getDepth() > configuration.searchSpaceConstraints.maxDepth) {
220 logger.debug("Reached max depth."); 214 logger.debug("Reached max depth.");
221 context.backtrack(); 215 context.backtrack();
@@ -264,15 +258,6 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
264 return activationIds; 258 return activationIds;
265 } 259 }
266 260
267 private void checkForSolution(final Fitness fitness) {
268 if (fitness.isSatisifiesHardObjectives()) {
269 if (solutionStoreWithDiversityDescriptor.isDifferent(context)) {
270 solutionStoreWithDiversityDescriptor.newSolution(context);
271 solutionStore.newSolution(context);
272 }
273 }
274 }
275
276 @Override 261 @Override
277 public void interruptStrategy() { 262 public void interruptStrategy() {
278 isInterrupted = true; 263 isInterrupted = true;
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DiversityChecker.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DiversityChecker.xtend
new file mode 100644
index 00000000..fb1b2066
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DiversityChecker.xtend
@@ -0,0 +1,184 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import com.google.common.collect.HashMultiset
4import com.google.common.collect.ImmutableSet
5import com.google.common.collect.Multiset
6import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.AbstractNodeDescriptor
7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.NeighbourhoodWithTraces
8import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2ImmutableTypeLattice
9import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
10import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.DiversityDescriptor
11import java.util.Collection
12import java.util.HashSet
13import java.util.Map
14import java.util.Set
15import org.eclipse.viatra.dse.base.ThreadContext
16import org.eclipse.xtend.lib.annotations.Accessors
17
18interface DiversityChecker {
19 public static val NO_DIVERSITY_CHECKER = new DiversityChecker {
20 override isActive() {
21 false
22 }
23
24 override getTotalRuntime() {
25 0
26 }
27
28 override getSuccessRate() {
29 1.0
30 }
31
32 override newSolution(ThreadContext threadContext, Object solutionId, Collection<Object> dominatedSolutionIds) {
33 true
34 }
35 }
36
37 def boolean isActive()
38
39 def long getTotalRuntime()
40
41 def double getSuccessRate()
42
43 def boolean newSolution(ThreadContext threadContext, Object solutionId, Collection<Object> dominatedSolutionIds)
44
45 static def of(DiversityDescriptor descriptor) {
46 if (descriptor.ensureDiversity) {
47 new NodewiseDiversityChecker(descriptor)
48 } else {
49 NO_DIVERSITY_CHECKER
50 }
51 }
52}
53
54abstract class AbstractDiversityChecker implements DiversityChecker {
55 val DiversityDescriptor descriptor
56 val PartialInterpretation2ImmutableTypeLattice solutionCoder = new PartialInterpretation2ImmutableTypeLattice
57
58 @Accessors(PUBLIC_GETTER) var long totalRuntime = 0
59 var int allCheckCount = 0
60 var int successfulCheckCount = 0
61
62 protected new(DiversityDescriptor descriptor) {
63 if (!descriptor.ensureDiversity) {
64 throw new IllegalArgumentException(
65 "Diversity description should enforce diversity or NO_DIVERSITY_CHECKER should be used instead.")
66 }
67 this.descriptor = descriptor
68 }
69
70 override isActive() {
71 true
72 }
73
74 override getTotalRuntime() {
75 throw new UnsupportedOperationException("TODO: auto-generated method stub")
76 }
77
78 override getSuccessRate() {
79 (allCheckCount as double) / (successfulCheckCount as double)
80 }
81
82 override newSolution(ThreadContext threadContext, Object solutionId, Collection<Object> dominatedSolutionIds) {
83 val start = System.nanoTime
84 val model = threadContext.model as PartialInterpretation
85 val representation = solutionCoder.createRepresentation(model, descriptor.range, descriptor.parallels,
86 descriptor.maxNumber, descriptor.relevantTypes, descriptor.relevantRelations)
87 val isDifferent = internalNewSolution(representation, solutionId, dominatedSolutionIds)
88 totalRuntime += System.nanoTime - start
89 allCheckCount++
90 if (isDifferent) {
91 successfulCheckCount++
92 }
93 isDifferent
94 }
95
96 protected abstract def boolean internalNewSolution(
97 NeighbourhoodWithTraces<Map<? extends AbstractNodeDescriptor, Integer>, AbstractNodeDescriptor> representation,
98 Object solutionId, Collection<Object> dominatedSolutionIds)
99}
100
101class NodewiseDiversityChecker extends AbstractDiversityChecker {
102 var Multiset<Integer> nodeCodes = HashMultiset.create
103 val Map<Object, Set<Integer>> tracedNodeCodes = newHashMap
104
105 new(DiversityDescriptor descriptor) {
106 super(descriptor)
107 }
108
109 override protected internalNewSolution(
110 NeighbourhoodWithTraces<Map<? extends AbstractNodeDescriptor, Integer>, AbstractNodeDescriptor> representation,
111 Object solutionId, Collection<Object> dominatedSolutionIds) {
112 val nodeCodesInSolution = ImmutableSet.copyOf(representation.modelRepresentation.keySet.map[hashCode])
113 val remainingNodeCodes = if (dominatedSolutionIds.empty) {
114 nodeCodes
115 } else {
116 getRemainingNodeCodes(dominatedSolutionIds)
117 }
118 val hasNewCode = nodeCodesInSolution.exists[!remainingNodeCodes.contains(it)]
119 if (hasNewCode) {
120 nodeCodes = remainingNodeCodes
121 nodeCodes.addAll(nodeCodesInSolution)
122 for (dominatedSolutionId : dominatedSolutionIds) {
123 tracedNodeCodes.remove(dominatedSolutionId)
124 }
125 tracedNodeCodes.put(solutionId, nodeCodesInSolution)
126 }
127 hasNewCode
128 }
129
130 private def getRemainingNodeCodes(Collection<Object> dominatedSolutionIds) {
131 // TODO Optimize multiset operations.
132 val copyOfNodeCodes = HashMultiset.create(nodeCodes)
133 for (dominatedSolutionId : dominatedSolutionIds) {
134 val dominatedModelCode = tracedNodeCodes.get(dominatedSolutionId)
135 if (dominatedModelCode === null) {
136 throw new IllegalArgumentException("Unknown dominated solution: " + dominatedSolutionId)
137 }
138 copyOfNodeCodes.removeAll(dominatedModelCode)
139 }
140 copyOfNodeCodes
141 }
142}
143
144class GraphwiseDiversityChecker extends AbstractDiversityChecker {
145 var Set<Integer> modelCodes = newHashSet
146 val Map<Object, Integer> tracedModelCodes = newHashMap
147
148 new(DiversityDescriptor descriptor) {
149 super(descriptor)
150 }
151
152 override protected internalNewSolution(
153 NeighbourhoodWithTraces<Map<? extends AbstractNodeDescriptor, Integer>, AbstractNodeDescriptor> representation,
154 Object solutionId, Collection<Object> dominatedSolutionIds) {
155 val modelCodeOfSolution = representation.modelRepresentation.hashCode
156 val remainingModelCodes = if (dominatedSolutionIds.empty) {
157 modelCodes
158 } else {
159 getRemainingModelCodes(dominatedSolutionIds)
160 }
161 val isNewCode = !remainingModelCodes.contains(modelCodeOfSolution)
162 if (isNewCode) {
163 modelCodes = remainingModelCodes
164 modelCodes += modelCodeOfSolution
165 for (dominatedSolutionId : dominatedSolutionIds) {
166 tracedModelCodes.remove(dominatedSolutionId)
167 }
168 tracedModelCodes.put(solutionId, modelCodeOfSolution)
169 }
170 isNewCode
171 }
172
173 private def getRemainingModelCodes(Collection<Object> dominatedSolutionIds) {
174 val copyOfModelCodes = new HashSet(modelCodes)
175 for (dominatedSolutionId : dominatedSolutionIds) {
176 val dominatedModelCode = tracedModelCodes.get(dominatedSolutionId)
177 if (dominatedModelCode === null) {
178 throw new IllegalArgumentException("Unknown dominated solution: " + dominatedSolutionId)
179 }
180 copyOfModelCodes -= dominatedModelCode
181 }
182 copyOfModelCodes
183 }
184}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithDiversityDescriptor.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithDiversityDescriptor.xtend
deleted file mode 100644
index 1e7f18a8..00000000
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithDiversityDescriptor.xtend
+++ /dev/null
@@ -1,120 +0,0 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2ImmutableTypeLattice
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
5import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.DiversityDescriptor
6import java.util.LinkedList
7import java.util.List
8import org.eclipse.viatra.dse.base.ThreadContext
9import java.util.HashSet
10import java.util.Set
11
12enum DiversityGranularity {
13 Nodewise, Graphwise
14}
15
16class SolutionStoreWithDiversityDescriptor {
17 val DiversityDescriptor descriptor
18 DiversityGranularity granularity
19 val PartialInterpretation2ImmutableTypeLattice solutionCoder = new PartialInterpretation2ImmutableTypeLattice
20 val Set<Integer> solutionCodeList = new HashSet
21
22 var long runtime
23 var int allCheck
24 var int successfulCheck
25
26 new(DiversityDescriptor descriptor) {
27 if(descriptor.ensureDiversity) {
28 this.descriptor = descriptor
29 this.granularity = DiversityGranularity::Nodewise
30 } else {
31 this.descriptor = null
32 this.granularity = DiversityGranularity::Nodewise
33 }
34 }
35
36 def public isActive() {
37 descriptor!==null
38 }
39
40 def getSumRuntime() {
41 return runtime
42 }
43 def getSuccessRate() {
44 return successfulCheck as double / allCheck
45 }
46
47 def isDifferent(ThreadContext context) {
48 if(active) {
49 val start = System.nanoTime
50 val model = context.model as PartialInterpretation
51 var boolean isDifferent
52 if(this.granularity == DiversityGranularity::Graphwise) {
53 val code = solutionCoder.createRepresentation(model,
54 descriptor.range,
55 descriptor.parallels,
56 descriptor.maxNumber,
57 descriptor.relevantTypes,
58 descriptor.relevantRelations).modelRepresentation.hashCode
59
60 isDifferent = !solutionCodeList.contains(code)
61 } else if(this.granularity == DiversityGranularity::Nodewise){
62 val codes = solutionCoder.createRepresentation(model,
63 descriptor.range,
64 descriptor.parallels,
65 descriptor.maxNumber,
66 descriptor.relevantTypes,
67 descriptor.relevantRelations).modelRepresentation.keySet.map[hashCode].toList
68 val differentCodes = codes.filter[!solutionCodeList.contains(it)]
69 //println(differentCodes.size)
70
71 isDifferent = differentCodes.size>=1
72 } else {
73 throw new UnsupportedOperationException('''Unsupported diversity type: «this.granularity»''')
74 }
75
76 runtime += System.nanoTime - start
77 allCheck++
78 if(isDifferent) { successfulCheck++ }
79 return isDifferent
80 } else {
81 allCheck++
82 successfulCheck++
83 return true
84 }
85 }
86
87 def canBeDifferent(ThreadContext context) {
88 return true
89 }
90
91 def newSolution(ThreadContext context) {
92 if(active) {
93 val start = System.nanoTime
94 val model = context.model as PartialInterpretation
95 if(this.granularity == DiversityGranularity::Graphwise) {
96 val code = solutionCoder.createRepresentation(model,
97 descriptor.range,
98 descriptor.parallels,
99 descriptor.maxNumber,
100 descriptor.relevantTypes,
101 descriptor.relevantRelations).modelRepresentation.hashCode
102
103 solutionCodeList += code.hashCode
104 } else if(this.granularity == DiversityGranularity::Nodewise){
105 val codes = solutionCoder.createRepresentation(model,
106 descriptor.range,
107 descriptor.parallels,
108 descriptor.maxNumber,
109 descriptor.relevantTypes,
110 descriptor.relevantRelations).modelRepresentation.keySet.map[hashCode].toList
111
112 solutionCodeList += codes.map[it.hashCode]
113 } else {
114 throw new UnsupportedOperationException('''Unsupported diversity type: «this.granularity»''')
115 }
116
117 runtime += System.nanoTime - start
118 }
119 }
120} \ No newline at end of file
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 17df6c55..6bffeb59 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
@@ -13,10 +13,11 @@ import org.eclipse.viatra.dse.solutionstore.SolutionStore.ISolutionSaver
13import org.eclipse.xtend.lib.annotations.Accessors 13import org.eclipse.xtend.lib.annotations.Accessors
14 14
15/** 15/**
16 * Based on {@link org.eclipse.viatra.dse.solutionstore.SolutionStore.BestSolutionSaver}. 16 * Based on {@link SolutionStore.BestSolutionSaver}.
17 */ 17 */
18class ViatraReasonerSolutionSaver implements ISolutionSaver { 18class ViatraReasonerSolutionSaver implements ISolutionSaver {
19 @Accessors val solutionCopier = new SolutionCopier 19 @Accessors val solutionCopier = new SolutionCopier
20 @Accessors val DiversityChecker diversityChecker
20 val boolean hasExtremalObjectives 21 val boolean hasExtremalObjectives
21 val int numberOfRequiredSolutions 22 val int numberOfRequiredSolutions
22 val ObjectiveComparatorHelper comparatorHelper 23 val ObjectiveComparatorHelper comparatorHelper
@@ -24,7 +25,8 @@ class ViatraReasonerSolutionSaver implements ISolutionSaver {
24 25
25 @Accessors(PUBLIC_SETTER) var Map<Object, Solution> solutionsCollection 26 @Accessors(PUBLIC_SETTER) var Map<Object, Solution> solutionsCollection
26 27
27 new(IObjective[][] leveledExtremalObjectives, int numberOfRequiredSolutions) { 28 new(IObjective[][] leveledExtremalObjectives, int numberOfRequiredSolutions, DiversityChecker diversityChecker) {
29 this.diversityChecker = diversityChecker
28 comparatorHelper = new ObjectiveComparatorHelper(leveledExtremalObjectives) 30 comparatorHelper = new ObjectiveComparatorHelper(leveledExtremalObjectives)
29 hasExtremalObjectives = leveledExtremalObjectives.exists[!empty] 31 hasExtremalObjectives = leveledExtremalObjectives.exists[!empty]
30 this.numberOfRequiredSolutions = numberOfRequiredSolutions 32 this.numberOfRequiredSolutions = numberOfRequiredSolutions
@@ -34,12 +36,15 @@ class ViatraReasonerSolutionSaver implements ISolutionSaver {
34 if (hasExtremalObjectives) { 36 if (hasExtremalObjectives) {
35 saveBestSolutionOnly(context, id, solutionTrajectory) 37 saveBestSolutionOnly(context, id, solutionTrajectory)
36 } else { 38 } else {
37 basicSaveSolution(context, id, solutionTrajectory) 39 saveAnyDiverseSolution(context, id, solutionTrajectory)
38 } 40 }
39 } 41 }
40 42
41 private def saveBestSolutionOnly(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory) { 43 private def saveBestSolutionOnly(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory) {
42 val fitness = context.lastFitness 44 val fitness = context.lastFitness
45 if (!fitness.satisifiesHardObjectives) {
46 return false
47 }
43 val dominatedTrajectories = newArrayList 48 val dominatedTrajectories = newArrayList
44 for (entry : trajectories.entrySet) { 49 for (entry : trajectories.entrySet) {
45 val isLastFitnessBetter = comparatorHelper.compare(fitness, entry.value) 50 val isLastFitnessBetter = comparatorHelper.compare(fitness, entry.value)
@@ -54,9 +59,12 @@ class ViatraReasonerSolutionSaver implements ISolutionSaver {
54 if (dominatedTrajectories.size == 0 && !needsMoreSolutionsWithSameFitness) { 59 if (dominatedTrajectories.size == 0 && !needsMoreSolutionsWithSameFitness) {
55 return false 60 return false
56 } 61 }
62 if (!diversityChecker.newSolution(context, id, dominatedTrajectories.map[solution.stateCode])) {
63 return false
64 }
57 // We must save the new trajectory before removing dominated trajectories 65 // We must save the new trajectory before removing dominated trajectories
58 // to avoid removing the current solution when it is reachable only via dominated trajectories. 66 // to avoid removing the current solution when it is reachable only via dominated trajectories.
59 val solutionSaved = basicSaveSolution(context, id, solutionTrajectory) 67 val solutionSaved = basicSaveSolution(context, id, solutionTrajectory, fitness)
60 for (dominatedTrajectory : dominatedTrajectories) { 68 for (dominatedTrajectory : dominatedTrajectories) {
61 trajectories -= dominatedTrajectory 69 trajectories -= dominatedTrajectory
62 val dominatedSolution = dominatedTrajectory.solution 70 val dominatedSolution = dominatedTrajectory.solution
@@ -73,8 +81,18 @@ class ViatraReasonerSolutionSaver implements ISolutionSaver {
73 solutionSaved 81 solutionSaved
74 } 82 }
75 83
76 private def basicSaveSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory) { 84 private def saveAnyDiverseSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory) {
77 val fitness = context.lastFitness 85 val fitness = context.lastFitness
86 if (!fitness.satisifiesHardObjectives) {
87 return false
88 }
89 if (!diversityChecker.newSolution(context, id, emptyList)) {
90 return false
91 }
92 basicSaveSolution(context, id, solutionTrajectory, fitness)
93 }
94
95 private def basicSaveSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory, Fitness fitness) {
78 var boolean solutionSaved = false 96 var boolean solutionSaved = false
79 var dseSolution = solutionsCollection.get(id) 97 var dseSolution = solutionsCollection.get(id)
80 if (dseSolution === null) { 98 if (dseSolution === null) {