diff options
Diffstat (limited to 'Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java')
1 files changed, 532 insertions, 468 deletions
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java index eb7df089..d9f84b36 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java | |||
@@ -16,6 +16,7 @@ import java.util.Random; | |||
16 | import java.util.Set; | 16 | import java.util.Set; |
17 | 17 | ||
18 | import org.apache.log4j.Logger; | 18 | import org.apache.log4j.Logger; |
19 | import org.eclipse.emf.ecore.EObject; | ||
19 | import org.eclipse.emf.ecore.util.EcoreUtil; | 20 | import org.eclipse.emf.ecore.util.EcoreUtil; |
20 | import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy; | 21 | import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy; |
21 | import org.eclipse.viatra.dse.base.ThreadContext; | 22 | import org.eclipse.viatra.dse.base.ThreadContext; |
@@ -35,480 +36,540 @@ import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem; | |||
35 | import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.InconsistencyResult; | 36 | import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.InconsistencyResult; |
36 | import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicResult; | 37 | import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicResult; |
37 | import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult; | 38 | import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult; |
38 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethod; | ||
39 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic.PartialInterpretation2Logic; | 39 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic.PartialInterpretation2Logic; |
40 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation; | 40 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation; |
41 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.NeighbourhoodBasedPartialInterpretationStateCoder; | ||
41 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualisation; | 42 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualisation; |
42 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualiser; | 43 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualiser; |
44 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ModelGenerationMethod; | ||
43 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.RealisticGuidance; | 45 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.RealisticGuidance; |
44 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration; | 46 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration; |
45 | import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace; | 47 | import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace; |
46 | 48 | ||
47 | public class HillClimbingOnRealisticMetricStrategyForModelGeneration implements IStrategy { | 49 | public class HillClimbingOnRealisticMetricStrategyForModelGeneration implements IStrategy { |
48 | // Services and Configuration | 50 | // Services and Configuration |
49 | private ThreadContext context; | 51 | private ThreadContext context; |
50 | private ReasonerWorkspace workspace; | 52 | private ReasonerWorkspace workspace; |
51 | private ViatraReasonerConfiguration configuration; | 53 | private ViatraReasonerConfiguration configuration; |
52 | private ModelGenerationMethod method; | 54 | private ModelGenerationMethod method; |
53 | private PartialInterpretation2Logic partialInterpretation2Logic = new PartialInterpretation2Logic(); | 55 | private PartialInterpretation2Logic partialInterpretation2Logic = new PartialInterpretation2Logic(); |
54 | private Comparator<TrajectoryWithFitness> comparator; | 56 | private Comparator<TrajectoryWithFitness> comparator; |
55 | private Logger logger = Logger.getLogger(IStrategy.class); | 57 | private Logger logger = Logger.getLogger(IStrategy.class); |
58 | public NumericSolver numericSolver = null; | ||
59 | |||
60 | // Running | ||
61 | private PriorityQueue<TrajectoryWithFitness> trajectoiresToExplore; | ||
62 | private SolutionStore solutionStore; | ||
63 | private SolutionStoreWithCopy solutionStoreWithCopy; | ||
64 | private SolutionStoreWithDiversityDescriptor solutionStoreWithDiversityDescriptor; | ||
65 | private volatile boolean isInterrupted = false; | ||
66 | private ModelResult modelResultByInternalSolver = null; | ||
67 | private Random random = new Random(); | ||
68 | |||
69 | // matchers for detecting the number of violations | ||
70 | private Collection<ViatraQueryMatcher<? extends IPatternMatch>> mustMatchers; | ||
71 | private Collection<ViatraQueryMatcher<? extends IPatternMatch>> mayMatchers; | ||
72 | |||
73 | // Encode the used activations of a particular state | ||
74 | private Map<Object, List<Object>> stateAndActivations; | ||
75 | private boolean allowMustViolation; | ||
76 | private Domain domain; | ||
77 | int targetSize; | ||
78 | public ActivationSelector activationSelector = new EvenActivationSelector(random); | ||
79 | // Statistics | ||
80 | private int numberOfStatecoderFail = 0; | ||
81 | private int numberOfPrintedModel = 0; | ||
82 | private int numberOfSolverCalls = 0; | ||
83 | private PartialInterpretationMetricDistance metricDistance; | ||
84 | private double currentStateValue = Double.MAX_VALUE; | ||
85 | private double currentNodeTypeDistance = 1; | ||
86 | private int numNodesToGenerate = 0; | ||
87 | public long explorationStarted = 0; | ||
88 | public long globalConstraintEvaluationTime = 0; | ||
89 | public long fitnessCalculationTime = 0; | ||
90 | |||
91 | public HillClimbingOnRealisticMetricStrategyForModelGeneration( | ||
92 | ReasonerWorkspace workspace, | ||
93 | ViatraReasonerConfiguration configuration, | ||
94 | ModelGenerationMethod method) | ||
95 | { | ||
96 | this.workspace = workspace; | ||
97 | this.configuration = configuration; | ||
98 | this.method = method; | ||
99 | } | ||
100 | |||
101 | public SolutionStoreWithCopy getSolutionStoreWithCopy() { | ||
102 | return solutionStoreWithCopy; | ||
103 | } | ||
104 | public SolutionStoreWithDiversityDescriptor getSolutionStoreWithDiversityDescriptor() { | ||
105 | return solutionStoreWithDiversityDescriptor; | ||
106 | } | ||
107 | public int getNumberOfStatecoderFail() { | ||
108 | return numberOfStatecoderFail; | ||
109 | } | ||
110 | |||
111 | public long getForwardTime() { | ||
112 | return context.getDesignSpaceManager().getForwardTime(); | ||
113 | } | ||
114 | public long getBacktrackingTime() { | ||
115 | return context.getDesignSpaceManager().getBacktrackingTime(); | ||
116 | } | ||
117 | |||
118 | @Override | ||
119 | public void initStrategy(ThreadContext context) { | ||
120 | this.context = context; | ||
121 | this.solutionStore = context.getGlobalContext().getSolutionStore(); | ||
122 | domain = Domain.valueOf(configuration.domain); | ||
123 | |||
124 | ViatraQueryEngine engine = context.getQueryEngine(); | ||
125 | // // TODO: visualisation | ||
126 | mustMatchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>(); | ||
127 | mayMatchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>(); | ||
56 | 128 | ||
57 | // Running | 129 | // manully restict the number of super types of one class |
58 | private PriorityQueue<TrajectoryWithFitness> trajectoiresToExplore; | 130 | this.method.getInvalidWF().forEach(a ->{ |
59 | private SolutionStore solutionStore; | 131 | ViatraQueryMatcher<? extends IPatternMatch> matcher = a.getMatcher(engine); |
60 | private SolutionStoreWithCopy solutionStoreWithCopy; | 132 | mustMatchers.add(matcher); |
61 | private SolutionStoreWithDiversityDescriptor solutionStoreWithDiversityDescriptor; | 133 | }); |
62 | private volatile boolean isInterrupted = false; | ||
63 | private ModelResult modelResultByInternalSolver = null; | ||
64 | private Random random = new Random(); | ||
65 | 134 | ||
66 | // matchers for detecting the number of violations | 135 | this.method.getUnfinishedWF().forEach(a ->{ |
67 | private Collection<ViatraQueryMatcher<? extends IPatternMatch>> mustMatchers; | 136 | ViatraQueryMatcher<? extends IPatternMatch> matcher = a.getMatcher(engine); |
68 | private Collection<ViatraQueryMatcher<? extends IPatternMatch>> mayMatchers; | 137 | mayMatchers.add(matcher); |
138 | }); | ||
69 | 139 | ||
70 | // Encode the used activations of a particular state | ||
71 | private Map<Object, List<Object>> stateAndActivations; | ||
72 | private boolean allowMustViolation; | ||
73 | private Domain domain; | ||
74 | int targetSize; | ||
75 | |||
76 | // Statistics | ||
77 | private int numberOfStatecoderFail = 0; | ||
78 | private int numberOfPrintedModel = 0; | ||
79 | private int numberOfSolverCalls = 0; | ||
80 | private PartialInterpretationMetricDistance metricDistance; | ||
81 | private double currentStateValue = Double.MAX_VALUE; | ||
82 | private double currentNodeTypeDistance = 1; | ||
83 | private int numNodesToGenerate = 0; | ||
84 | 140 | ||
85 | public HillClimbingOnRealisticMetricStrategyForModelGeneration( | 141 | //set up comparator |
86 | ReasonerWorkspace workspace, | 142 | final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper(); |
87 | ViatraReasonerConfiguration configuration, | 143 | this.comparator = new Comparator<TrajectoryWithFitness>() { |
88 | ModelGenerationMethod method) | 144 | @Override |
89 | { | 145 | public int compare(TrajectoryWithFitness o1, TrajectoryWithFitness o2) { |
90 | this.workspace = workspace; | 146 | return objectiveComparatorHelper.compare(o2.fitness, o1.fitness); |
91 | this.configuration = configuration; | 147 | } |
92 | this.method = method; | 148 | }; |
93 | } | ||
94 | 149 | ||
95 | public SolutionStoreWithCopy getSolutionStoreWithCopy() { | 150 | this.solutionStoreWithCopy = new SolutionStoreWithCopy(); |
96 | return solutionStoreWithCopy; | 151 | this.solutionStoreWithDiversityDescriptor = new SolutionStoreWithDiversityDescriptor(configuration.diversityRequirement); |
97 | } | 152 | |
98 | public SolutionStoreWithDiversityDescriptor getSolutionStoreWithDiversityDescriptor() { | 153 | trajectoiresToExplore = new PriorityQueue<TrajectoryWithFitness>(11, comparator); |
99 | return solutionStoreWithDiversityDescriptor; | 154 | stateAndActivations = new HashMap<Object, List<Object>>(); |
155 | metricDistance = new PartialInterpretationMetricDistance(domain); | ||
156 | |||
157 | //set whether allows must violations during the realistic generation | ||
158 | allowMustViolation = configuration.allowMustViolations; | ||
159 | targetSize = configuration.typeScopes.maxNewElements + 2; | ||
160 | //this.numericSolver = new NumericSolver(method, this.configuration.runIntermediateNumericalConsistencyChecks, false); | ||
161 | } | ||
162 | |||
163 | @Override | ||
164 | public void explore() { | ||
165 | this.explorationStarted=System.nanoTime(); | ||
166 | if (!checkGlobalConstraints()) { | ||
167 | logger.info("Global contraint is not satisifed in the first state. Terminate."); | ||
168 | return; | ||
100 | } | 169 | } |
101 | public int getNumberOfStatecoderFail() { | 170 | if (configuration.searchSpaceConstraints.maxDepth == 0) { |
102 | return numberOfStatecoderFail; | 171 | logger.info("Maximal depth is reached in the initial solution. Terminate."); |
172 | return; | ||
103 | } | 173 | } |
104 | |||
105 | @Override | ||
106 | public void initStrategy(ThreadContext context) { | ||
107 | this.context = context; | ||
108 | this.solutionStore = context.getGlobalContext().getSolutionStore(); | ||
109 | domain = Domain.valueOf(configuration.domain); | ||
110 | |||
111 | ViatraQueryEngine engine = context.getQueryEngine(); | ||
112 | // // TODO: visualisation | ||
113 | mustMatchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>(); | ||
114 | mayMatchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>(); | ||
115 | |||
116 | // manully restict the number of super types of one class | ||
117 | this.method.getInvalidWF().forEach(a ->{ | ||
118 | ViatraQueryMatcher<? extends IPatternMatch> matcher = a.getMatcher(engine); | ||
119 | mustMatchers.add(matcher); | ||
120 | }); | ||
121 | |||
122 | this.method.getUnfinishedWF().forEach(a ->{ | ||
123 | ViatraQueryMatcher<? extends IPatternMatch> matcher = a.getMatcher(engine); | ||
124 | mayMatchers.add(matcher); | ||
125 | }); | ||
126 | 174 | ||
127 | 175 | final Fitness firstFittness = context.calculateFitness(); | |
128 | //set up comparator | 176 | |
129 | final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper(); | 177 | //final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper(); |
130 | this.comparator = new Comparator<TrajectoryWithFitness>() { | 178 | final Object[] firstTrajectory = context.getTrajectory().toArray(new Object[0]); |
131 | @Override | 179 | TrajectoryWithFitness currentTrajectoryWithFittness = new TrajectoryWithFitness(firstTrajectory, firstFittness); |
132 | public int compare(TrajectoryWithFitness o1, TrajectoryWithFitness o2) { | 180 | trajectoiresToExplore.add(currentTrajectoryWithFittness); |
133 | return objectiveComparatorHelper.compare(o2.fitness, o1.fitness); | 181 | Object lastState = null; |
182 | |||
183 | //if(configuration) | ||
184 | visualiseCurrentState(); | ||
185 | // the two is the True and False node generated at the beginning of the generation | ||
186 | int count = 0; | ||
187 | mainLoop: while (!isInterrupted && !configuration.progressMonitor.isCancelled()) { | ||
188 | |||
189 | if (currentTrajectoryWithFittness == null) { | ||
190 | if (trajectoiresToExplore.isEmpty()) { | ||
191 | logger.debug("State space is fully traversed."); | ||
192 | return; | ||
193 | } else { | ||
194 | currentTrajectoryWithFittness = selectState(); | ||
195 | if (logger.isDebugEnabled()) { | ||
196 | logger.debug("Current trajectory: " + Arrays.toString(context.getTrajectory().toArray())); | ||
197 | logger.debug("New trajectory is chosen: " + currentTrajectoryWithFittness); | ||
198 | } | ||
199 | context.getDesignSpaceManager().executeTrajectoryWithMinimalBacktrackWithoutStateCoding(currentTrajectoryWithFittness.trajectory); | ||
200 | |||
201 | // reset the regression for this trajectory | ||
202 | metricDistance.getLinearModel().resetRegression(context.getCurrentStateId()); | ||
134 | } | 203 | } |
135 | }; | 204 | } |
136 | 205 | ||
137 | this.solutionStoreWithCopy = new SolutionStoreWithCopy(); | 206 | List<Object> activationIds = selectActivation(); |
138 | this.solutionStoreWithDiversityDescriptor = new SolutionStoreWithDiversityDescriptor(configuration.diversityRequirement); | 207 | PartialInterpretation model = (PartialInterpretation) context.getModel(); |
208 | System.out.println(model.getNewElements().size()); | ||
209 | System.out.println("# violations: " + getNumberOfViolations(mayMatchers)); | ||
139 | 210 | ||
140 | trajectoiresToExplore = new PriorityQueue<TrajectoryWithFitness>(11, comparator); | 211 | Map<Object, Double> valueMap = new HashMap<Object,Double>(); |
141 | stateAndActivations = new HashMap<Object, List<Object>>(); | ||
142 | metricDistance = new PartialInterpretationMetricDistance(domain); | ||
143 | 212 | ||
144 | //set whether allows must violations during the realistic generation | 213 | //init epsilon and draw |
145 | allowMustViolation = configuration.allowMustViolations; | 214 | MetricDistanceGroup heuristics = metricDistance.calculateMetricDistanceKS(model); |
146 | targetSize = configuration.typeScopes.maxNewElements + 2; | ||
147 | } | ||
148 | 215 | ||
149 | @Override | 216 | if(!stateAndActivations.containsKey(context.getCurrentStateId())) { |
150 | public void explore() { | 217 | stateAndActivations.put(context.getCurrentStateId(), new ArrayList<Object>()); |
151 | if (!context.checkGlobalConstraints()) { | ||
152 | logger.info("Global contraint is not satisifed in the first state. Terminate."); | ||
153 | return; | ||
154 | } | ||
155 | if (configuration.searchSpaceConstraints.maxDepth == 0) { | ||
156 | logger.info("Maximal depth is reached in the initial solution. Terminate."); | ||
157 | return; | ||
158 | } | 218 | } |
159 | 219 | ||
160 | final Fitness firstFittness = context.calculateFitness(); | 220 | // calculate values for epsilon greedy |
161 | 221 | double epsilon = 1.0/count; | |
162 | //final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper(); | 222 | double draw = Math.random(); |
163 | final Object[] firstTrajectory = context.getTrajectory().toArray(new Object[0]); | 223 | count++; |
164 | TrajectoryWithFitness currentTrajectoryWithFittness = new TrajectoryWithFitness(firstTrajectory, firstFittness); | 224 | this.currentNodeTypeDistance = heuristics.getNodeTypeDistance(); |
165 | trajectoiresToExplore.add(currentTrajectoryWithFittness); | 225 | numNodesToGenerate = model.getMaxNewElements(); |
166 | Object lastState = null; | 226 | System.out.println("NA distance: " + heuristics.getNADistance()); |
167 | 227 | System.out.println("MPC distance: " + heuristics.getMPCDistance()); | |
168 | //if(configuration) | 228 | System.out.println("Out degree distance:" + heuristics.getOutDegreeDistance()); |
169 | visualiseCurrentState(); | 229 | System.out.println("NodeType :" + currentNodeTypeDistance); |
170 | // the two is the True and False node generated at the beginning of the generation | ||
171 | int count = 0; | ||
172 | mainLoop: while (!isInterrupted && !configuration.progressMonitor.isCancelled()) { | ||
173 | 230 | ||
174 | if (currentTrajectoryWithFittness == null) { | ||
175 | if (trajectoiresToExplore.isEmpty()) { | ||
176 | logger.debug("State space is fully traversed."); | ||
177 | return; | ||
178 | } else { | ||
179 | currentTrajectoryWithFittness = selectState(); | ||
180 | if (logger.isDebugEnabled()) { | ||
181 | logger.debug("Current trajectory: " + Arrays.toString(context.getTrajectory().toArray())); | ||
182 | logger.debug("New trajectory is chosen: " + currentTrajectoryWithFittness); | ||
183 | } | ||
184 | context.getDesignSpaceManager().executeTrajectoryWithMinimalBacktrackWithoutStateCoding(currentTrajectoryWithFittness.trajectory); | ||
185 | |||
186 | // reset the regression for this trajectory | ||
187 | metricDistance.getLinearModel().resetRegression(context.getCurrentStateId()); | ||
188 | } | ||
189 | } | ||
190 | |||
191 | List<Object> activationIds = selectActivation(); | ||
192 | PartialInterpretation model = (PartialInterpretation) context.getModel(); | ||
193 | // System.out.println(model.getNewElements().size()); | ||
194 | // System.out.println("# violations: " + getNumberOfViolations(mayMatchers)); | ||
195 | |||
196 | Map<Object, Double> valueMap = new HashMap<Object,Double>(); | ||
197 | |||
198 | //init epsilon and draw | ||
199 | MetricDistanceGroup heuristics = metricDistance.calculateMetricDistanceKS(model); | ||
200 | 231 | ||
201 | if(!stateAndActivations.containsKey(context.getCurrentStateId())) { | 232 | //TODO: the number of activations to be checked should be configurasble |
202 | stateAndActivations.put(context.getCurrentStateId(), new ArrayList<Object>()); | 233 | if(activationIds.size() > 50) { |
203 | } | 234 | activationIds = activationIds.subList(0, 50); |
235 | } | ||
236 | |||
237 | valueMap = sortWithWeight(activationIds); | ||
238 | lastState = context.getCurrentStateId(); | ||
239 | while (!isInterrupted && !configuration.progressMonitor.isCancelled() && activationIds.size() > 0) { | ||
240 | final Object nextActivation = drawWithEpsilonProbabilty(activationIds, valueMap, epsilon, draw); | ||
241 | |||
242 | stateAndActivations.get(context.getCurrentStateId()).add(nextActivation); | ||
243 | logger.debug("Executing new activation: " + nextActivation); | ||
244 | context.executeAcitvationId(nextActivation); | ||
245 | visualiseCurrentState(); | ||
246 | boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFittness); | ||
247 | if(consistencyCheckResult == true) { continue mainLoop; } | ||
204 | 248 | ||
205 | // calculate values for epsilon greedy | 249 | // if (context.isCurrentStateAlreadyTraversed()) { |
206 | double epsilon = 1.0/count; | 250 | // logger.info("The new state is already visited."); |
207 | double draw = Math.random(); | 251 | // context.backtrack(); |
208 | count++; | 252 | // } else if (!checkGlobalConstraints()) { |
209 | this.currentNodeTypeDistance = heuristics.getNodeTypeDistance(); | 253 | // logger.debug("Global contraint is not satisifed."); |
210 | numNodesToGenerate = model.getMaxNewElements(); | 254 | // context.backtrack(); |
211 | // System.out.println("NA distance: " + heuristics.getNADistance()); | 255 | // } |
212 | // System.out.println("MPC distance: " + heuristics.getMPCDistance()); | ||
213 | // System.out.println("Out degree distance:" + heuristics.getOutDegreeDistance()); | ||
214 | // System.out.println("NodeType :" + currentNodeTypeDistance); | ||
215 | |||
216 | |||
217 | //TODO: the number of activations to be checked should be configurasble | ||
218 | if(activationIds.size() > 50) { | ||
219 | activationIds = activationIds.subList(0, 50); | ||
220 | } | ||
221 | 256 | ||
222 | valueMap = sortWithWeight(activationIds); | 257 | int currentSize = model.getNewElements().size(); |
223 | lastState = context.getCurrentStateId(); | 258 | int targetDiff = targetSize - currentSize; |
224 | while (!isInterrupted && !configuration.progressMonitor.isCancelled() && activationIds.size() > 0) { | 259 | boolean shouldFinish = currentSize >= targetSize; |
225 | final Object nextActivation = drawWithEpsilonProbabilty(activationIds, valueMap, epsilon, draw); | 260 | |
226 | 261 | // does not allow must violations | |
227 | stateAndActivations.get(context.getCurrentStateId()).add(nextActivation); | 262 | if((getNumberOfViolations(mustMatchers) > 0|| getNumberOfViolations(mayMatchers) > targetDiff) && !allowMustViolation && !shouldFinish) { |
228 | logger.debug("Executing new activation: " + nextActivation); | 263 | context.backtrack(); |
229 | context.executeAcitvationId(nextActivation); | 264 | }else { |
230 | visualiseCurrentState(); | 265 | final Fitness nextFitness = context.calculateFitness(); |
231 | boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFittness); | ||
232 | if(consistencyCheckResult == true) { continue mainLoop; } | ||
233 | |||
234 | int currentSize = model.getNewElements().size(); | ||
235 | int targetDiff = targetSize - currentSize; | ||
236 | boolean shouldFinish = currentSize >= targetSize; | ||
237 | 266 | ||
238 | // does not allow must violations | 267 | // the only hard objectives are configured in the config file |
239 | if((getNumberOfViolations(mustMatchers) > 0|| getNumberOfViolations(mayMatchers) > targetDiff) && !allowMustViolation && !shouldFinish) { | 268 | checkForSolution(nextFitness); |
269 | |||
270 | if (context.getDepth() > configuration.searchSpaceConstraints.maxDepth) { | ||
271 | logger.debug("Reached max depth."); | ||
240 | context.backtrack(); | 272 | context.backtrack(); |
241 | }else { | 273 | continue; |
242 | final Fitness nextFitness = context.calculateFitness(); | ||
243 | |||
244 | // the only hard objectives are configured in the config file | ||
245 | checkForSolution(nextFitness); | ||
246 | |||
247 | if (context.getDepth() > configuration.searchSpaceConstraints.maxDepth) { | ||
248 | logger.debug("Reached max depth."); | ||
249 | context.backtrack(); | ||
250 | continue; | ||
251 | } | ||
252 | |||
253 | //Record value for current trajectory | ||
254 | TrajectoryWithFitness nextTrajectoryWithFittness = new TrajectoryWithFitness( | ||
255 | context.getTrajectory().toArray(), nextFitness); | ||
256 | int nodeSize = ((PartialInterpretation) context.getModel()).getNewElements().size(); | ||
257 | int violation = getNumberOfViolations(mayMatchers); | ||
258 | double currentValue = calculateCurrentStateValue(nodeSize, violation); | ||
259 | metricDistance.getLinearModel().feedData(context.getCurrentStateId(), metricDistance.calculateFeature(nodeSize, violation), currentValue, lastState); | ||
260 | trajectoiresToExplore.add(nextTrajectoryWithFittness); | ||
261 | currentStateValue = currentValue; | ||
262 | //Currently, just go to the next state without considering the value of trajectory | ||
263 | currentTrajectoryWithFittness = nextTrajectoryWithFittness; | ||
264 | continue mainLoop; | ||
265 | |||
266 | } | 274 | } |
275 | |||
276 | //Record value for current trajectory | ||
277 | TrajectoryWithFitness nextTrajectoryWithFittness = new TrajectoryWithFitness( | ||
278 | context.getTrajectory().toArray(), nextFitness); | ||
279 | int nodeSize = ((PartialInterpretation) context.getModel()).getNewElements().size(); | ||
280 | int violation = getNumberOfViolations(mayMatchers); | ||
281 | double currentValue = calculateCurrentStateValue(nodeSize, violation); | ||
282 | metricDistance.getLinearModel().feedData(context.getCurrentStateId(), metricDistance.calculateFeature(nodeSize, violation), currentValue, lastState); | ||
283 | trajectoiresToExplore.add(nextTrajectoryWithFittness); | ||
284 | currentStateValue = currentValue; | ||
285 | //Currently, just go to the next state without considering the value of trajectory | ||
286 | currentTrajectoryWithFittness = nextTrajectoryWithFittness; | ||
287 | continue mainLoop; | ||
288 | |||
267 | } | 289 | } |
268 | logger.debug("State is fully traversed."); | ||
269 | trajectoiresToExplore.remove(currentTrajectoryWithFittness); | ||
270 | currentTrajectoryWithFittness = null; | ||
271 | context.backtrack(); | ||
272 | } | 290 | } |
273 | logger.info("Interrupted."); | 291 | logger.debug("State is fully traversed."); |
292 | trajectoiresToExplore.remove(currentTrajectoryWithFittness); | ||
293 | currentTrajectoryWithFittness = null; | ||
294 | context.backtrack(); | ||
274 | } | 295 | } |
296 | logger.info("Interrupted."); | ||
297 | } | ||
275 | 298 | ||
276 | /** | 299 | private boolean checkGlobalConstraints() { |
277 | * | 300 | long start = System.nanoTime(); |
278 | * @param activationIds | 301 | boolean result = context.checkGlobalConstraints(); |
279 | * @return: activation to value map | 302 | globalConstraintEvaluationTime += System.nanoTime() - start; |
280 | */ | 303 | return result; |
281 | private Map<Object, Double> sortWithWeight(List<Object> activationIds){ | 304 | } |
282 | Map<Object, Double> valueMap = new HashMap<Object, Double>(); | 305 | |
283 | Object currentId = context.getCurrentStateId(); | 306 | private Fitness calculateFitness() { |
284 | // check for next states | 307 | long start = System.nanoTime(); |
285 | for(Object id : activationIds) { | 308 | Fitness fitness = context.calculateFitness(); |
286 | context.executeAcitvationId(id); | 309 | fitnessCalculationTime += System.nanoTime() - start; |
287 | int violation = getNumberOfViolations(mayMatchers); | 310 | return fitness; |
311 | } | ||
312 | |||
313 | /** | ||
314 | * | ||
315 | * @param activationIds | ||
316 | * @return: activation to value map | ||
317 | */ | ||
318 | private Map<Object, Double> sortWithWeight(List<Object> activationIds){ | ||
319 | Map<Object, Double> valueMap = new HashMap<Object, Double>(); | ||
320 | Object currentId = context.getCurrentStateId(); | ||
321 | // check for next states | ||
322 | for(Object id : activationIds) { | ||
323 | context.executeAcitvationId(id); | ||
324 | int violation = getNumberOfViolations(mayMatchers); | ||
288 | 325 | ||
289 | if(!allowMustViolation && getNumberOfViolations(mustMatchers) > 0) { | 326 | if(!allowMustViolation && getNumberOfViolations(mustMatchers) > 0) { |
290 | valueMap.put(id, Double.MAX_VALUE); | 327 | valueMap.put(id, Double.MAX_VALUE); |
291 | stateAndActivations.get(currentId).add(id); | 328 | stateAndActivations.get(currentId).add(id); |
292 | }else { | 329 | }else { |
293 | valueMap.put(id, calculateFutureStateValue(violation)); | 330 | valueMap.put(id, calculateFutureStateValue(violation)); |
294 | } | ||
295 | |||
296 | |||
297 | |||
298 | context.backtrack(); | ||
299 | } | 331 | } |
332 | |||
333 | |||
300 | 334 | ||
301 | //remove all the elements having large distance | 335 | context.backtrack(); |
302 | Collections.sort(activationIds, Comparator.comparing(li -> valueMap.get(li))); | ||
303 | return valueMap; | ||
304 | } | 336 | } |
305 | 337 | ||
306 | private double calculateFutureStateValue(int violation) { | 338 | //remove all the elements having large distance |
307 | long start = System.nanoTime(); | 339 | Collections.sort(activationIds, Comparator.comparing(li -> valueMap.get(li))); |
308 | int nodeSize = ((PartialInterpretation) context.getModel()).getNewElements().size(); | 340 | return valueMap; |
309 | double currentValue = calculateCurrentStateValue(nodeSize,violation); | 341 | } |
310 | double[] toPredict = metricDistance.calculateFeature(100, violation); | 342 | |
311 | if(Math.abs(currentValue - currentStateValue) < 0.001) { | 343 | private double calculateFutureStateValue(int violation) { |
312 | this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start); | 344 | long start = System.nanoTime(); |
313 | return Double.MAX_VALUE; | 345 | int nodeSize = ((PartialInterpretation) context.getModel()).getNewElements().size(); |
314 | } | 346 | double currentValue = calculateCurrentStateValue(nodeSize,violation); |
315 | try { | 347 | double[] toPredict = metricDistance.calculateFeature(100, violation); |
316 | this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start); | 348 | if(Math.abs(currentValue - currentStateValue) < 0.001) { |
317 | return metricDistance.getLinearModel().getPredictionForNextDataSample(metricDistance.calculateFeature(nodeSize, violation), currentValue, toPredict); | 349 | this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start); |
318 | }catch(IllegalArgumentException e) { | 350 | return Double.MAX_VALUE; |
319 | this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start); | 351 | } |
320 | return currentValue; | 352 | try { |
321 | } | 353 | this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start); |
322 | 354 | return metricDistance.getLinearModel().getPredictionForNextDataSample(metricDistance.calculateFeature(nodeSize, violation), currentValue, toPredict); | |
355 | }catch(IllegalArgumentException e) { | ||
356 | this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start); | ||
357 | return currentValue; | ||
323 | } | 358 | } |
324 | private double calculateCurrentStateValue(int factor, int violation) { | ||
325 | PartialInterpretation model = (PartialInterpretation) context.getModel(); | ||
326 | MetricDistanceGroup g = metricDistance.calculateMetricDistanceKS(model); | ||
327 | if(configuration.realisticGuidance == RealisticGuidance.MPC) { | ||
328 | return g.getMPCDistance(); | ||
329 | }else if(configuration.realisticGuidance == RealisticGuidance.NodeActivity) { | ||
330 | return g.getNADistance(); | ||
331 | }else if(configuration.realisticGuidance == RealisticGuidance.OutDegree) { | ||
332 | return g.getOutDegreeDistance(); | ||
333 | }else if(configuration.realisticGuidance == RealisticGuidance.NodeType) { | ||
334 | return g.getNodeTypeDistance(); | ||
335 | }else if(configuration.realisticGuidance == RealisticGuidance.Composite) { | ||
336 | double consistenceWeights = 5 * factor / (configuration.typeScopes.maxNewElements + 2) * (1- 1.0/(1+violation)); | ||
337 | if(domain == Domain.Yakindumm) { | ||
338 | double unfinishFactor = 50 * (1 - (double)factor / targetSize); | ||
339 | double nodeTypeFactor = g.getNodeTypeDistance(); | ||
340 | double normalFactor = 5; | ||
341 | if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) { | ||
342 | nodeTypeFactor = 0; | ||
343 | normalFactor = 100; | ||
344 | unfinishFactor = 0; | ||
345 | } | ||
346 | |||
347 | return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor; | ||
348 | }else if (domain == Domain.Ecore) { | ||
349 | double unfinishFactor = 100 * (1 - (double)factor / targetSize); | ||
350 | double nodeTypeFactor = g.getNodeTypeDistance(); | ||
351 | double normalFactor = 5; | ||
352 | if(currentNodeTypeDistance <= 0.12 || numNodesToGenerate == 1) { | ||
353 | nodeTypeFactor = 0; | ||
354 | normalFactor = 100; | ||
355 | unfinishFactor *= 0.5; | ||
356 | } | ||
357 | |||
358 | return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor; | ||
359 | }else { | ||
360 | double unfinishFactor = context.calculateFitness().get("CompositeUnfinishednessObjective"); | ||
361 | double nodeTypeFactor = g.getNodeTypeDistance(); | ||
362 | double normalFactor = 5; | ||
363 | if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) { | ||
364 | nodeTypeFactor = 0; | ||
365 | normalFactor = 100; | ||
366 | //unfinishFactor *= 0.5; | ||
367 | } | ||
368 | |||
369 | return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + 2*g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor; | ||
370 | } | ||
371 | 359 | ||
372 | }else if(configuration.realisticGuidance == RealisticGuidance.Composite_Without_Violations) { | 360 | } |
373 | if(domain == Domain.Yakindumm) { | 361 | private double calculateCurrentStateValue(int factor, int violation) { |
374 | double unfinishFactor = 50 * (1 - (double)factor / targetSize); | 362 | PartialInterpretation model = (PartialInterpretation) context.getModel(); |
375 | double nodeTypeFactor = g.getNodeTypeDistance(); | 363 | MetricDistanceGroup g = metricDistance.calculateMetricDistanceKS(model); |
376 | double normalFactor = 5; | 364 | if(configuration.realisticGuidance == RealisticGuidance.MPC) { |
377 | if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) { | 365 | return g.getMPCDistance(); |
378 | nodeTypeFactor = 0; | 366 | }else if(configuration.realisticGuidance == RealisticGuidance.NodeActivity) { |
379 | normalFactor = 100; | 367 | return g.getNADistance(); |
380 | unfinishFactor = 0; | 368 | }else if(configuration.realisticGuidance == RealisticGuidance.OutDegree) { |
381 | } | 369 | return g.getOutDegreeDistance(); |
382 | 370 | }else if(configuration.realisticGuidance == RealisticGuidance.NodeType) { | |
383 | return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor; | 371 | return g.getNodeTypeDistance(); |
384 | }else if (domain == Domain.Github) { | 372 | }else if(configuration.realisticGuidance == RealisticGuidance.Composite) { |
385 | double unfinishFactor = 100 * (1 - (double)factor / targetSize); | 373 | double consistenceWeights = 5 * factor / (configuration.typeScopes.maxNewElements + 2) * (1- 1.0/(1+violation)); |
386 | double nodeTypeFactor = g.getNodeTypeDistance(); | 374 | if(domain == Domain.Yakindumm) { |
387 | double normalFactor = 5; | 375 | double unfinishFactor = 50 * (1 - (double)factor / targetSize); |
388 | if(currentNodeTypeDistance <= 0.12 || numNodesToGenerate == 1) { | 376 | double nodeTypeFactor = g.getNodeTypeDistance(); |
389 | nodeTypeFactor = 0; | 377 | double normalFactor = 5; |
390 | normalFactor = 100; | 378 | if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) { |
391 | unfinishFactor *= 0.5; | 379 | nodeTypeFactor = 0; |
392 | } | 380 | normalFactor = 100; |
393 | 381 | unfinishFactor = 0; | |
394 | return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor; | ||
395 | } else { | ||
396 | double unfinishFactor = 100 * (1 - (double)factor / targetSize); | ||
397 | double nodeTypeFactor = g.getNodeTypeDistance(); | ||
398 | double normalFactor = 5; | ||
399 | if(currentNodeTypeDistance <= 0.20 || numNodesToGenerate == 1) { | ||
400 | nodeTypeFactor = 0; | ||
401 | normalFactor = 100; | ||
402 | unfinishFactor *= 0.5; | ||
403 | } | ||
404 | |||
405 | return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor; | ||
406 | } | 382 | } |
383 | |||
384 | return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor; | ||
385 | }else if (domain == Domain.Ecore) { | ||
386 | double unfinishFactor = 100 * (1 - (double)factor / targetSize); | ||
387 | double nodeTypeFactor = g.getNodeTypeDistance(); | ||
388 | double normalFactor = 5; | ||
389 | if(currentNodeTypeDistance <= 0.12 || numNodesToGenerate == 1) { | ||
390 | nodeTypeFactor = 0; | ||
391 | normalFactor = 100; | ||
392 | unfinishFactor *= 0.5; | ||
393 | } | ||
394 | |||
395 | return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor; | ||
407 | }else { | 396 | }else { |
408 | return violation; | 397 | double unfinishFactor = context.calculateFitness().get("CompositeUnfinishednessObjective"); |
409 | } | 398 | double nodeTypeFactor = g.getNodeTypeDistance(); |
410 | } | 399 | double normalFactor = 5; |
411 | 400 | if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) { | |
412 | private int getNumberOfViolations(Collection<ViatraQueryMatcher<? extends IPatternMatch>> matchers) { | 401 | nodeTypeFactor = 0; |
413 | int violations = matchers.stream().mapToInt(m -> m.countMatches()).sum(); | 402 | normalFactor = 100; |
414 | 403 | //unfinishFactor *= 0.5; | |
415 | return violations; | 404 | } |
416 | } | 405 | |
417 | 406 | return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + 2*g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor; | |
418 | // Modified epsilon greedy choose for action based on value function | ||
419 | // with probability epsilon, choose the state with probability based on the weight | ||
420 | // with probability 1 - epsilon, choose the best state | ||
421 | // epsilon should decay w.r.t. time | ||
422 | private Object drawWithEpsilonProbabilty(List<Object> activationIds, Map<Object, Double> valueMap, double epsilon, double currentDraw) { | ||
423 | if(activationIds.size() <= 0) { | ||
424 | return null; | ||
425 | } | 407 | } |
426 | 408 | ||
427 | // if epsilon is smaller than current draw, return greedy choice | 409 | }else if(configuration.realisticGuidance == RealisticGuidance.Composite_Without_Violations) { |
428 | if(epsilon < currentDraw) { | 410 | if(domain == Domain.Yakindumm) { |
429 | return activationIds.remove(0); | 411 | double unfinishFactor = 50 * (1 - (double)factor / targetSize); |
430 | }else { | 412 | double nodeTypeFactor = g.getNodeTypeDistance(); |
431 | //else return draw with probability of the weights | 413 | double normalFactor = 5; |
432 | //find the sum of all 1-weights: the smaller the better | 414 | if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) { |
433 | double sum = valueMap.values().stream().mapToDouble(d->1).sum(); | 415 | nodeTypeFactor = 0; |
434 | double rand = Math.random() * sum; | 416 | normalFactor = 100; |
435 | double iterator = 0.0; | 417 | unfinishFactor = 0; |
436 | Object idToReturn = null; | 418 | } |
437 | 419 | ||
438 | // draw an item with probability | 420 | return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor; |
439 | for(Object o : valueMap.keySet()) { | 421 | }else if (domain == Domain.Github) { |
440 | iterator += (1); | 422 | double unfinishFactor = 100 * (1 - (double)factor / targetSize); |
441 | if(rand < iterator) { | 423 | double nodeTypeFactor = g.getNodeTypeDistance(); |
442 | idToReturn = o; | 424 | double normalFactor = 5; |
443 | break; | 425 | if(currentNodeTypeDistance <= 0.12 || numNodesToGenerate == 1) { |
444 | } | 426 | nodeTypeFactor = 0; |
427 | normalFactor = 100; | ||
428 | unfinishFactor *= 0.5; | ||
429 | } | ||
430 | |||
431 | return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor; | ||
432 | } else { | ||
433 | double unfinishFactor = 100 * (1 - (double)factor / targetSize); | ||
434 | double nodeTypeFactor = g.getNodeTypeDistance(); | ||
435 | double normalFactor = 5; | ||
436 | if(currentNodeTypeDistance <= 0.20 || numNodesToGenerate == 1) { | ||
437 | nodeTypeFactor = 0; | ||
438 | normalFactor = 100; | ||
439 | unfinishFactor *= 0.5; | ||
445 | } | 440 | } |
446 | 441 | ||
447 | //delete the item from the list | 442 | return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor; |
448 | activationIds.remove(idToReturn); | ||
449 | valueMap.remove(idToReturn); | ||
450 | return idToReturn; | ||
451 | } | 443 | } |
444 | }else { | ||
445 | return violation; | ||
452 | } | 446 | } |
447 | } | ||
448 | |||
449 | private int getNumberOfViolations(Collection<ViatraQueryMatcher<? extends IPatternMatch>> matchers) { | ||
450 | int violations = matchers.stream().mapToInt(m -> m.countMatches()).sum(); | ||
453 | 451 | ||
454 | private List<Object> selectActivation() { | 452 | return violations; |
455 | List<Object> activationIds; | 453 | } |
456 | try { | 454 | |
457 | activationIds = new ArrayList<Object>(context.getCurrentActivationIds()); | 455 | // Modified epsilon greedy choose for action based on value function |
458 | if(stateAndActivations.containsKey(context.getCurrentStateId())) { | 456 | // with probability epsilon, choose the state with probability based on the weight |
459 | activationIds.removeAll(stateAndActivations.get(context.getCurrentStateId())); | 457 | // with probability 1 - epsilon, choose the best state |
458 | // epsilon should decay w.r.t. time | ||
459 | private Object drawWithEpsilonProbabilty(List<Object> activationIds, Map<Object, Double> valueMap, double epsilon, double currentDraw) { | ||
460 | if(activationIds.size() <= 0) { | ||
461 | return null; | ||
462 | } | ||
463 | |||
464 | // if epsilon is smaller than current draw, return greedy choice | ||
465 | if(epsilon < currentDraw) { | ||
466 | return activationIds.remove(0); | ||
467 | }else { | ||
468 | //else return draw with probability of the weights | ||
469 | //find the sum of all 1-weights: the smaller the better | ||
470 | double sum = valueMap.values().stream().mapToDouble(d->1).sum(); | ||
471 | double rand = Math.random() * sum; | ||
472 | double iterator = 0.0; | ||
473 | Object idToReturn = null; | ||
474 | |||
475 | // draw an item with probability | ||
476 | for(Object o : valueMap.keySet()) { | ||
477 | iterator += (1); | ||
478 | if(rand < iterator) { | ||
479 | idToReturn = o; | ||
480 | break; | ||
460 | } | 481 | } |
461 | Collections.shuffle(activationIds); | ||
462 | } catch (NullPointerException e) { | ||
463 | numberOfStatecoderFail++; | ||
464 | activationIds = Collections.emptyList(); | ||
465 | } | 482 | } |
466 | return activationIds; | 483 | |
484 | //delete the item from the list | ||
485 | activationIds.remove(idToReturn); | ||
486 | valueMap.remove(idToReturn); | ||
487 | return idToReturn; | ||
467 | } | 488 | } |
489 | } | ||
490 | |||
491 | private List<Object> selectActivation() { | ||
492 | List<Object> activationIds; | ||
493 | try { | ||
494 | activationIds = this.activationSelector.randomizeActivationIDs(context.getUntraversedActivationIds()); | ||
495 | } catch (NullPointerException e) { | ||
496 | numberOfStatecoderFail++; | ||
497 | activationIds = Collections.emptyList(); | ||
498 | } | ||
499 | return activationIds; | ||
500 | } | ||
468 | 501 | ||
469 | private void checkForSolution(final Fitness fittness) { | 502 | private void checkForSolution(final Fitness fittness) { |
470 | if (fittness.isSatisifiesHardObjectives()) { | 503 | if (fittness.isSatisifiesHardObjectives()) { |
471 | logger.debug("Solution Found!!"); | 504 | logger.debug("Solution Found!!"); |
472 | logger.debug("# violations: " + (getNumberOfViolations(mustMatchers))); | 505 | logger.debug("# violations: " + (getNumberOfViolations(mustMatchers))); |
473 | if (solutionStoreWithDiversityDescriptor.isDifferent(context)) { | 506 | if (solutionStoreWithDiversityDescriptor.isDifferent(context)) { |
474 | solutionStoreWithCopy.newSolution(context); | 507 | solutionStoreWithCopy.newSolution(context); |
475 | solutionStoreWithDiversityDescriptor.newSolution(context); | 508 | solutionStoreWithDiversityDescriptor.newSolution(context); |
476 | solutionStore.newSolution(context); | 509 | solutionStore.newSolution(context); |
477 | configuration.progressMonitor.workedModelFound(configuration.solutionScope.numberOfRequiredSolution); | 510 | configuration.progressMonitor.workedModelFound(configuration.solutionScope.numberOfRequiredSolutions); |
478 | 511 | ||
479 | logger.debug("Found a solution."); | 512 | logger.debug("Found a solution."); |
480 | } | ||
481 | } | 513 | } |
482 | } | 514 | } |
515 | } | ||
516 | |||
517 | public List<String> times = new LinkedList<String>(); | ||
518 | private void saveTimes() { | ||
519 | long forwardTime = context.getDesignSpaceManager().getForwardTime()/1000000; | ||
520 | long backtrackingTime = context.getDesignSpaceManager().getBacktrackingTime()/1000000; | ||
521 | long statecoderTime = ((NeighbourhoodBasedPartialInterpretationStateCoder)this.context.getStateCoder()).getStatecoderRuntime()/1000000; | ||
522 | long solutionCopy = solutionStoreWithCopy.getSumRuntime()/1000000; | ||
523 | long activationSelection = this.activationSelector.getRuntime()/1000000; | ||
524 | // long numericalSolverSumTime = this.numericSolver.getRuntime()/1000000; | ||
525 | // long numericalSolverProblemForming = this.numericSolver.getSolverSolvingProblem()/1000000; | ||
526 | // long numericalSolverSolving = this.numericSolver.getSolverSolvingProblem()/1000000; | ||
527 | // long numericalSolverInterpreting = this.numericSolver.getSolverSolution()/1000000; | ||
528 | long metricCalculationTime = this.method.getStatistics().metricCalculationTime / 1000000; | ||
529 | this.times.add( | ||
530 | "(TransformationExecutionTime"+method.getStatistics().transformationExecutionTime/1000000+ | ||
531 | "|ForwardTime:"+forwardTime+ | ||
532 | "|Backtrackingtime:"+backtrackingTime+ | ||
533 | "|StateCoderTime:"+statecoderTime+ | ||
534 | "|SolutionCopyTime:"+solutionCopy+ | ||
535 | "|ActivationSelectionTime:"+activationSelection+ | ||
536 | //"|NumericalSolverSumTime:"+numericalSolverSumTime+ | ||
537 | //"|NumericalSolverProblemFormingTime:"+numericalSolverProblemForming+ | ||
538 | //"|NumericalSolverSolvingTime:"+numericalSolverSolving+ | ||
539 | //"|NumericalSolverInterpretingSolution:"+numericalSolverInterpreting+ | ||
540 | "|MetricCalculationTime:"+metricCalculationTime + ")" | ||
541 | ); | ||
542 | |||
543 | } | ||
483 | 544 | ||
484 | @Override | 545 | @Override |
485 | public void interruptStrategy() { | 546 | public void interruptStrategy() { |
486 | isInterrupted = true; | 547 | isInterrupted = true; |
487 | } | 548 | } |
488 | 549 | ||
489 | 550 | ||
490 | private TrajectoryWithFitness selectState() { | 551 | private TrajectoryWithFitness selectState() { |
491 | int randomNumber = random.nextInt(configuration.randomBacktrackChance); | 552 | int randomNumber = random.nextInt(configuration.randomBacktrackChance); |
492 | if (randomNumber == 0) { | 553 | if (randomNumber == 0) { |
493 | int elements = trajectoiresToExplore.size(); | 554 | int elements = trajectoiresToExplore.size(); |
494 | int randomElementIndex = random.nextInt(elements); | 555 | int randomElementIndex = random.nextInt(elements); |
495 | logger.debug("Randomly backtract to the " + randomElementIndex + " best solution..."); | 556 | logger.debug("Randomly backtract to the " + randomElementIndex + " best solution..."); |
496 | Iterator<TrajectoryWithFitness> iterator = trajectoiresToExplore.iterator(); | 557 | Iterator<TrajectoryWithFitness> iterator = trajectoiresToExplore.iterator(); |
497 | while (randomElementIndex != 0) { | 558 | while (randomElementIndex != 0) { |
498 | iterator.next(); | 559 | iterator.next(); |
499 | randomElementIndex--; | 560 | randomElementIndex--; |
500 | } | 561 | } |
501 | TrajectoryWithFitness res = iterator.next(); | 562 | TrajectoryWithFitness res = iterator.next(); |
502 | if (res == null) { | 563 | if (res == null) { |
503 | return trajectoiresToExplore.element(); | ||
504 | } else { | ||
505 | return res; | ||
506 | } | ||
507 | } else { | ||
508 | return trajectoiresToExplore.element(); | 564 | return trajectoiresToExplore.element(); |
565 | } else { | ||
566 | return res; | ||
509 | } | 567 | } |
510 | } | 568 | } else { |
511 | 569 | return trajectoiresToExplore.element(); | |
570 | } | ||
571 | } | ||
572 | |||
512 | // private void logCurrentStateMetric() { | 573 | // private void logCurrentStateMetric() { |
513 | // if(this.configuration.documentationLevel != DocumentationLevel.NONE || workspace == null) { | 574 | // if(this.configuration.documentationLevel != DocumentationLevel.NONE || workspace == null) { |
514 | // return; | 575 | // return; |
@@ -518,77 +579,80 @@ public class HillClimbingOnRealisticMetricStrategyForModelGeneration implements | |||
518 | // PartialInterpretationMetric.calculateMetric(interpretation, "debug/metric/" + context.getModel().hashCode(), context.getCurrentStateId().toString()); | 579 | // PartialInterpretationMetric.calculateMetric(interpretation, "debug/metric/" + context.getModel().hashCode(), context.getCurrentStateId().toString()); |
519 | // } | 580 | // } |
520 | 581 | ||
521 | public void visualiseCurrentState() { | 582 | public void visualiseCurrentState() { |
522 | PartialInterpretationVisualiser partialInterpretatioVisualiser = configuration.debugCongiguration.partialInterpretatioVisualiser; | 583 | PartialInterpretationVisualiser partialInterpretatioVisualiser = configuration.debugConfiguration.partialInterpretatioVisualiser; |
523 | if(partialInterpretatioVisualiser != null && this.configuration.documentationLevel == DocumentationLevel.FULL && workspace != null) { | 584 | if(partialInterpretatioVisualiser != null && this.configuration.documentationLevel == DocumentationLevel.FULL && workspace != null) { |
524 | PartialInterpretation p = (PartialInterpretation) (context.getModel()); | 585 | PartialInterpretation p = (PartialInterpretation) (context.getModel()); |
525 | int id = ++numberOfPrintedModel; | 586 | int id = ++numberOfPrintedModel; |
526 | if (id % configuration.debugCongiguration.partalInterpretationVisualisationFrequency == 0) { | 587 | if (id % configuration.debugConfiguration.partalInterpretationVisualisationFrequency == 0) { |
527 | PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p); | 588 | PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p); |
528 | visualisation.writeToFile(workspace, String.format("state%09d.png", id)); | 589 | logger.debug("Visualizing state: " + id + " (" + context.getDesignSpaceManager().getCurrentState() + ")"); |
529 | } | 590 | String name = String.format("state%09d", id); |
591 | visualisation.writeToFile(workspace, name + ".png"); | ||
592 | workspace.writeModel((EObject) context.getModel(), name + ".xmi"); | ||
530 | } | 593 | } |
531 | } | 594 | } |
595 | } | ||
532 | 596 | ||
533 | protected boolean checkConsistency(TrajectoryWithFitness t) { | 597 | protected boolean checkConsistency(TrajectoryWithFitness t) { |
534 | LogicReasoner internalIncosnsitencyDetector = configuration.internalConsistencyCheckerConfiguration.internalIncosnsitencyDetector; | 598 | LogicReasoner internalIncosnsitencyDetector = configuration.internalConsistencyCheckerConfiguration.internalIncosnsitencyDetector; |
535 | if (internalIncosnsitencyDetector!= null) { | 599 | if (internalIncosnsitencyDetector!= null) { |
536 | int id = ++numberOfSolverCalls; | 600 | int id = ++numberOfSolverCalls; |
537 | if (id % configuration.internalConsistencyCheckerConfiguration.incternalConsistencyCheckingFrequency == 0) { | 601 | if (id % configuration.internalConsistencyCheckerConfiguration.incternalConsistencyCheckingFrequency == 0) { |
538 | try { | 602 | try { |
539 | PartialInterpretation interpretation = (PartialInterpretation) (context.getModel()); | 603 | PartialInterpretation interpretation = (PartialInterpretation) (context.getModel()); |
540 | PartialInterpretation copied = EcoreUtil.copy(interpretation); | 604 | PartialInterpretation copied = EcoreUtil.copy(interpretation); |
541 | this.partialInterpretation2Logic.transformPartialIntepretation2Logic(copied.getProblem(), copied); | 605 | this.partialInterpretation2Logic.transformPartialIntepretation2Logic(copied.getProblem(), copied); |
542 | LogicProblem newProblem = copied.getProblem(); | 606 | LogicProblem newProblem = copied.getProblem(); |
543 | 607 | ||
544 | this.configuration.typeScopes.maxNewElements = interpretation.getMaxNewElements(); | 608 | this.configuration.typeScopes.maxNewElements = interpretation.getMaxNewElements(); |
545 | this.configuration.typeScopes.minNewElements = interpretation.getMinNewElements(); | 609 | this.configuration.typeScopes.minNewElements = interpretation.getMinNewElements(); |
546 | LogicResult result = internalIncosnsitencyDetector.solve(newProblem, configuration, workspace); | 610 | LogicResult result = internalIncosnsitencyDetector.solve(newProblem, configuration, workspace); |
547 | if (result instanceof InconsistencyResult) { | 611 | if (result instanceof InconsistencyResult) { |
548 | logger.debug("Solver found an Inconsistency!"); | 612 | logger.debug("Solver found an Inconsistency!"); |
549 | removeSubtreeFromQueue(t); | 613 | removeSubtreeFromQueue(t); |
550 | return true; | 614 | return true; |
551 | } else if (result instanceof ModelResult) { | 615 | } else if (result instanceof ModelResult) { |
552 | logger.debug("Solver found a model!"); | 616 | logger.debug("Solver found a model!"); |
553 | solutionStore.newSolution(context); | 617 | solutionStore.newSolution(context); |
554 | 618 | ||
555 | this.modelResultByInternalSolver = (ModelResult) result; | 619 | this.modelResultByInternalSolver = (ModelResult) result; |
556 | return true; | 620 | return true; |
557 | } else { | 621 | } else { |
558 | logger.debug("Failed consistency check."); | 622 | logger.debug("Failed consistency check."); |
559 | return false; | ||
560 | } | ||
561 | } catch (Exception e) { | ||
562 | logger.debug("Problem with internal consistency checking: "+e.getMessage()); | ||
563 | e.printStackTrace(); | ||
564 | return false; | 623 | return false; |
565 | } | 624 | } |
625 | } catch (Exception e) { | ||
626 | logger.debug("Problem with internal consistency checking: "+e.getMessage()); | ||
627 | e.printStackTrace(); | ||
628 | return false; | ||
566 | } | 629 | } |
567 | |||
568 | } | 630 | } |
569 | return false; | ||
570 | } | ||
571 | 631 | ||
572 | protected void removeSubtreeFromQueue(TrajectoryWithFitness t) { | ||
573 | PriorityQueue<TrajectoryWithFitness> previous = this.trajectoiresToExplore; | ||
574 | this.trajectoiresToExplore = new PriorityQueue<>(this.comparator); | ||
575 | for (TrajectoryWithFitness trajectoryWithFitness : previous) { | ||
576 | if (!containsAsSubstring(trajectoryWithFitness.trajectory, t.trajectory)) { | ||
577 | this.trajectoiresToExplore.add(trajectoryWithFitness); | ||
578 | } else { | ||
579 | logger.debug("State has been excluded due to inherent inconsistency"); | ||
580 | } | ||
581 | } | ||
582 | } | 632 | } |
633 | return false; | ||
634 | } | ||
583 | 635 | ||
584 | private boolean containsAsSubstring(Object[] full, Object[] substring) { | 636 | protected void removeSubtreeFromQueue(TrajectoryWithFitness t) { |
585 | if (substring.length > full.length) { | 637 | PriorityQueue<TrajectoryWithFitness> previous = this.trajectoiresToExplore; |
586 | return false; | 638 | this.trajectoiresToExplore = new PriorityQueue<>(this.comparator); |
587 | } else if (substring.length == full.length) { | 639 | for (TrajectoryWithFitness trajectoryWithFitness : previous) { |
588 | return Arrays.equals(full, substring); | 640 | if (!containsAsSubstring(trajectoryWithFitness.trajectory, t.trajectory)) { |
641 | this.trajectoiresToExplore.add(trajectoryWithFitness); | ||
589 | } else { | 642 | } else { |
590 | Object[] part = Arrays.copyOfRange(full, 0, substring.length); | 643 | logger.debug("State has been excluded due to inherent inconsistency"); |
591 | return Arrays.equals(part, substring); | ||
592 | } | 644 | } |
593 | } | 645 | } |
646 | } | ||
647 | |||
648 | private boolean containsAsSubstring(Object[] full, Object[] substring) { | ||
649 | if (substring.length > full.length) { | ||
650 | return false; | ||
651 | } else if (substring.length == full.length) { | ||
652 | return Arrays.equals(full, substring); | ||
653 | } else { | ||
654 | Object[] part = Arrays.copyOfRange(full, 0, substring.length); | ||
655 | return Arrays.equals(part, substring); | ||
656 | } | ||
657 | } | ||
594 | } | 658 | } |