| 1 | package de.uka.ipd.sdq.dsexplore.opt4j.start; |
| 2 | |
| 3 | import java.util.ArrayList; |
| 4 | import java.util.Collection; |
| 5 | import java.util.HashMap; |
| 6 | import java.util.LinkedList; |
| 7 | import java.util.List; |
| 8 | import java.util.Map; |
| 9 | import java.util.Set; |
| 10 | |
| 11 | import org.apache.log4j.Logger; |
| 12 | import org.eclipse.core.runtime.CoreException; |
| 13 | import org.eclipse.core.runtime.IProgressMonitor; |
| 14 | import org.eclipse.core.runtime.Status; |
| 15 | import org.opt4j.common.archive.BoundedArchive; |
| 16 | import org.opt4j.common.archive.CrowdingArchive; |
| 17 | import org.opt4j.common.archive.DefaultArchive; |
| 18 | import org.opt4j.config.Task; |
| 19 | import org.opt4j.config.Task.State; |
| 20 | import org.opt4j.core.Archive; |
| 21 | import org.opt4j.core.Individual; |
| 22 | import org.opt4j.core.IndividualBuilder; |
| 23 | import org.opt4j.core.IndividualCollection; |
| 24 | import org.opt4j.core.IndividualCollectionListener; |
| 25 | import org.opt4j.core.Objective; |
| 26 | import org.opt4j.core.Population; |
| 27 | import org.opt4j.core.Value; |
| 28 | import org.opt4j.core.domination.ConstraintDominationModule; |
| 29 | import org.opt4j.core.domination.ConstraintDominationModule.Strategy; |
| 30 | import org.opt4j.core.optimizer.Completer; |
| 31 | import org.opt4j.core.optimizer.Control; |
| 32 | import org.opt4j.core.optimizer.Optimizer; |
| 33 | import org.opt4j.core.problem.Evaluator; |
| 34 | import org.opt4j.operator.mutate.BasicMutateModule; |
| 35 | import org.opt4j.optimizer.ea.EvolutionaryAlgorithmModule; |
| 36 | import org.opt4j.optimizer.ea.ScalingNsga2Module; |
| 37 | import org.opt4j.optimizer.rs.RandomSearchModule; |
| 38 | import org.opt4j.start.Opt4J; |
| 39 | import org.opt4j.start.Opt4JTask; |
| 40 | |
| 41 | import com.google.inject.Module; |
| 42 | |
| 43 | import de.uka.ipd.sdq.dsexplore.analysis.IAnalysis; |
| 44 | import de.uka.ipd.sdq.dsexplore.exception.ExceptionHelper; |
| 45 | import de.uka.ipd.sdq.dsexplore.helper.GenotypeReader; |
| 46 | import de.uka.ipd.sdq.dsexplore.helper.ResultsWriter; |
| 47 | import de.uka.ipd.sdq.dsexplore.launch.DSEWorkflowConfiguration; |
| 48 | import de.uka.ipd.sdq.dsexplore.opt4j.archive.PopulationTracker; |
| 49 | import de.uka.ipd.sdq.dsexplore.opt4j.archive.PopulationTrackerModule; |
| 50 | import de.uka.ipd.sdq.dsexplore.opt4j.genotype.DesignDecisionGenotype; |
| 51 | import de.uka.ipd.sdq.dsexplore.opt4j.representation.DSECreator; |
| 52 | import de.uka.ipd.sdq.dsexplore.opt4j.representation.DSEDecoder; |
| 53 | import de.uka.ipd.sdq.dsexplore.opt4j.representation.DSEEvaluator; |
| 54 | import de.uka.ipd.sdq.dsexplore.opt4j.representation.DSEEvolutionaryAlgorithmModule; |
| 55 | import de.uka.ipd.sdq.dsexplore.opt4j.representation.DSEIndividual; |
| 56 | import de.uka.ipd.sdq.dsexplore.opt4j.representation.DSEIndividualBuilder; |
| 57 | import de.uka.ipd.sdq.dsexplore.opt4j.representation.DSEModule; |
| 58 | import de.uka.ipd.sdq.dsexplore.opt4j.representation.DSEMutateModule; |
| 59 | import de.uka.ipd.sdq.dsexplore.opt4j.representation.DSEProblem; |
| 60 | import de.uka.ipd.sdq.dsexplore.opt4j.representation.GivenInstanceModule; |
| 61 | import de.uka.ipd.sdq.dsexplore.opt4j.representation.RuleBasedSearchModule; |
| 62 | import de.uka.ipd.sdq.dsexplore.qml.pcm.datastructures.UsageScenarioBasedObjective; |
| 63 | import de.uka.ipd.sdq.pcm.cost.CostRepository; |
| 64 | import de.uka.ipd.sdq.pcm.designdecision.Choice; |
| 65 | import de.uka.ipd.sdq.pcmsolver.models.PCMInstance; |
| 66 | import de.uka.ipd.sdq.tcfmoop.config.GivenParetoFrontIsReachedConfig; |
| 67 | import de.uka.ipd.sdq.tcfmoop.config.IConfiguration; |
| 68 | import de.uka.ipd.sdq.tcfmoop.config.InsignificantSetQualityImprovementConfig; |
| 69 | import de.uka.ipd.sdq.tcfmoop.config.MinimalQualityCriteriaValueConfig; |
| 70 | import de.uka.ipd.sdq.tcfmoop.config.InsignificantSetQualityImprovementConfig.UnresolvedValueDifference; |
| 71 | import de.uka.ipd.sdq.tcfmoop.config.InsignificantSetQualityImprovementConfig.ValueDifference; |
| 72 | import de.uka.ipd.sdq.tcfmoop.config.exceptions.InvalidConfigException; |
| 73 | import de.uka.ipd.sdq.tcfmoop.tcmanager.TerminationCriteriaManager; |
| 74 | import de.uka.ipd.sdq.workflow.mdsd.blackboard.MDSDBlackboard; |
| 75 | |
| 76 | //import org.aopalliance.intercept.MethodInterceptor; |
| 77 | |
| 78 | /** |
| 79 | * Main class to start the whole Opt4J stuff. |
| 80 | * |
| 81 | * TODO: Make this a Singleton instead of static? Even better: Handle the global stuff properly. Similar to SimuComModel. |
| 82 | * @author martens |
| 83 | * |
| 84 | */ |
| 85 | public class Opt4JStarter { |
| 86 | |
| 87 | private static DSEProblem problem = null; |
| 88 | private static DSECreator creator = null; |
| 89 | |
| 90 | private static Opt4JTask task = null; |
| 91 | |
| 92 | private static DSEWorkflowConfiguration myDSEConfig = null; |
| 93 | |
| 94 | /** Logger for log4j. */ |
| 95 | private static Logger logger = |
| 96 | Logger.getLogger("de.uka.ipd.sdq.dsexplore.opt4j.start.Opt4JStarter"); |
| 97 | |
| 98 | private static List<ResultsWriter> writers = null; |
| 99 | |
| 100 | public static void init(List<IAnalysis> evaluators, DSEWorkflowConfiguration dseConfig, PCMInstance pcmInstance, IProgressMonitor monitor, MDSDBlackboard blackboard) throws CoreException{ |
| 101 | |
| 102 | Opt4JStarter.myDSEConfig = dseConfig; |
| 103 | |
| 104 | Collection<Module> modules = new ArrayList<Module>(); |
| 105 | |
| 106 | DSEModule dseModule = new DSEModule(); |
| 107 | modules.add(dseModule); |
| 108 | |
| 109 | addOptimisationModules(dseConfig.getMaxIterations(), dseConfig, |
| 110 | modules); |
| 111 | |
| 112 | addPopulationModule(modules); |
| 113 | |
| 114 | |
| 115 | ConstraintDominationModule m = new ConstraintDominationModule(); |
| 116 | m.setStrategyForFeasibleSolutions(Strategy.GoalAttainmentDomination); |
| 117 | modules.add(m); //XXX: |
| 118 | //Don't forget to disable cache in GenotypReader.java if using constraints... |
| 119 | //Check QML declarations |
| 120 | |
| 121 | // set tournament value because default of 0 is stupid. |
| 122 | ScalingNsga2Module nsgaModule = new ScalingNsga2Module(); |
| 123 | nsgaModule.setTournament(3); |
| 124 | modules.add(nsgaModule); |
| 125 | |
| 126 | openTask(modules); |
| 127 | |
| 128 | Opt4JStarter.writers = new LinkedList<ResultsWriter>(); |
| 129 | |
| 130 | Opt4JStarter.problem = new DSEProblem(dseConfig, pcmInstance); |
| 131 | if (dseConfig.isNewProblem()){ |
| 132 | Opt4JStarter.problem.saveProblem(); |
| 133 | } |
| 134 | |
| 135 | GenotypeReader.setTask(task); //QUICKHACK |
| 136 | |
| 137 | DSEEvaluator ev = task.getInstance(DSEEvaluator.class); |
| 138 | ev.init(evaluators, monitor,blackboard, dseConfig.isStopOnInitialFailure()); |
| 139 | |
| 140 | //Termination Criteria Manager Initializitation if needed |
| 141 | if(myDSEConfig.getUseTerminationCriteria()){ |
| 142 | TerminationCriteriaManager tcm = task.getInstance(TerminationCriteriaManager.class); |
| 143 | |
| 144 | resolveObjectivesForTCM(); |
| 145 | |
| 146 | tcm.initialize(myDSEConfig.getTCConfigurations()); |
| 147 | |
| 148 | if(myDSEConfig.getActivateComposedTerminationCriteria()){ |
| 149 | tcm.activateComposedCriterion(); |
| 150 | tcm.setComposedCriterionExpression(myDSEConfig.getComposedCriteriaExpression()); |
| 151 | } |
| 152 | |
| 153 | if(myDSEConfig.getRunInComparisionMode()){ |
| 154 | tcm.activateTCComparisionMode(); |
| 155 | } |
| 156 | |
| 157 | } |
| 158 | |
| 159 | } |
| 160 | |
| 161 | public static void openTask(Collection<Module> modules) { |
| 162 | Opt4JStarter.task = new Opt4JTask(false); |
| 163 | task.init(modules); |
| 164 | task.open(); |
| 165 | } |
| 166 | |
| 167 | /** |
| 168 | * Only starts Opt4J, needs call to {@link Opt4JStarter#init(IAnalysis, IAnalysis, List, CostRepository, PCMInstance, boolean)} first. |
| 169 | * @param dseConfig |
| 170 | *@param monitor |
| 171 | * @param genotypes May be null |
| 172 | * @param allCandidates |
| 173 | * @param archiveCandidates |
| 174 | * @throws CoreException |
| 175 | */ |
| 176 | public static void runOpt4JWithPopulation( |
| 177 | DSEWorkflowConfiguration dseConfig, |
| 178 | IProgressMonitor monitor, |
| 179 | List<DesignDecisionGenotype> genotypes, |
| 180 | List<DesignDecisionGenotype> allCandidates, List<DesignDecisionGenotype> archiveCandidates) throws CoreException { |
| 181 | |
| 182 | if (Opt4JStarter.problem == null){ |
| 183 | throw new CoreException(new Status(Status.ERROR, |
| 184 | "de.uka.ipd.sdq.dsexplore", 0, "Opt4JStarter has not been properly initialised. Contact developers.", null)); |
| 185 | } |
| 186 | |
| 187 | if (genotypes != null && genotypes.size() > 0){ |
| 188 | Opt4JStarter.problem.setInitialPopulation(genotypes); |
| 189 | } |
| 190 | |
| 191 | DSEListener listener = new DSEListener(monitor,dseConfig); |
| 192 | runTask(listener, dseConfig, allCandidates, archiveCandidates); |
| 193 | |
| 194 | } |
| 195 | |
| 196 | /** |
| 197 | * Can only be called after calling {@link Opt4JStarter#init(List, DSEWorkflowConfiguration, PCMInstance, IProgressMonitor, MDSDBlackboard)}. |
| 198 | * @param listener |
| 199 | * @param dseConfig |
| 200 | * @param allCandidates may be null |
| 201 | * @param archiveCandidates |
| 202 | * @throws CoreException |
| 203 | */ |
| 204 | private static void runTask(DSEListener listener, DSEWorkflowConfiguration dseConfig, List<DesignDecisionGenotype> allCandidates, List<DesignDecisionGenotype> archiveCandidates) |
| 205 | throws CoreException { |
| 206 | |
| 207 | try { |
| 208 | Opt4JStarter.creator = task.getInstance(DSECreator.class); |
| 209 | Optimizer opt = task.getInstance(Optimizer.class); |
| 210 | opt.addOptimizerIterationListener(listener); |
| 211 | IndividualBuilder indivBuilder = getIndividualBuilder(); |
| 212 | //indivBuilder.addIndividualStateListener(new DSEIndividualStateListener(dseConfig)); |
| 213 | |
| 214 | //add the previously defined all candidates to the custom PopulationTracker archive, |
| 215 | PopulationTracker populationTracker = getAllIndividuals(); |
| 216 | Archive archive = getArchiveIndividuals(); |
| 217 | Completer completer = task.getInstance(Completer.class); |
| 218 | if (allCandidates != null && allCandidates.size() > 0){ |
| 219 | if (indivBuilder instanceof DSEIndividualBuilder){ |
| 220 | logger.debug("Reading in predefined all candidates."); |
| 221 | DSEIndividualBuilder dseBuilder = (DSEIndividualBuilder)indivBuilder; |
| 222 | for (DesignDecisionGenotype designDecisionGenotype : allCandidates) { |
| 223 | DSEIndividual individual = dseBuilder.build(designDecisionGenotype); |
| 224 | completer.complete(individual); |
| 225 | populationTracker.addIndividualsManually(individual); |
| 226 | } |
| 227 | logger.debug("Finished reading in predefined all candidates."); |
| 228 | |
| 229 | logger.debug("Reading in archive candidates to add them to Archive"); |
| 230 | |
| 231 | try { |
| 232 | for (DesignDecisionGenotype designDecisionGenotype : archiveCandidates) { |
| 233 | Individual individual = dseBuilder.build(designDecisionGenotype); |
| 234 | completer.complete(individual); |
| 235 | archive.add(individual); |
| 236 | } |
| 237 | } catch (Exception e) { |
| 238 | throw new CoreException(new Status(Status.ERROR, |
| 239 | "de.uka.ipd.sdq.dsexplore", 0, "Cannot archive candidates to archive "+archive.getClass().getSimpleName()+". Maybe too many? Reason: " + e.getMessage(), e)); |
| 240 | } |
| 241 | logger.debug("Finished reading in archive candidates"); |
| 242 | |
| 243 | } |
| 244 | |
| 245 | } |
| 246 | |
| 247 | task.execute(); |
| 248 | |
| 249 | |
| 250 | } catch (CoreException e) { |
| 251 | throw e; |
| 252 | } catch (Exception e) { |
| 253 | throw new CoreException(new Status(Status.ERROR, |
| 254 | "de.uka.ipd.sdq.dsexplore", 0, e.getMessage(), e)); |
| 255 | } finally { |
| 256 | |
| 257 | DSEEvaluator evaluator = task.getInstance(DSEEvaluator.class); |
| 258 | List<Exception> exceptions = evaluator.getExceptionList(); |
| 259 | |
| 260 | try { |
| 261 | |
| 262 | |
| 263 | // PopulationTracker allIndividuals = getAllIndividuals(); |
| 264 | // ResultsWriter.printOutIndividuals(allIndividuals.getIndividuals(), "All Individuals"); |
| 265 | // |
| 266 | // ResultsWriter.printOutIndividuals(allIndividuals.getParetoOptimalIndividuals(), "Own Optimal Candidates"); |
| 267 | |
| 268 | // final iteration as csv |
| 269 | Optimizer opt = task.getInstance(Optimizer.class); |
| 270 | int iteration = opt.getIteration(); |
| 271 | |
| 272 | ResultsWriter.writeDSEIndividualsToFile(Opt4JStarter.getPopulationIndividuals(), dseConfig.getResultFolder()+"population", iteration, true, true, exceptions); |
| 273 | ResultsWriter.writeIndividualsToFile(Opt4JStarter.getArchiveIndividuals(), dseConfig.getResultFolder()+"archiveCandidates", iteration, exceptions, true, true); |
| 274 | |
| 275 | } catch (Exception e){ |
| 276 | logger.error("Optimisation failed, I could not save the last results."); |
| 277 | e.printStackTrace(); |
| 278 | } |
| 279 | |
| 280 | String config = dseConfig.getOriginalConfiguration().getMemento(); |
| 281 | ResultsWriter.writeStringToFile("config", config, listener.getIteration(), exceptions, ".txt"); |
| 282 | |
| 283 | if (exceptions.size() > 0){ |
| 284 | logger.warn("Errors occured during evaluation."); |
| 285 | for (Exception exception : exceptions) { |
| 286 | exception.printStackTrace(); |
| 287 | } |
| 288 | } |
| 289 | |
| 290 | } |
| 291 | } |
| 292 | |
| 293 | /** |
| 294 | * Can only be called after calling {@link Opt4JStarter#init(List, DSEWorkflowConfiguration, PCMInstance, IProgressMonitor, MDSDBlackboard)}. |
| 295 | * @return |
| 296 | * @throws CoreException |
| 297 | */ |
| 298 | public static DSEIndividualBuilder getIndividualBuilder() throws CoreException { |
| 299 | if (task != null){ |
| 300 | IndividualBuilder indivBuilder = task.getInstance(IndividualBuilder.class); |
| 301 | if (!(indivBuilder instanceof DSEIndividualBuilder)){ |
| 302 | ExceptionHelper.createNewInitialisationException("Internal Error: IndividualBuilder is not a DSEIndividualBuilder, Opt4JStarter has not properly been initialised."); |
| 303 | } |
| 304 | return (DSEIndividualBuilder)indivBuilder; |
| 305 | } else |
| 306 | throw ExceptionHelper.createNewInitialisationException("Internal Error: Cannot access IndividualBuilder, Opt4JStarter has not properly been initialised."); |
| 307 | } |
| 308 | |
| 309 | private static void addPopulationModule(Collection<Module> modules) { |
| 310 | // ArchiveModule am = new ArchiveModule(); |
| 311 | // am.setType(ArchiveModule.Type.); |
| 312 | PopulationTrackerModule p = new PopulationTrackerModule(); |
| 313 | |
| 314 | modules.add(p); |
| 315 | // modules.add(dtlz); |
| 316 | // modules.add(gui); |
| 317 | } |
| 318 | |
| 319 | private static void addOptimisationModules(int maxIterations, |
| 320 | DSEWorkflowConfiguration config, |
| 321 | Collection<Module> modules) throws CoreException { |
| 322 | |
| 323 | int individualsPerGeneration = config.getIndividualsPerGeneration(); |
| 324 | double crossoverRate = config.getCrossoverRate(); |
| 325 | |
| 326 | if (config.getMaxIterations() == 0 && config.hasPredefinedInstances()){ |
| 327 | GivenInstanceModule givenInstanceModule = new GivenInstanceModule(); |
| 328 | modules.add(givenInstanceModule); |
| 329 | } else if (config.isRuleBasedSearch()){ |
| 330 | RuleBasedSearchModule rbModule = new RuleBasedSearchModule(); |
| 331 | rbModule.setGenerations(maxIterations); |
| 332 | rbModule.setFullSearch(config.isFullRuleBasedSearch()); |
| 333 | modules.add(rbModule); |
| 334 | } else if (config.isRandomSearch()){ |
| 335 | RandomSearchModule rsm = new RandomSearchModule(){ |
| 336 | @Override |
| 337 | public void config(){ |
| 338 | super.config(); |
| 339 | bind(IndividualBuilder.class).to(DSEIndividualBuilder.class); |
| 340 | } |
| 341 | }; |
| 342 | rsm.setBatchsize(config.getIndividualsPerGeneration()); |
| 343 | rsm.setEvaluations(maxIterations*rsm.getBatchsize()); |
| 344 | modules.add(rsm); |
| 345 | } else { |
| 346 | EvolutionaryAlgorithmModule ea = new DSEEvolutionaryAlgorithmModule(); |
| 347 | ea.setGenerations(maxIterations); |
| 348 | ea.setAlpha(individualsPerGeneration); |
| 349 | ea.setLambda((int) Math.floor(individualsPerGeneration / 2.0 + 0.5)); |
| 350 | ea.setCrossoverRate(crossoverRate); |
| 351 | |
| 352 | DSEMutateModule mutation = new DSEMutateModule(); |
| 353 | // adaptive rate uses 1/genotype length * mutation intensity, so we use that, too |
| 354 | // is only set once per run, so genotypes of changing length are not supported. |
| 355 | mutation.setMutationIntensity(3); |
| 356 | |
| 357 | /* SimulatedAnnealingModule sa = new SimulatedAnnealingModule(); |
| 358 | sa.setIterations(maxIterations);*/ |
| 359 | |
| 360 | |
| 361 | /* |
| 362 | * GUIModule gui = new GUIModule(); gui.setCloseOnStop(true); |
| 363 | */ |
| 364 | modules.add(ea); |
| 365 | } |
| 366 | } |
| 367 | |
| 368 | |
| 369 | public static void closeTask(){ |
| 370 | if (Opt4JStarter.task != null){ |
| 371 | Opt4JStarter.task.close(); |
| 372 | } |
| 373 | } |
| 374 | |
| 375 | @Deprecated |
| 376 | public static void startOpt4JWithGUI(){ |
| 377 | //String id = Opt4JPluginActivator.PLUGIN_ID; |
| 378 | |
| 379 | try { |
| 380 | Opt4J.main(new String[0]); |
| 381 | |
| 382 | } catch (Exception e){ |
| 383 | // TODO Auto-generated catch block |
| 384 | e.printStackTrace(); |
| 385 | } |
| 386 | |
| 387 | } |
| 388 | |
| 389 | public synchronized static void terminate (){ |
| 390 | if (task != null && !task.getState().equals(State.DONE)){ |
| 391 | Control control = task.getInstance(Control.class); |
| 392 | control.doTerminate(); |
| 393 | logger.warn("Terminating run"); |
| 394 | } else { |
| 395 | logger.warn("Cannot terminate as no task is executing"); |
| 396 | } |
| 397 | } |
| 398 | |
| 399 | /** |
| 400 | * Returns the instance of {@link Archive} from the Opt4J {@link Task}, |
| 401 | * which is a {@link DefaultArchive} inheriting from |
| 402 | * {@link CrowdingArchive} and {@link BoundedArchive}. |
| 403 | * |
| 404 | * Can only be called after calling {@link Opt4JStarter#init(List, DSEWorkflowConfiguration, PCMInstance, IProgressMonitor, MDSDBlackboard)}. |
| 405 | * |
| 406 | * @return |
| 407 | */ |
| 408 | public static Archive getArchiveIndividuals(){ |
| 409 | return task.getInstance(Archive.class); |
| 410 | } |
| 411 | |
| 412 | /** |
| 413 | * Returns the instance of {@link Population} from the Opt4J {@link Task}, |
| 414 | * which is a plain {@link IndividualCollection}. |
| 415 | * |
| 416 | * Can only be called after calling {@link Opt4JStarter#init(List, DSEWorkflowConfiguration, PCMInstance, IProgressMonitor, MDSDBlackboard)}. |
| 417 | * |
| 418 | * @return |
| 419 | */ |
| 420 | public static List<DSEIndividual> getPopulationIndividuals(){ |
| 421 | Population p = task.getInstance(Population.class); |
| 422 | List<DSEIndividual> individuals = new ArrayList<DSEIndividual>(p.size()); |
| 423 | for (Individual individual : p) { |
| 424 | if (individual instanceof DSEIndividual){ |
| 425 | individuals.add((DSEIndividual) individual); |
| 426 | } else { |
| 427 | logger.error("There was an illegal individual that is not instance of DSEIndividual. Ignoring it. "+individual.toString()); |
| 428 | } |
| 429 | } |
| 430 | return individuals; |
| 431 | } |
| 432 | |
| 433 | /** |
| 434 | * Returns the instance of {@link PopulationTracker} from the Opt4J {@link Task}, |
| 435 | * which is an {@link IndividualCollectionListener} that listens on the |
| 436 | * {@link Population} instance from the Opt4J {@link Task}. |
| 437 | * |
| 438 | * Can only be called after calling {@link Opt4JStarter#init(List, DSEWorkflowConfiguration, PCMInstance, IProgressMonitor, MDSDBlackboard)}. |
| 439 | * |
| 440 | * @return |
| 441 | */ |
| 442 | public static PopulationTracker getAllIndividuals(){ |
| 443 | return task.getInstance(PopulationTracker.class); |
| 444 | } |
| 445 | |
| 446 | public static void tearDown(){ |
| 447 | |
| 448 | for (ResultsWriter writer : writers) { |
| 449 | writer.close(); |
| 450 | } |
| 451 | |
| 452 | writers = null; |
| 453 | |
| 454 | problem = null; |
| 455 | |
| 456 | creator = null; |
| 457 | |
| 458 | task = null; |
| 459 | |
| 460 | } |
| 461 | |
| 462 | /** |
| 463 | * Can only be called after calling {@link Opt4JStarter#init(List, DSEWorkflowConfiguration, PCMInstance, IProgressMonitor, MDSDBlackboard)}. |
| 464 | * @param writer |
| 465 | */ |
| 466 | public static void registerWriter(ResultsWriter writer) { |
| 467 | writers.add(writer); |
| 468 | |
| 469 | } |
| 470 | |
| 471 | public static Choice createRandomGene(int index, DesignDecisionGenotype genotype) { |
| 472 | if (Opt4JStarter.creator != null){ |
| 473 | return Opt4JStarter.creator.createRandomChoice(genotype.get(index).getDegreeOfFreedomInstance()); |
| 474 | } else { |
| 475 | logger.error("Could not create random value as DSECreator is not available."); |
| 476 | throw new RuntimeException("Could not create random value as DSECreator is not available."); |
| 477 | } |
| 478 | |
| 479 | } |
| 480 | |
| 481 | /** |
| 482 | * Can only be called after calling {@link Opt4JStarter#init(List, DSEWorkflowConfiguration, PCMInstance, IProgressMonitor, MDSDBlackboard)}. |
| 483 | * If not, this returns null. |
| 484 | * @return the problem or null. |
| 485 | */ |
| 486 | public static DSEProblem getProblem() { |
| 487 | return problem; |
| 488 | } |
| 489 | |
| 490 | /** |
| 491 | * Can only be called after calling {@link Opt4JStarter#init(List, DSEWorkflowConfiguration, PCMInstance, IProgressMonitor, MDSDBlackboard)}. |
| 492 | * @return |
| 493 | * @throws CoreException |
| 494 | */ |
| 495 | public static DSEEvaluator getDSEEvaluator() throws CoreException{ |
| 496 | Evaluator<?> e = task.getInstance(Evaluator.class); |
| 497 | if (e != null && e instanceof DSEEvaluator){ |
| 498 | return (DSEEvaluator)e; |
| 499 | } else { |
| 500 | throw new CoreException(new Status(Status.ERROR, |
| 501 | "de.uka.ipd.sdq.dsexplore", "Wrong initialisation of Evaluator: class DSEEvaluator expected, but found "+e == null ? "null" : e.getClass().getName())); |
| 502 | } |
| 503 | } |
| 504 | |
| 505 | /** |
| 506 | * Can only be called after calling {@link Opt4JStarter#init(List, DSEWorkflowConfiguration, PCMInstance, IProgressMonitor, MDSDBlackboard)}. |
| 507 | * @return |
| 508 | * @throws CoreException |
| 509 | */ |
| 510 | public static DSEDecoder getDSEDecoder() throws CoreException{ |
| 511 | DSEDecoder e = task.getInstance(DSEDecoder.class); |
| 512 | if (e != null){ |
| 513 | return e; |
| 514 | } else { |
| 515 | throw new CoreException(new Status(Status.ERROR, |
| 516 | "de.uka.ipd.sdq.dsexplore", "Wrong initialisation of Decoder: class DSEDecoder expected, but found null")); |
| 517 | } |
| 518 | } |
| 519 | |
| 520 | /** |
| 521 | * Can only be called after calling {@link Opt4JStarter#init(List, DSEWorkflowConfiguration, PCMInstance, IProgressMonitor, MDSDBlackboard)}. |
| 522 | * @return the {@link DSEWorkflowConfiguration} or null is init has not been called before. |
| 523 | */ |
| 524 | public static DSEWorkflowConfiguration getDSEWorkflowConfig() { |
| 525 | return myDSEConfig; |
| 526 | } |
| 527 | |
| 528 | /** |
| 529 | * Can only be called after calling {@link Opt4JStarter#init(List, DSEWorkflowConfiguration, PCMInstance, IProgressMonitor, MDSDBlackboard)}. |
| 530 | * @return |
| 531 | * @throws CoreException |
| 532 | */ |
| 533 | public static DSECreator getDSECreator() throws CoreException{ |
| 534 | DSECreator e = task.getInstance(DSECreator.class); |
| 535 | if (e != null){ |
| 536 | return e; |
| 537 | } else { |
| 538 | throw new CoreException(new Status(Status.ERROR, |
| 539 | "de.uka.ipd.sdq.dsexplore", "Wrong initialisation of Decoder: class DSEDecoder expected, but found null")); |
| 540 | } |
| 541 | } |
| 542 | |
| 543 | /** |
| 544 | * Resolves Objectives in the Configuration classes by using their String representation. |
| 545 | * Also Builds a Pareto Front for the "A Given Pareto Front Is Reached" from a file if needed. |
| 546 | * @author Atanas Dimitrov |
| 547 | * @throws CoreException |
| 548 | */ |
| 549 | private static void resolveObjectivesForTCM() throws CoreException { |
| 550 | |
| 551 | for (IConfiguration conf : myDSEConfig.getTCConfigurations()) { |
| 552 | |
| 553 | switch (conf.getTerminationCriterionName()) { |
| 554 | |
| 555 | case MINIMAL_QUALITY_CIRTERIA_VALUE: |
| 556 | Map<String, Value<?>> unresolvedObjectiveMap = ((MinimalQualityCriteriaValueConfig) conf).getUnresolvedObjectiveMinimalValue(); |
| 557 | |
| 558 | if (unresolvedObjectiveMap != null && !unresolvedObjectiveMap.isEmpty()) { |
| 559 | |
| 560 | Collection<Objective> objectives = Opt4JStarter.getDSEEvaluator().getObjectives(); |
| 561 | Set<String> unresolvedObjectives = unresolvedObjectiveMap.keySet(); |
| 562 | Map<Objective, Value<?>> configuredObjectives = new HashMap<Objective, Value<?>>(); |
| 563 | |
| 564 | |
| 565 | for (String unresolveObjective : unresolvedObjectives) { |
| 566 | for (Objective o : objectives) { |
| 567 | if(o instanceof UsageScenarioBasedObjective){ |
| 568 | if (unresolveObjective.contains(((UsageScenarioBasedObjective)o).getUsageScenario().getId())) { |
| 569 | configuredObjectives.put(o, unresolvedObjectiveMap.get(unresolveObjective)); |
| 570 | break; |
| 571 | } |
| 572 | }else{ |
| 573 | if (o.getName().contains(unresolveObjective) || unresolveObjective.contains(o.getName())) { |
| 574 | configuredObjectives.put(o, unresolvedObjectiveMap.get(unresolveObjective)); |
| 575 | break; |
| 576 | } |
| 577 | } |
| 578 | |
| 579 | } |
| 580 | } |
| 581 | |
| 582 | unresolvedObjectiveMap.clear(); |
| 583 | |
| 584 | try { |
| 585 | ((MinimalQualityCriteriaValueConfig) (conf)).setObjectiveMinimalValues(configuredObjectives); |
| 586 | } catch (InvalidConfigException e) { |
| 587 | // TODO Auto-generated catch block |
| 588 | e.printStackTrace(); |
| 589 | } |
| 590 | } |
| 591 | |
| 592 | break; |
| 593 | |
| 594 | case INSIGNIFICANT_SET_QUALITY_IMPROVEMENT: |
| 595 | List<UnresolvedValueDifference> unresolvedValueDifferences = ((InsignificantSetQualityImprovementConfig) conf).getUnresolvedValueDifferences(); |
| 596 | |
| 597 | if(unresolvedValueDifferences != null && !unresolvedValueDifferences.isEmpty()){ |
| 598 | Collection<Objective> objectives = Opt4JStarter.getDSEEvaluator().getObjectives(); |
| 599 | List<ValueDifference> valueDifferences = new LinkedList<ValueDifference>(); |
| 600 | |
| 601 | for(UnresolvedValueDifference uvd : unresolvedValueDifferences){ |
| 602 | |
| 603 | for (Objective o : objectives) { |
| 604 | if(o instanceof UsageScenarioBasedObjective){ |
| 605 | if (uvd.objective.contains(((UsageScenarioBasedObjective)o).getUsageScenario().getId())) { |
| 606 | try { |
| 607 | valueDifferences.add(((InsignificantSetQualityImprovementConfig) conf).new ValueDifference(o, uvd.averageImprovement, uvd.maxMinImprovement)); |
| 608 | } catch (InvalidConfigException e) { |
| 609 | // TODO Auto-generated catch block |
| 610 | e.printStackTrace(); |
| 611 | } |
| 612 | break; |
| 613 | } |
| 614 | }else{ |
| 615 | if (o.getName().contains(uvd.objective) || uvd.objective.contains(o.getName())) { |
| 616 | try { |
| 617 | valueDifferences.add(((InsignificantSetQualityImprovementConfig) conf).new ValueDifference(o, uvd.averageImprovement, uvd.maxMinImprovement)); |
| 618 | } catch (InvalidConfigException e) { |
| 619 | // TODO Auto-generated catch block |
| 620 | e.printStackTrace(); |
| 621 | } |
| 622 | break; |
| 623 | } |
| 624 | } |
| 625 | } |
| 626 | |
| 627 | } |
| 628 | |
| 629 | unresolvedValueDifferences.clear(); |
| 630 | |
| 631 | try { |
| 632 | ((InsignificantSetQualityImprovementConfig) conf).setValueDifferences(valueDifferences); |
| 633 | } catch (InvalidConfigException e) { |
| 634 | // TODO Auto-generated catch block |
| 635 | e.printStackTrace(); |
| 636 | } |
| 637 | |
| 638 | |
| 639 | } |
| 640 | |
| 641 | break; |
| 642 | |
| 643 | case GIVEN_PARETO_FRONT_IS_REACHED: |
| 644 | |
| 645 | String filePath = ((GivenParetoFrontIsReachedConfig) conf).getParetoFrontFile(); |
| 646 | |
| 647 | if(filePath != null && !filePath.isEmpty()){ |
| 648 | try { |
| 649 | ((GivenParetoFrontIsReachedConfig) conf).setParetoFront(GenotypeReader.getObjectives(filePath)); |
| 650 | } catch (InvalidConfigException e) { |
| 651 | e.printStackTrace(); |
| 652 | } |
| 653 | } |
| 654 | |
| 655 | ((GivenParetoFrontIsReachedConfig) conf).setParetoFrontFile(""); |
| 656 | |
| 657 | break; |
| 658 | } |
| 659 | |
| 660 | } |
| 661 | |
| 662 | } |
| 663 | } |
| 664 | |
| 665 | |