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 | } |