1 | package de.uka.ipd.sdq.dsexplore.analysis.cost; |
2 | |
3 | import java.util.ArrayList; |
4 | import java.util.HashMap; |
5 | import java.util.Iterator; |
6 | import java.util.List; |
7 | import java.util.Map; |
8 | |
9 | import org.apache.log4j.Logger; |
10 | import org.eclipse.core.runtime.CoreException; |
11 | import org.eclipse.core.runtime.IProgressMonitor; |
12 | import org.eclipse.core.runtime.Status; |
13 | import org.eclipse.debug.core.ILaunchConfiguration; |
14 | import org.eclipse.emf.common.util.EList; |
15 | import org.eclipse.emf.ecore.util.EcoreUtil; |
16 | import org.opt4j.core.Constraint; |
17 | import org.opt4j.core.Criterion; |
18 | import org.opt4j.core.Objective; |
19 | |
20 | import de.uka.ipd.sdq.dsexplore.analysis.AnalysisFailedException; |
21 | import de.uka.ipd.sdq.dsexplore.analysis.IAnalysis; |
22 | import de.uka.ipd.sdq.dsexplore.analysis.IAnalysisResult; |
23 | import de.uka.ipd.sdq.dsexplore.analysis.PCMPhenotype; |
24 | import de.uka.ipd.sdq.dsexplore.helper.EMFHelper; |
25 | import de.uka.ipd.sdq.dsexplore.launch.DSEConstantsContainer; |
26 | import de.uka.ipd.sdq.dsexplore.launch.DSEWorkflowConfiguration; |
27 | import de.uka.ipd.sdq.dsexplore.launch.DSEConstantsContainer.QualityAttribute; |
28 | import de.uka.ipd.sdq.dsexplore.qml.contract.QMLContract.EvaluationAspect; |
29 | import de.uka.ipd.sdq.dsexplore.qml.contracttype.QMLContractType.Dimension; |
30 | import de.uka.ipd.sdq.dsexplore.qml.pcm.datastructures.EvaluationAspectWithContext; |
31 | import de.uka.ipd.sdq.dsexplore.qml.pcm.datastructures.builder.InfeasibilityConstraintBuilder; |
32 | import de.uka.ipd.sdq.dsexplore.qml.pcm.datastructures.builder.ObjectiveBuilder; |
33 | import de.uka.ipd.sdq.dsexplore.qml.pcm.datastructures.builder.SatisfactionConstraintBuilder; |
34 | import de.uka.ipd.sdq.dsexplore.qml.pcm.reader.PCMDeclarationsReader; |
35 | import de.uka.ipd.sdq.dsexplore.qml.profile.QMLProfile.UsageScenarioRequirement; |
36 | import de.uka.ipd.sdq.pcm.allocation.AllocationContext; |
37 | import de.uka.ipd.sdq.pcm.core.composition.AssemblyContext; |
38 | import de.uka.ipd.sdq.pcm.core.composition.ComposedStructure; |
39 | import de.uka.ipd.sdq.pcm.cost.ComponentCostPerInstance; |
40 | import de.uka.ipd.sdq.pcm.cost.ComponentCostPerType; |
41 | import de.uka.ipd.sdq.pcm.cost.Cost; |
42 | import de.uka.ipd.sdq.pcm.cost.CostRepository; |
43 | import de.uka.ipd.sdq.pcm.cost.FixedProcessingResourceCost; |
44 | import de.uka.ipd.sdq.pcm.cost.ProcessingResourceCost; |
45 | import de.uka.ipd.sdq.pcm.cost.VariableProcessingResourceCost; |
46 | import de.uka.ipd.sdq.pcm.cost.helper.CostUtil; |
47 | import de.uka.ipd.sdq.pcm.repository.RepositoryComponent; |
48 | import de.uka.ipd.sdq.pcm.resourceenvironment.ProcessingResourceSpecification; |
49 | import de.uka.ipd.sdq.pcm.resourceenvironment.ResourceContainer; |
50 | import de.uka.ipd.sdq.pcm.resourcetype.ProcessingResourceType; |
51 | import de.uka.ipd.sdq.pcm.usagemodel.UsageModel; |
52 | import de.uka.ipd.sdq.pcmsolver.models.PCMInstance; |
53 | import de.uka.ipd.sdq.workflow.exceptions.JobFailedException; |
54 | import de.uka.ipd.sdq.workflow.exceptions.UserCanceledException; |
55 | import de.uka.ipd.sdq.workflow.mdsd.blackboard.MDSDBlackboard; |
56 | import de.uka.ipd.sdq.workflow.pcm.blackboard.PCMResourceSetPartition; |
57 | import de.uka.ipd.sdq.workflow.pcm.jobs.LoadPCMModelsIntoBlackboardJob; |
58 | |
59 | public class CostEvaluator implements IAnalysis{ |
60 | |
61 | /** Logger for log4j. */ |
62 | private static Logger logger = |
63 | Logger.getLogger("de.uka.ipd.sdq.dsexplore.analysis.cost"); |
64 | |
65 | private CostRepository costModel; |
66 | private MDSDBlackboard blackboard; |
67 | |
68 | private CostSolverQualityAttributeDeclaration costQualityAttribute = new CostSolverQualityAttributeDeclaration(); |
69 | |
70 | //Constraint handling |
71 | private List<Constraint> constraints = new ArrayList<Constraint>(); |
72 | private Map<Constraint, EvaluationAspectWithContext> constraintToAspect = new HashMap<Constraint, EvaluationAspectWithContext>(); //This is needed to determine, what THE result is (Mean, Variance, ...) |
73 | |
74 | private List<Objective> objectives = new ArrayList<Objective>(); |
75 | private Map<Objective, EvaluationAspectWithContext> objectiveToAspect = new HashMap<Objective, EvaluationAspectWithContext>(); |
76 | |
77 | private Map<Long, CostAnalysisResult> previousCostResults = new HashMap<Long, CostAnalysisResult>(); |
78 | |
79 | /** |
80 | * Sums up the initial cost of the PCM elements present in the given PCM instance. |
81 | * TODO For now, all cost in the internal costRepository are considered. Thus, only |
82 | * variable cost lead to a change in cost, e.g. the variable cost for |
83 | * changing processing rates. |
84 | * |
85 | * Careful: This must point to the right pcm instance first. |
86 | * @param pcmInstance the PCM instance |
87 | * @return |
88 | */ |
89 | private double getInitialCost(PCMInstance pcmInstance){ |
90 | List<Cost> costs = costModel.getCost(); |
91 | double sum = 0; |
92 | for (Iterator<Cost> iterator = costs.iterator(); iterator.hasNext();) { |
93 | Cost cost = iterator.next(); |
94 | if (doesCostApply(cost,pcmInstance)){ |
95 | sum += cost.getInitialCost(); |
96 | } |
97 | } |
98 | |
99 | return sum; |
100 | } |
101 | |
102 | /** |
103 | * Only checks uses in system (for components) and in the allocation (for processing resources) |
104 | * @param cost |
105 | * @param pcmInstance |
106 | * @return |
107 | */ |
108 | private boolean doesCostApply(Cost cost, PCMInstance pcmInstance) { |
109 | if (VariableProcessingResourceCost.class.isInstance(cost)){ |
110 | VariableProcessingResourceCost vc = (VariableProcessingResourceCost)cost; |
111 | ResourceContainer rc = (ResourceContainer)vc.getProcessingresourcespecification().eContainer(); |
112 | return checkWhetherResourceContainerIsUsed(pcmInstance, rc); |
113 | //No usage of resource container found, return false. |
114 | } else if (cost instanceof ComponentCostPerType){ |
115 | ComponentCostPerType cc = (ComponentCostPerType)cost; |
116 | RepositoryComponent rc = cc.getRepositoryComponent(); |
117 | //List<AssemblyContext> asctx = pcmInstance.getSystem().getAssemblyContexts__ComposedStructure(); |
118 | //TODO: also retrieve inner assembly contexts of deployed composite components. Cost currently need to be specified separately. |
119 | |
120 | List<AssemblyContext> asctx = getAllContainedAssemblyContexts(pcmInstance.getSystem().getAssemblyContexts__ComposedStructure()); |
121 | |
122 | |
123 | for (AssemblyContext assemblyContext : asctx) { |
124 | if (EMFHelper.checkIdentity(assemblyContext.getEncapsulatedComponent__AssemblyContext(), rc)){ |
125 | return true; |
126 | } |
127 | } |
128 | return false; |
129 | } else if (cost instanceof FixedProcessingResourceCost){ |
130 | FixedProcessingResourceCost fc = (FixedProcessingResourceCost)cost; |
131 | ResourceContainer rc = (ResourceContainer)fc.getProcessingresourcespecification().eContainer(); |
132 | return checkWhetherResourceContainerIsUsed(pcmInstance, rc); |
133 | } else |
134 | return true; |
135 | } |
136 | |
137 | /** |
138 | * Get all contained ones recursively |
139 | * @param assemblyContextsComposedStructure |
140 | * @return |
141 | */ |
142 | private List<AssemblyContext> getAllContainedAssemblyContexts( |
143 | EList<AssemblyContext> assemblyContextsComposedStructure) { |
144 | List<AssemblyContext> list = new ArrayList<AssemblyContext>(); |
145 | list.addAll(assemblyContextsComposedStructure); |
146 | for (AssemblyContext assemblyContext : assemblyContextsComposedStructure) { |
147 | if (assemblyContext.getEncapsulatedComponent__AssemblyContext() instanceof ComposedStructure){ |
148 | ComposedStructure composite = (ComposedStructure)assemblyContext.getEncapsulatedComponent__AssemblyContext(); |
149 | list.addAll(getAllContainedAssemblyContexts(composite.getAssemblyContexts__ComposedStructure())); |
150 | } |
151 | } |
152 | return list; |
153 | } |
154 | |
155 | private boolean checkWhetherResourceContainerIsUsed(PCMInstance pcmInstance, |
156 | ResourceContainer rc) { |
157 | List<AllocationContext> alloc = pcmInstance.getAllocation().getAllocationContexts_Allocation(); |
158 | for (AllocationContext allocationContext : alloc) { |
159 | if (EMFHelper.checkIdentity(allocationContext.getResourceContainer_AllocationContext(), rc)){ |
160 | return true; |
161 | } |
162 | } |
163 | return false; |
164 | } |
165 | |
166 | /** |
167 | * Careful: This must point to the right pcm instance first. |
168 | * @param pcmInstance |
169 | * @return |
170 | */ |
171 | private double getOperatingCost(PCMInstance pcmInstance){ |
172 | return 0.0; |
173 | } |
174 | |
175 | /** |
176 | * This calculates the perpetuity (see http://en.wikipedia.org/wiki/Present_value) cost. |
177 | * @param pcmInstance |
178 | * @param interest If interest <= 0, no operating cost are taken into account. |
179 | * @return |
180 | */ |
181 | public double getTotalCost(PCMInstance pcmInstance, double interest){ |
182 | |
183 | //Important: "Read in" the right PCM instance first. |
184 | updateCostModel(pcmInstance); |
185 | |
186 | double operatingCost = 0; |
187 | if (interest > 0){ |
188 | operatingCost = this.getOperatingCost(pcmInstance)/interest; |
189 | } |
190 | return this.getInitialCost(pcmInstance) + operatingCost; |
191 | } |
192 | |
193 | private void updateCostModel(PCMInstance pcmInstance) { |
194 | |
195 | List<Cost> allCosts = this.costModel.getCost(); |
196 | |
197 | createCostsForReplicas(allCosts, pcmInstance); |
198 | |
199 | for (Cost cost : allCosts) { |
200 | |
201 | // fix links between model elements (maybe this is not needed anymore...) |
202 | if (cost instanceof ComponentCostPerInstance){ |
203 | ((ComponentCostPerInstance) cost).setAllocation(pcmInstance.getAllocation()); |
204 | } else if (VariableProcessingResourceCost.class.isInstance(cost)) { |
205 | |
206 | VariableProcessingResourceCost varCost = (VariableProcessingResourceCost)cost; |
207 | |
208 | ProcessingResourceSpecification old_prs = ((VariableProcessingResourceCost) cost) |
209 | .getProcessingresourcespecification(); |
210 | ResourceContainer old_rc = (ResourceContainer) old_prs |
211 | .eContainer(); |
212 | ProcessingResourceType ars = old_prs |
213 | .getActiveResourceType_ActiveResourceSpecification(); |
214 | |
215 | List<ResourceContainer> all_new_rcs = pcmInstance.getResourceEnvironment() |
216 | .getResourceContainer_ResourceEnvironment(); |
217 | |
218 | for (ResourceContainer resourceContainer : all_new_rcs) { |
219 | |
220 | if (resourceContainer.getId().equals(old_rc.getId())) { |
221 | |
222 | List<ProcessingResourceSpecification> new_resources = resourceContainer |
223 | .getActiveResourceSpecifications_ResourceContainer(); |
224 | |
225 | boolean resourceTypeFound = false; |
226 | |
227 | for (ProcessingResourceSpecification new_prs : new_resources) { |
228 | |
229 | if (new_prs |
230 | .getActiveResourceType_ActiveResourceSpecification() |
231 | .getId() |
232 | .equals(ars.getId())) { |
233 | if (!resourceTypeFound){ |
234 | //Reset the processing rate with the first matching one found |
235 | varCost.setProcessingresourcespecification(new_prs); |
236 | resourceTypeFound = true; |
237 | } else { |
238 | throw new RuntimeException("There are two processing resources with the same resource type within one resource container, this cannot be handled by the optimisation yet. Please change your model."); |
239 | } |
240 | } |
241 | } |
242 | break; |
243 | } |
244 | |
245 | /* |
246 | * Resource resource = prs.eResource(); if (resource != |
247 | * null){ URI oldURI = resource.getURI(); |
248 | * resource.setURI(resEnvFileURI); } else { |
249 | * System.out.println |
250 | * ("Resource of ProcessingResourceSpecification " |
251 | * +prs.toString()+" has a null eResource!"); } |
252 | */ |
253 | } |
254 | } |
255 | } |
256 | |
257 | } |
258 | |
259 | /** |
260 | * FIXME: this should be more elegantly handled by separating a resource repository with costs specification from |
261 | * the actually used resources |
262 | * @param allCosts |
263 | * @param pcmInstance |
264 | */ |
265 | private void createCostsForReplicas(List<Cost> allCosts, |
266 | PCMInstance pcmInstance) { |
267 | |
268 | List<ResourceContainer> containers = pcmInstance.getResourceEnvironment().getResourceContainer_ResourceEnvironment(); |
269 | List<Cost> replicaCosts = new ArrayList<Cost>(); |
270 | |
271 | // also remove old replica costs from previous candidates |
272 | List<Cost> oldReplicaCosts = new ArrayList<Cost>(); |
273 | |
274 | for (Cost anyCost : allCosts) { |
275 | |
276 | // iterate through costs, look at all VariableProcessingResourceCost or FixedProcessingResourceCost and in particular at their resourcecontainer. |
277 | ResourceContainer originalContainer = null; |
278 | ProcessingResourceType procResourceType = null; |
279 | ProcessingResourceCost cost = null; |
280 | if (anyCost instanceof ProcessingResourceCost){ |
281 | cost = ((ProcessingResourceCost)anyCost); |
282 | originalContainer = cost.getProcessingresourcespecification().getResourceContainer_ProcessingResourceSpecification(); |
283 | procResourceType = cost.getProcessingresourcespecification().getActiveResourceType_ActiveResourceSpecification(); |
284 | } else { |
285 | // look at next cost model element |
286 | continue; |
287 | } |
288 | |
289 | // check if this is a cost model element for a replica, if yes delete it if its server is no longer in the resource environment |
290 | if (originalContainer.getEntityName().contains("Replica") && !containers.contains(originalContainer)){ |
291 | oldReplicaCosts.add(cost); |
292 | } |
293 | |
294 | // find replicated servers and their original |
295 | for (ResourceContainer resourceContainer : containers) { |
296 | if (resourceContainer.getEntityName().contains("Replica") && resourceContainer.getId().contains(originalContainer.getId())){ |
297 | // resourceContainer is a replica of originalResourceContainer |
298 | |
299 | // check if there already is a cost model element for the replica. If not, create a new one. |
300 | boolean replicaAlreadyAnnotated = false; |
301 | for (Cost existingCost : allCosts) { |
302 | if (existingCost instanceof ProcessingResourceCost){ |
303 | ProcessingResourceCost existingProcRateCost = (ProcessingResourceCost)existingCost; |
304 | if (existingProcRateCost.getProcessingresourcespecification().getResourceContainer_ProcessingResourceSpecification().getId() |
305 | .equals(resourceContainer.getId())){ |
306 | // there already is a cost model element annotating this replica, so continue; |
307 | replicaAlreadyAnnotated = true; |
308 | break; // inner for loop |
309 | } |
310 | } |
311 | } |
312 | if (replicaAlreadyAnnotated){ |
313 | continue; |
314 | } |
315 | |
316 | // get the processing resource spec that corresponds to the annotated one |
317 | ProcessingResourceSpecification replicaProcSpec = null; |
318 | for (ProcessingResourceSpecification procRes : resourceContainer.getActiveResourceSpecifications_ResourceContainer()) { |
319 | if (procRes.getActiveResourceType_ActiveResourceSpecification().getId().equals(procResourceType.getId())){ |
320 | replicaProcSpec = procRes; |
321 | break; |
322 | } |
323 | } |
324 | if (replicaProcSpec == null){ |
325 | logger.warn("Could not find processing resource type "+procResourceType.getEntityName()+" in container "+resourceContainer.getEntityName()+", assuming that there are no costs for it in this replica"); |
326 | return; |
327 | } |
328 | |
329 | // replicate cost element, too. |
330 | ProcessingResourceCost replicaCost = (ProcessingResourceCost)EcoreUtil.copy(cost); |
331 | replicaCost.setProcessingresourcespecification(replicaProcSpec); |
332 | replicaCosts.add(replicaCost); |
333 | } |
334 | } |
335 | } |
336 | allCosts.removeAll(oldReplicaCosts); |
337 | allCosts.addAll(replicaCosts); |
338 | } |
339 | |
340 | |
341 | |
342 | @Override |
343 | public void analyse(PCMPhenotype pheno, IProgressMonitor monitor) |
344 | throws CoreException, UserCanceledException, JobFailedException, |
345 | AnalysisFailedException { |
346 | PCMInstance pcm = pheno.getPCMInstance(); |
347 | this.previousCostResults.put(pheno.getNumericID(), new CostAnalysisResult(getTotalCost(pcm, 0), pcm)); |
348 | CostUtil.getInstance().resetCache(); |
349 | } |
350 | |
351 | @Override |
352 | public QualityAttribute getQualityAttribute() throws CoreException { |
353 | //return DSEConstantsContainer.COST_QUALITY; |
354 | return costQualityAttribute.getQualityAttribute(); |
355 | } |
356 | |
357 | @Override |
358 | public void initialise(DSEWorkflowConfiguration configuration) throws CoreException { |
359 | |
360 | CostRepository costs = getCostModel(configuration); |
361 | this.costModel = costs; |
362 | |
363 | initialiseCriteria(configuration); |
364 | } |
365 | |
366 | |
367 | private void initialiseCriteria(DSEWorkflowConfiguration configuration) throws CoreException{ |
368 | |
369 | PCMInstance pcmInstance = getPCMInstance(); |
370 | UsageModel usageModel = pcmInstance.getUsageModel(); |
371 | |
372 | PCMDeclarationsReader reader = new PCMDeclarationsReader( |
373 | configuration.getRawConfiguration().getAttribute("qmlDefinitionFile", "")); |
374 | |
375 | List<Dimension> dimensions = this.costQualityAttribute.getDimensions(); |
376 | |
377 | List<EvaluationAspectWithContext> costAspects = new ArrayList<EvaluationAspectWithContext>(6); |
378 | for (Dimension dimension : dimensions) { |
379 | costAspects.addAll(reader.getDimensionConstraintContextsForUsageModel(usageModel, dimension.getId())); |
380 | costAspects.addAll(reader.getDimensionObjectiveContextsForUsageModel(usageModel, dimension.getId())); |
381 | } |
382 | |
383 | |
384 | //Check constraint aspects and create Constraint-Objects for every Aspect |
385 | for (Iterator<EvaluationAspectWithContext> iterator = costAspects.iterator(); iterator.hasNext();) { |
386 | EvaluationAspectWithContext aspectContext = iterator |
387 | .next(); |
388 | |
389 | if(aspectContext.getRequirement() instanceof UsageScenarioRequirement) { |
390 | |
391 | //Handle possible aspects here |
392 | if (canEvaluateAspect(aspectContext.getEvaluationAspect(), aspectContext.getDimension())) { |
393 | |
394 | if(aspectContext.getCriterion() instanceof de.uka.ipd.sdq.dsexplore.qml.contract.QMLContract.Constraint) { |
395 | Constraint c = reader.translateEvalAspectToInfeasibilityConstraint(aspectContext, new InfeasibilityConstraintBuilder()); |
396 | constraints.add(c); |
397 | constraintToAspect.put(c, aspectContext); |
398 | } else { |
399 | //instanceof Objective |
400 | Objective o = reader.translateEvalAspectToObjective(this.getQualityAttribute().getName(), aspectContext, new ObjectiveBuilder()); |
401 | objectives.add(o); |
402 | objectiveToAspect.put(o, aspectContext); |
403 | |
404 | Constraint c = reader.translateEvalAspectToSatisfactionConstraint(aspectContext, o, new SatisfactionConstraintBuilder()); |
405 | constraints.add(c); |
406 | constraintToAspect.put(c, aspectContext); |
407 | } |
408 | } else { |
409 | //XXX: This should never be the case if the optimization is started with the LaunchConfig the aspect is checked there as well |
410 | throw new RuntimeException("Evaluation aspect not supported("+aspectContext.getEvaluationAspect()+")!"); |
411 | } |
412 | |
413 | |
414 | } else { |
415 | throw new RuntimeException("Unsupported Requirement!"); |
416 | } |
417 | |
418 | } |
419 | } |
420 | |
421 | private boolean canEvaluateAspect(EvaluationAspect aspect, Dimension dimension){ |
422 | return costQualityAttribute.canEvaluateAspectForDimension(aspect, dimension); |
423 | } |
424 | |
425 | //MOVED to PCMDeclarationsReader |
426 | // private Objective translateEvalAspectToObjective(EvaluationAspectWithContext aspect) { |
427 | // //Make sure, the aspect IS an objective |
428 | // try { |
429 | // if(aspect.getDimension().getType().getRelationSemantics().getRelSem() == EnumRelationSemantics.DECREASING) { |
430 | // return new Objective(this.getQualityAttribute(), Objective.Sign.MIN); |
431 | // } else { |
432 | // //INCREASING |
433 | // return new Objective(this.getQualityAttribute(), Objective.Sign.MAX); |
434 | // } |
435 | // } catch (CoreException e) { |
436 | // e.printStackTrace(); |
437 | // throw new RuntimeException("Could not get cost quality attribute!"); |
438 | // } |
439 | // } |
440 | |
441 | |
442 | /** |
443 | * returns a cost model or throws an exception. |
444 | * @param configuration.getRawConfiguration() |
445 | * @return a CostRepository which is not null |
446 | * @throws CoreException if the model could not be loaded. |
447 | */ |
448 | private CostRepository getCostModel(DSEWorkflowConfiguration configuration) throws CoreException { |
449 | String costModelFileName = configuration.getRawConfiguration().getAttribute(DSEConstantsContainer.COST_FILE, ""); |
450 | CostRepository cr = (CostRepository)EMFHelper.loadFromXMIFile(costModelFileName); |
451 | if (cr == null){ |
452 | throw new CoreException(new Status(Status.ERROR, "de.uka.ipd.sdq.dsexplore", 0, "Cost model "+costModelFileName+" could not be loaded.", null)); |
453 | } |
454 | return cr; |
455 | } |
456 | |
457 | private PCMInstance getPCMInstance(){ |
458 | return new PCMInstance((PCMResourceSetPartition)this.blackboard.getPartition(LoadPCMModelsIntoBlackboardJob.PCM_MODELS_PARTITION_ID)); |
459 | } |
460 | |
461 | @Override |
462 | public boolean hasStatisticResults() throws CoreException { |
463 | return false; |
464 | } |
465 | |
466 | // @Override |
467 | // public List<Objective> getObjectives() throws CoreException { |
468 | // List<Objective> objectives = new ArrayList<Objective>(1); |
469 | // Objective o = new Objective(this.getQualityAttribute(), Objective.Sign.MIN); |
470 | // objectives.add(o); |
471 | // |
472 | // return objectives; |
473 | // } |
474 | |
475 | @Override |
476 | public List<Criterion> getCriterions() throws CoreException { |
477 | List<Criterion> criterions = new ArrayList<Criterion>(); |
478 | |
479 | //Objective o = new Objective(this.getQualityAttribute(), Objective.Sign.MIN); |
480 | criterions.addAll(objectives); |
481 | |
482 | criterions.addAll(constraints); |
483 | |
484 | return criterions; |
485 | } |
486 | |
487 | @Override |
488 | public IAnalysisResult retrieveResultsFor(PCMPhenotype pheno, Criterion criterion) |
489 | throws CoreException, AnalysisFailedException { |
490 | //It is always the cost value, i.e. objective and constraint always have to refer to the SimpleValue (-> no statistical requirements atm) |
491 | //If more possible aspects are added, the criterion needs to be examined here |
492 | |
493 | return this.previousCostResults.get(pheno.getNumericID()); |
494 | } |
495 | |
496 | @Override |
497 | public boolean hasObjectivePerUsageScenario() throws CoreException { |
498 | return false; |
499 | } |
500 | |
501 | |
502 | @Override |
503 | public void setBlackboard(MDSDBlackboard blackboard) { |
504 | this.blackboard = blackboard; |
505 | } |
506 | |
507 | } |