aboutsummaryrefslogtreecommitdiffstats
path: root/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore
diff options
context:
space:
mode:
Diffstat (limited to 'Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore')
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ISolutionFoundHandler.java40
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ISolutionNameProvider.java18
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/IdBasedSolutionNameProvider.java37
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/LogSolutionHandler.java28
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ModelSaverSolutionFoundHandler.java55
-rw-r--r--Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/SolutionStore.java311
6 files changed, 489 insertions, 0 deletions
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ISolutionFoundHandler.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ISolutionFoundHandler.java
new file mode 100644
index 00000000..8d74e856
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ISolutionFoundHandler.java
@@ -0,0 +1,40 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.solutionstore;
10
11import org.eclipse.viatra.dse.api.SolutionTrajectory;
12import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
13import org.eclipse.viatra.dse.base.ThreadContext;
14import org.eclipse.viatra.dse.solutionstore.SolutionStore.ISolutionSaver;
15
16/**
17 * Contains callback methods which are called when a solution is found by the exploration {@link IStrategy}.
18 *
19 * @author Andras Szabolcs Nagy
20 *
21 */
22public interface ISolutionFoundHandler {
23
24 /**
25 * Called when a solution is saved by the {@link ISolutionSaver}. Later, this solution can be omitted from the final
26 * set of solutions.
27 *
28 * @param context
29 * @param trajectory
30 */
31 void solutionFound(ThreadContext context, SolutionTrajectory trajectory);
32
33 /**
34 * Called when the exploration found a solution but it was not saved because of certain conditions.
35 *
36 * @param context
37 * @param trajectory
38 */
39 void solutionTriedToSave(ThreadContext context, SolutionTrajectory trajectory);
40} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ISolutionNameProvider.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ISolutionNameProvider.java
new file mode 100644
index 00000000..36e6b5b7
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ISolutionNameProvider.java
@@ -0,0 +1,18 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.solutionstore;
10
11/**
12 * Provides file name when a model is searialzed.
13 * @author Andras Szabolcs Nagy
14 *
15 */
16public interface ISolutionNameProvider {
17 String getName();
18} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/IdBasedSolutionNameProvider.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/IdBasedSolutionNameProvider.java
new file mode 100644
index 00000000..43460015
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/IdBasedSolutionNameProvider.java
@@ -0,0 +1,37 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.solutionstore;
10
11/**
12 * Provides file name with a String <code>[prefix][id].[extension]</code> pattern.
13 * @author Andras Szabolcs Nagy
14 *
15 */
16public class IdBasedSolutionNameProvider implements ISolutionNameProvider {
17
18 private int id = 1;
19 private String prefix;
20 private String extension;
21
22 public IdBasedSolutionNameProvider(String prefix, String extension) {
23 this.extension = extension;
24 this.prefix = prefix;
25
26 }
27
28 @Override
29 public String getName() {
30 StringBuilder sb = new StringBuilder(prefix);
31 sb.append(id++);
32 sb.append('.');
33 sb.append(extension);
34 return sb.toString();
35 }
36
37} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/LogSolutionHandler.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/LogSolutionHandler.java
new file mode 100644
index 00000000..118f0c75
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/LogSolutionHandler.java
@@ -0,0 +1,28 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.solutionstore;
10
11import org.apache.log4j.Logger;
12import org.eclipse.viatra.dse.api.SolutionTrajectory;
13import org.eclipse.viatra.dse.base.ThreadContext;
14
15public class LogSolutionHandler implements ISolutionFoundHandler {
16
17 Logger logger = Logger.getLogger(LogSolutionHandler.class);
18
19 @Override
20 public void solutionFound(ThreadContext context, SolutionTrajectory trajectory) {
21 logger.info("Solution registered: " + trajectory.toPrettyString());
22 }
23
24 @Override
25 public void solutionTriedToSave(ThreadContext context, SolutionTrajectory trajectory) {
26 logger.debug("Not good enough solution: " + trajectory.toPrettyString());
27 }
28} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ModelSaverSolutionFoundHandler.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ModelSaverSolutionFoundHandler.java
new file mode 100644
index 00000000..bbbe60de
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/ModelSaverSolutionFoundHandler.java
@@ -0,0 +1,55 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Andras Szabolcs Nagy and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.solutionstore;
10
11import java.util.HashSet;
12
13import org.eclipse.emf.common.notify.Notifier;
14import org.eclipse.viatra.dse.api.SolutionTrajectory;
15import org.eclipse.viatra.dse.base.ThreadContext;
16import org.eclipse.viatra.dse.util.EMFHelper;
17
18public class ModelSaverSolutionFoundHandler implements ISolutionFoundHandler {
19
20 private HashSet<Object> savedSolutions = new HashSet<Object>();
21 private ISolutionNameProvider solutionNameProvider;
22
23 public ModelSaverSolutionFoundHandler() {
24 solutionNameProvider = new IdBasedSolutionNameProvider("solution", "xmi");
25 }
26
27 public ModelSaverSolutionFoundHandler(String extension) {
28 solutionNameProvider = new IdBasedSolutionNameProvider("solution", extension);
29 }
30
31 public ModelSaverSolutionFoundHandler(String prefix, String extension) {
32 solutionNameProvider = new IdBasedSolutionNameProvider(prefix, extension);
33 }
34
35 public ModelSaverSolutionFoundHandler(ISolutionNameProvider solutionNameProvider) {
36 this.solutionNameProvider = solutionNameProvider;
37 }
38
39 @Override
40 public void solutionTriedToSave(ThreadContext context, SolutionTrajectory trajectory) {
41 }
42
43 @Override
44 public void solutionFound(ThreadContext context, SolutionTrajectory trajectory) {
45 Object stateCode = trajectory.getSolution().getStateCode();
46
47 if (savedSolutions.contains(stateCode)) {
48 return;
49 }
50
51 savedSolutions.add(stateCode);
52 Notifier clonedModel = EMFHelper.clone(context.getModel());
53 EMFHelper.saveModel(clonedModel, solutionNameProvider.getName());
54 }
55} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/SolutionStore.java b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/SolutionStore.java
new file mode 100644
index 00000000..578ae277
--- /dev/null
+++ b/Solvers/VIATRA-Solver/org.eclipse.viatra.dse/src/org/eclipse/viatra/dse/solutionstore/SolutionStore.java
@@ -0,0 +1,311 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package org.eclipse.viatra.dse.solutionstore;
10
11import java.util.ArrayList;
12import java.util.Collection;
13import java.util.HashMap;
14import java.util.List;
15import java.util.Map;
16import java.util.Map.Entry;
17import java.util.concurrent.atomic.AtomicBoolean;
18import java.util.concurrent.atomic.AtomicInteger;
19
20import org.apache.log4j.Level;
21import org.apache.log4j.Logger;
22import org.eclipse.emf.common.notify.Notifier;
23import org.eclipse.viatra.dse.api.DSEException;
24import org.eclipse.viatra.dse.api.Solution;
25import org.eclipse.viatra.dse.api.SolutionTrajectory;
26import org.eclipse.viatra.dse.base.DesignSpaceManager;
27import org.eclipse.viatra.dse.base.ThreadContext;
28import org.eclipse.viatra.dse.objectives.Fitness;
29import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper;
30import org.eclipse.viatra.dse.statecode.IStateCoderFactory;
31import org.eclipse.viatra.dse.util.EMFHelper;
32import org.eclipse.viatra.query.runtime.exception.ViatraQueryException;
33
34/**
35 *
36 * @author Andras Szabolcs Nagy
37 *
38 */
39public class SolutionStore {
40
41 public interface ISolutionSaver {
42 void setSolutionsCollection(Map<Object, Solution> solutions);
43 boolean saveSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory);
44 }
45
46 public interface IEnoughSolutions extends ISolutionFoundHandler {
47 boolean enoughSolutions();
48 }
49
50 public static class ANumberOfEnoughSolutions implements IEnoughSolutions {
51
52 private final AtomicInteger foundSolutions;
53 private final AtomicBoolean foundEnoughSolutions;
54
55 public ANumberOfEnoughSolutions(int number) {
56 foundSolutions = new AtomicInteger(number);
57 foundEnoughSolutions = new AtomicBoolean(false);
58 }
59
60 @Override
61 public boolean enoughSolutions() {
62 return foundEnoughSolutions.get();
63 }
64
65 @Override
66 public void solutionFound(ThreadContext context, SolutionTrajectory trajectory) {
67 int solutionsToFind = foundSolutions.decrementAndGet();
68 if (solutionsToFind == 0) {
69 foundEnoughSolutions.set(true);
70 }
71 }
72
73 @Override
74 public void solutionTriedToSave(ThreadContext context, SolutionTrajectory trajectory) {
75 }
76 }
77
78 public static class SimpleSolutionSaver implements ISolutionSaver {
79
80 private Map<Object, Solution> solutions;
81
82 @Override
83 public void setSolutionsCollection(Map<Object, Solution> solutions) {
84 this.solutions = solutions;
85 }
86
87 @Override
88 public boolean saveSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory) {
89 Solution solution = solutions.get(id);
90 if (solution != null) {
91 if (solution.getTrajectories().contains(solutionTrajectory)) {
92 return false;
93 } else {
94 solution.addTrajectory(solutionTrajectory);
95 solutionTrajectory.setSolution(solution);
96 }
97 } else {
98 solution = new Solution(id, solutionTrajectory);
99 solutions.put(id, solution);
100 solutionTrajectory.setSolution(solution);
101 }
102 return true;
103 }
104 }
105
106 public static class BestSolutionSaver implements ISolutionSaver {
107
108 private Map<Object, Solution> solutions;
109 private Map<SolutionTrajectory, Fitness> trajectories = new HashMap<>();
110
111 @Override
112 public void setSolutionsCollection(Map<Object, Solution> solutions) {
113 this.solutions = solutions;
114 }
115
116 @Override
117 public boolean saveSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory) {
118
119 Fitness lastFitness = context.getLastFitness();
120 ObjectiveComparatorHelper comparatorHelper = context.getObjectiveComparatorHelper();
121
122 List<SolutionTrajectory> dominatedTrajectories = new ArrayList<>();
123
124 for (Entry<SolutionTrajectory, Fitness> entry : trajectories.entrySet()) {
125 int isLastFitnessBetter = comparatorHelper.compare(lastFitness, entry.getValue());
126 if (isLastFitnessBetter < 0) {
127 return false;
128 }
129 if (isLastFitnessBetter > 0) {
130 dominatedTrajectories.add(entry.getKey());
131 }
132 }
133
134 boolean solutionSaved = false;
135
136 Solution solution = solutions.get(id);
137 if (solution != null) {
138 if (!solution.getTrajectories().contains(solutionTrajectory)) {
139 solution.addTrajectory(solutionTrajectory);
140 solutionTrajectory.setSolution(solution);
141 solutionSaved = true;
142 trajectories.put(solutionTrajectory, lastFitness);
143 }
144 } else {
145 solution = new Solution(id, solutionTrajectory);
146 solutions.put(id, solution);
147 solutionTrajectory.setSolution(solution);
148 solutionSaved = true;
149 trajectories.put(solutionTrajectory, lastFitness);
150 }
151
152 for (SolutionTrajectory st : dominatedTrajectories) {
153 trajectories.remove(st);
154 Solution s = st.getSolution();
155 if (!s.getTrajectories().remove(st)) {
156 throw new DSEException("Should not happen.");
157 }
158 if (s.getTrajectories().isEmpty()) {
159 Object stateCode = s.getStateCode();
160 solutions.remove(stateCode);
161 }
162 }
163
164 return solutionSaved;
165 }
166
167 }
168
169 protected boolean acceptOnlyGoalSolutions = true;
170 protected final Map<Object, Solution> solutions = new HashMap<Object, Solution>();
171 protected ISolutionSaver solutionSaver = new SimpleSolutionSaver();
172 protected List<ISolutionFoundHandler> solutionFoundHandlers = new ArrayList<ISolutionFoundHandler>(1);
173
174 protected final IEnoughSolutions enoughSolutions;
175
176 public SolutionStore() {
177 this(new IEnoughSolutions() {
178 @Override
179 public void solutionFound(ThreadContext context, SolutionTrajectory trajectory) {
180 }
181
182 @Override
183 public boolean enoughSolutions() {
184 return false;
185 }
186
187 @Override
188 public void solutionTriedToSave(ThreadContext context, SolutionTrajectory trajectory) {
189 }
190 });
191 }
192
193 public SolutionStore(int numOfSolutionsToFind) {
194 this(new ANumberOfEnoughSolutions(numOfSolutionsToFind));
195 }
196
197 public SolutionStore(IEnoughSolutions enoughSolutionsImpl) {
198 enoughSolutions = enoughSolutionsImpl;
199 }
200
201 public synchronized void newSolution(ThreadContext context) {
202 solutionSaver.setSolutionsCollection(solutions);
203 Fitness fitness = context.getLastFitness();
204 DesignSpaceManager dsm = context.getDesignSpaceManager();
205 Object id = dsm.getCurrentState();
206 IStateCoderFactory stateCoderFactory = context.getGlobalContext().getStateCoderFactory();
207 SolutionTrajectory solutionTrajectory = dsm.getTrajectoryInfo().createSolutionTrajectory(stateCoderFactory, context.getDesignSpaceManager());
208 solutionTrajectory.setFitness(fitness);
209
210 if (acceptOnlyGoalSolutions && !fitness.isSatisifiesHardObjectives()) {
211 unsavedSolutionCallbacks(context, solutionTrajectory);
212 return;
213 }
214
215 boolean solutionSaved = solutionSaver.saveSolution(context, id, solutionTrajectory);
216
217 if (solutionSaved) {
218 enoughSolutions.solutionFound(context, solutionTrajectory);
219
220 savedSolutionCallbacks(context, solutionTrajectory);
221
222 if (enoughSolutions.enoughSolutions()) {
223 context.getGlobalContext().stopAllThreads();
224 }
225 } else {
226 unsavedSolutionCallbacks(context, solutionTrajectory);
227 }
228 }
229
230 private void unsavedSolutionCallbacks(ThreadContext context, SolutionTrajectory solutionTrajectory) {
231 for (ISolutionFoundHandler handler : solutionFoundHandlers) {
232 handler.solutionTriedToSave(context, solutionTrajectory);
233 }
234 }
235
236 private void savedSolutionCallbacks(ThreadContext context, SolutionTrajectory solutionTrajectory) {
237 for (ISolutionFoundHandler handler : solutionFoundHandlers) {
238 handler.solutionFound(context, solutionTrajectory);
239 }
240 }
241
242 public synchronized Collection<Solution> getSolutions() {
243 return solutions.values();
244 }
245
246 public synchronized void registerSolutionFoundHandler(ISolutionFoundHandler handler) {
247 if (solutionFoundHandlers == null) {
248 solutionFoundHandlers = new ArrayList<ISolutionFoundHandler>(1);
249 }
250 solutionFoundHandlers.add(handler);
251 }
252
253 public SolutionStore logSolutionsWhenFound() {
254 registerSolutionFoundHandler(new LogSolutionHandler());
255 Logger.getLogger(LogSolutionHandler.class).setLevel(Level.INFO);
256 return this;
257 }
258
259 public SolutionStore saveModelWhenFound() {
260 registerSolutionFoundHandler(new ModelSaverSolutionFoundHandler());
261 return this;
262 }
263
264 public SolutionStore saveModelWhenFound(String extension) {
265 registerSolutionFoundHandler(new ModelSaverSolutionFoundHandler(extension));
266 return this;
267 }
268
269 public SolutionStore saveModelWhenFound(String prefix, String extension) {
270 registerSolutionFoundHandler(new ModelSaverSolutionFoundHandler(prefix, extension));
271 return this;
272 }
273
274 public SolutionStore saveModelWhenFound(ISolutionNameProvider solutionNameProvider) {
275 registerSolutionFoundHandler(new ModelSaverSolutionFoundHandler(solutionNameProvider));
276 return this;
277 }
278
279 public SolutionStore acceptGoalSolutionsOnly() {
280 acceptOnlyGoalSolutions = true;
281 return this;
282 }
283
284 public SolutionStore acceptAnySolutions() {
285 acceptOnlyGoalSolutions = false;
286 return this;
287 }
288
289 public SolutionStore withSolutionSaver(ISolutionSaver solutionSaver) {
290 this.solutionSaver = solutionSaver;
291 return this;
292 }
293
294 public SolutionStore storeBestSolutionsOnly() {
295 this.solutionSaver = new BestSolutionSaver();
296 return this;
297 }
298
299 public void saveModels(Notifier model, ISolutionNameProvider solutionNameProvider) {
300 try {
301 for (Solution solution : solutions.values()) {
302 SolutionTrajectory trajectory = solution.getArbitraryTrajectory();
303 trajectory.doTransformationUndoable(model);
304 EMFHelper.saveModel(model, solutionNameProvider.getName());
305 trajectory.undoTransformation();
306 }
307 } catch (ViatraQueryException e) {
308 Logger.getLogger(SolutionStore.class).error("Exception happened during model saving.", e);
309 }
310 }
311}