| 1 | package de.uka.ipd.sdq.dsexplore.opt4j.representation; |
| 2 | |
| 3 | import java.util.List; |
| 4 | import java.util.Random; |
| 5 | |
| 6 | import org.eclipse.emf.ecore.EObject; |
| 7 | import org.opt4j.core.problem.Creator; |
| 8 | |
| 9 | import com.google.inject.Inject; |
| 10 | |
| 11 | import de.uka.ipd.sdq.dsexplore.opt4j.genotype.DesignDecisionGenotype; |
| 12 | import de.uka.ipd.sdq.dsexplore.opt4j.start.Opt4JStarter; |
| 13 | import de.uka.ipd.sdq.pcm.core.entity.Entity; |
| 14 | import de.uka.ipd.sdq.pcm.designdecision.Choice; |
| 15 | import de.uka.ipd.sdq.pcm.designdecision.ContinousRangeChoice; |
| 16 | import de.uka.ipd.sdq.pcm.designdecision.ContinuousRangeDegree; |
| 17 | import de.uka.ipd.sdq.pcm.designdecision.DegreeOfFreedomInstance; |
| 18 | import de.uka.ipd.sdq.pcm.designdecision.DiscreteDegree; |
| 19 | import de.uka.ipd.sdq.pcm.designdecision.DiscreteRangeChoice; |
| 20 | import de.uka.ipd.sdq.pcm.designdecision.DiscreteRangeDegree; |
| 21 | import de.uka.ipd.sdq.pcm.designdecision.ClassChoice; |
| 22 | import de.uka.ipd.sdq.pcm.designdecision.ClassDegree; |
| 23 | import de.uka.ipd.sdq.pcm.designdecision.OrderedIntegerDegree; |
| 24 | import de.uka.ipd.sdq.pcm.designdecision.SchedulingPolicyChoice; |
| 25 | import de.uka.ipd.sdq.pcm.designdecision.SchedulingPolicyDegree; |
| 26 | import de.uka.ipd.sdq.pcm.designdecision.designdecisionFactory; |
| 27 | import de.uka.ipd.sdq.pcm.designdecision.impl.designdecisionFactoryImpl; |
| 28 | import de.uka.ipd.sdq.pcm.resourceenvironment.SchedulingPolicy; |
| 29 | |
| 30 | /** |
| 31 | * The {@link DSECreator} is responsible for randomly creating genotypes |
| 32 | * in the solution space. It can query the {@link DSEProblem} for the |
| 33 | * available design space. |
| 34 | * |
| 35 | * @author Anne |
| 36 | * |
| 37 | */ |
| 38 | public class DSECreator implements Creator<DesignDecisionGenotype> { |
| 39 | |
| 40 | private DSEProblem problem; |
| 41 | private Random random; |
| 42 | |
| 43 | private int numberOfNotEvaluatedPredefinedOnes; |
| 44 | |
| 45 | @Inject |
| 46 | public DSECreator(){ |
| 47 | //XXX like this you can only set the problem once. Maybe dont save the reference. |
| 48 | this.problem = Opt4JStarter.getProblem(); |
| 49 | this.random = new Random(); |
| 50 | this.numberOfNotEvaluatedPredefinedOnes = this.problem.getInitialGenotypeList().size(); |
| 51 | } |
| 52 | |
| 53 | |
| 54 | @Override |
| 55 | public DesignDecisionGenotype create() { |
| 56 | |
| 57 | if (this.numberOfNotEvaluatedPredefinedOnes > 0){ |
| 58 | DesignDecisionGenotype genome = this.problem.getInitialGenotypeList().get(this.problem.getInitialGenotypeList().size()-this.numberOfNotEvaluatedPredefinedOnes); |
| 59 | numberOfNotEvaluatedPredefinedOnes --; |
| 60 | return genome; |
| 61 | |
| 62 | } |
| 63 | |
| 64 | DesignDecisionGenotype genotype = new DesignDecisionGenotype(); |
| 65 | |
| 66 | List<DegreeOfFreedomInstance> degrees = problem.getDesignDecisions(); |
| 67 | for (DegreeOfFreedomInstance DegreeOfFreedomInstance : degrees) { |
| 68 | genotype.add(createRandomChoice(DegreeOfFreedomInstance)); |
| 69 | } |
| 70 | |
| 71 | return genotype; |
| 72 | } |
| 73 | |
| 74 | |
| 75 | private int createIntegerValue(DiscreteDegree discDegree) { |
| 76 | |
| 77 | if (discDegree instanceof DiscreteRangeDegree){ |
| 78 | DiscreteRangeDegree dicRangeDegree = (DiscreteRangeDegree)discDegree; |
| 79 | int range = dicRangeDegree.getTo() - dicRangeDegree.getFrom(); |
| 80 | if (!dicRangeDegree.isLowerBoundIncluded()) range--; |
| 81 | if (!dicRangeDegree.isUpperBoundIncluded()) range--; |
| 82 | //random.nextInt creates a random value between 0 <= x < param. I want one 0 <= x <= range. Thus, I add 1 |
| 83 | int value = dicRangeDegree.getFrom() + this.random.nextInt(range+1); |
| 84 | return value; |
| 85 | } else if (discDegree instanceof OrderedIntegerDegree){ |
| 86 | OrderedIntegerDegree orderedIntegerDegree = (OrderedIntegerDegree) discDegree; |
| 87 | int randomIndex = this.random.nextInt(orderedIntegerDegree.getListOfIntegers().size()); |
| 88 | return orderedIntegerDegree.getListOfIntegers().get(randomIndex); |
| 89 | } else throw new RuntimeException("Unknown degree "+discDegree.getClass().getName()); |
| 90 | |
| 91 | } |
| 92 | |
| 93 | |
| 94 | private double createDoubleValue(ContinuousRangeDegree contDegree) { |
| 95 | double lowerMargin = 0; |
| 96 | if (contDegree.isLowerBoundIncluded()){ |
| 97 | lowerMargin = Double.MIN_VALUE; |
| 98 | } |
| 99 | double upperMargin = 0; |
| 100 | if (contDegree.isUpperBoundIncluded()){ |
| 101 | upperMargin = Double.MIN_VALUE; |
| 102 | } |
| 103 | double factor = contDegree.getTo() - upperMargin - contDegree.getFrom() - lowerMargin; |
| 104 | |
| 105 | |
| 106 | return contDegree.getFrom() + lowerMargin + this.random.nextDouble()*factor; |
| 107 | |
| 108 | } |
| 109 | |
| 110 | |
| 111 | |
| 112 | public Choice createRandomChoice(DegreeOfFreedomInstance degree) { |
| 113 | designdecisionFactory factory = designdecisionFactoryImpl.init(); |
| 114 | Choice choice; |
| 115 | if (degree instanceof DiscreteDegree){ |
| 116 | DiscreteRangeChoice discChoice = factory.createDiscreteRangeChoice() ; |
| 117 | discChoice.setChosenValue(createIntegerValue((DiscreteDegree)degree)); |
| 118 | choice = discChoice; |
| 119 | } else if (degree instanceof ContinuousRangeDegree){ |
| 120 | ContinousRangeChoice contChoice = factory.createContinousRangeChoice(); |
| 121 | contChoice.setChosenValue(createDoubleValue((ContinuousRangeDegree)degree)); |
| 122 | choice = contChoice; |
| 123 | } else if (degree instanceof ClassDegree){ |
| 124 | ClassChoice enumChoice = factory.createClassChoice(); |
| 125 | enumChoice.setChosenValue(createRandomEntity((ClassDegree)degree)); |
| 126 | choice = enumChoice; |
| 127 | } else if (degree instanceof SchedulingPolicyDegree){ |
| 128 | SchedulingPolicyChoice schedChoice = factory.createSchedulingPolicyChoice(); |
| 129 | schedChoice.setChosenValue(createRandomSchedulingPolicy((SchedulingPolicyDegree)degree)); |
| 130 | choice = schedChoice; |
| 131 | } else throw new RuntimeException("Unknown degree "+degree.getClass().getName()); |
| 132 | choice.setDegreeOfFreedomInstance(degree); |
| 133 | return choice; |
| 134 | } |
| 135 | |
| 136 | |
| 137 | |
| 138 | private SchedulingPolicy createRandomSchedulingPolicy( |
| 139 | SchedulingPolicyDegree degree) { |
| 140 | List<SchedulingPolicy> domain = degree.getDomainOfAllowedSchedulingPolicies(); |
| 141 | int index = this.random.nextInt(domain.size()); |
| 142 | return domain.get(index); |
| 143 | } |
| 144 | |
| 145 | |
| 146 | private EObject createRandomEntity(ClassDegree enumDegree) { |
| 147 | List<EObject> domain = enumDegree.getClassDesignOptions(); |
| 148 | int index = this.random.nextInt(domain.size()); |
| 149 | return domain.get(index); |
| 150 | |
| 151 | } |
| 152 | |
| 153 | public void setNumberOfNotEvaluatedPredefinedOnes( |
| 154 | int numberOfNotEvaluatedPredefinedOnes) { |
| 155 | this.numberOfNotEvaluatedPredefinedOnes = numberOfNotEvaluatedPredefinedOnes; |
| 156 | } |
| 157 | |
| 158 | public int getNumberOfNotEvaluatedPredefinedOnes(){ |
| 159 | return this.numberOfNotEvaluatedPredefinedOnes; |
| 160 | } |
| 161 | } |