EMMA Coverage Report (generated Sun Feb 05 10:43:15 CET 2012)
[all classes][de.uka.ipd.sdq.dsexplore.opt4j.optimizer.heuristic.startingPopulation.impl]

COVERAGE SUMMARY FOR SOURCE FILE [StartingPopulationHeuristicImpl.java]

nameclass, %method, %block, %line, %
StartingPopulationHeuristicImpl.java0%   (0/2)0%   (0/15)0%   (0/724)0%   (0/123)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class StartingPopulationHeuristicImpl0%   (0/1)0%   (0/11)0%   (0/644)0%   (0/121)
$SWITCH_TABLE$de$uka$ipd$sdq$dsexplore$opt4j$optimizer$heuristic$startingPopu... 0%   (0/1)0%   (0/48)0%   (0/1)
StartingPopulationHeuristicImpl (DSEWorkflowConfiguration): void 0%   (0/1)0%   (0/16)0%   (0/5)
allocateContextToContainer (ResourceContainer, int, DSEIndividual): void 0%   (0/1)0%   (0/75)0%   (0/19)
allocateRandomlyToContainer (Individual, ResourceContainer, int, ArrayList): ... 0%   (0/1)0%   (0/31)0%   (0/6)
getAdjustedProcessingRatePopulation (Collection, IndividualBuilder, StartingP... 0%   (0/1)0%   (0/111)0%   (0/25)
getNumberOfComponentsPerResourceContainer (int, int): ArrayList 0%   (0/1)0%   (0/76)0%   (0/10)
getParetoOptimalIndividuals (List): List 0%   (0/1)0%   (0/76)0%   (0/15)
getRandomIndividual (ArrayList, Individual): Individual 0%   (0/1)0%   (0/44)0%   (0/6)
getRandomInt (int, int): int 0%   (0/1)0%   (0/14)0%   (0/2)
getStartingPopulation (Completer, IndividualBuilder, DSEIndividual): Collection 0%   (0/1)0%   (0/48)0%   (0/8)
getStartingPopulationWithDefaultProcessingRate (Completer, IndividualBuilder,... 0%   (0/1)0%   (0/105)0%   (0/24)
     
class StartingPopulationHeuristicImpl$PROCESSING_RATE_LEVEL0%   (0/1)0%   (0/4)0%   (0/80)0%   (0/2)
<static initializer> 0%   (0/1)0%   (0/54)0%   (0/1)
StartingPopulationHeuristicImpl$PROCESSING_RATE_LEVEL (String, int): void 0%   (0/1)0%   (0/5)0%   (0/1)
valueOf (String): StartingPopulationHeuristicImpl$PROCESSING_RATE_LEVEL 0%   (0/1)0%   (0/5)0%   (0/1)
values (): StartingPopulationHeuristicImpl$PROCESSING_RATE_LEVEL [] 0%   (0/1)0%   (0/16)0%   (0/1)

1package de.uka.ipd.sdq.dsexplore.opt4j.optimizer.heuristic.startingPopulation.impl;
2 
3import java.util.ArrayList;
4import java.util.Collection;
5import java.util.LinkedList;
6import java.util.List;
7import java.util.Random;
8 
9import org.eclipse.emf.ecore.EObject;
10import org.opt4j.core.Individual;
11import org.opt4j.core.IndividualBuilder;
12import org.opt4j.core.optimizer.Completer;
13import org.opt4j.core.optimizer.TerminationException;
14 
15import de.uka.ipd.sdq.dsexplore.launch.DSEWorkflowConfiguration;
16import de.uka.ipd.sdq.dsexplore.opt4j.genotype.DesignDecisionGenotype;
17import de.uka.ipd.sdq.dsexplore.opt4j.operator.CopyDesignDecisionGenotype;
18import de.uka.ipd.sdq.dsexplore.opt4j.optimizer.heuristic.startingPopulation.AbstractStartingPopulationHeuristic;
19import de.uka.ipd.sdq.dsexplore.opt4j.representation.DSEIndividual;
20import de.uka.ipd.sdq.pcm.core.entity.Entity;
21import de.uka.ipd.sdq.pcm.designdecision.AllocationDegree;
22import de.uka.ipd.sdq.pcm.designdecision.Choice;
23import de.uka.ipd.sdq.pcm.designdecision.ContinousRangeChoice;
24import de.uka.ipd.sdq.pcm.designdecision.ContinuousProcessingRateDegree;
25import de.uka.ipd.sdq.pcm.designdecision.DegreeOfFreedomInstance;
26import de.uka.ipd.sdq.pcm.designdecision.ClassChoice;
27import de.uka.ipd.sdq.pcm.resourceenvironment.ResourceContainer;
28 
29/**
30 * Class implements a basic strategy to implement a heuristic that generates a starting
31 * population. The user specifies minNumerOfResourceContainers and maxNumberOfResourceContainers. Then
32 * the algorithm will generate numberOfCandidatesPerAllocationLevel individuals for each resource container
33 * number ("allocation level") between minNumberOfResourceContainers and maxNumberOfResourceContainers using a random allocation
34 * of components (resp. allocation contexts) to resource containers and the default processing rate (as used
35 * by firstIndividual. For each allocation level all individuals are evaluated and the Pareto optimal
36 * candidates are put into the population. Then four new individuals are generated for each Pareto optimal 
37 * individual in the population. These new individuals use four different processing rates: minimum processing
38 * rate, maximum processing rate, lower processing rate (mean between default and minimum) and higher processing rate 
39 * (mean between default and maximum). All of them are put into the population as well.
40 * @author Tom Beyer
41 *
42 */
43public class StartingPopulationHeuristicImpl extends AbstractStartingPopulationHeuristic {
44        private int minNumberOfResourceContainers;
45        private int maxNumberOfResourceContainers;
46        private final static int MAX_TRIES = 50;
47//        private final double thresholdMaxUtilisation = 0.70;
48        private int numberOfCandidatesPerAllocationLevel;
49        public enum PROCESSING_RATE_LEVEL {MIN, LESS, DEFAULT, MORE, MAX};
50        
51        /**
52         * 
53         * @param configuration As defined by the user in the GUI.
54         */
55        public StartingPopulationHeuristicImpl(DSEWorkflowConfiguration configuration) {
56                super(configuration);
57                minNumberOfResourceContainers = configuration.getMinNumberOfResourceContainers();
58                maxNumberOfResourceContainers = configuration.getMaxNumberOfResourceContainers();
59                numberOfCandidatesPerAllocationLevel = configuration.getNumberOfCandidatesPerAllocationLevel();
60        }
61        
62        /**
63         * 
64         * @param numberOfComponents
65         * @param numberOfResourceContainers
66         * @return Calculates the number of components on each resource container when using numberOfComponents allocation
67         * contexts and numberOfResourceContainers resource containers. Integer represents number of components/allocation 
68         * contexts and each resource container. Size of array will be numberOfResourceContainers.
69         */
70        public static ArrayList<Integer> getNumberOfComponentsPerResourceContainer(int numberOfComponents, int numberOfResourceContainers) {
71                if (numberOfResourceContainers <= 0 || numberOfComponents < 0) {
72                        throw new IllegalArgumentException();
73                }
74                // calculate number of resource containers with floor(numberOfComponents/numberOfResourceContainers) components
75                int numberOfServersWithLessComponents = (int) ((numberOfComponents - Math.ceil(((double)numberOfComponents)/((double)numberOfResourceContainers))*numberOfResourceContainers)/
76                                (Math.floor(((double)numberOfComponents)/((double)numberOfResourceContainers))-Math.ceil(((double)numberOfComponents)/((double)numberOfResourceContainers))));
77                ArrayList<Integer> numberOfComponentsPerResourceContainer = new ArrayList<Integer>(numberOfResourceContainers);
78                for (int i = 1; i <= numberOfResourceContainers; i++) {
79                        if (i <= numberOfServersWithLessComponents) {
80                                numberOfComponentsPerResourceContainer.add((int)Math.floor(((double)numberOfComponents)/((double)numberOfResourceContainers)));
81                        } else {
82                                numberOfComponentsPerResourceContainer.add((int)Math.ceil(((double)numberOfComponents)/((double)numberOfResourceContainers)));
83                        }
84                }
85                return numberOfComponentsPerResourceContainer;
86        }
87        
88        /**
89         * Used to generate starting population as described in class documentation.
90         * 
91         * FIXME: Must only use those servers that are allowed in designdecisions. 
92         */
93        public Collection<DSEIndividual> getStartingPopulation(Completer completer, IndividualBuilder individualBuilder, DSEIndividual baseIndividual) {
94                Collection<DSEIndividual> result = new LinkedList<DSEIndividual>();
95                // default processing rate
96                Collection<DSEIndividual> population = getStartingPopulationWithDefaultProcessingRate(completer, individualBuilder, baseIndividual);
97                // max processing rate
98                result.addAll(getAdjustedProcessingRatePopulation(population, individualBuilder, PROCESSING_RATE_LEVEL.MAX));
99                // min processing rate
100                result.addAll(getAdjustedProcessingRatePopulation(population, individualBuilder, PROCESSING_RATE_LEVEL.MIN));
101                // less processing rate
102                result.addAll(getAdjustedProcessingRatePopulation(population, individualBuilder, PROCESSING_RATE_LEVEL.LESS));
103                // more processing rate
104                result.addAll(getAdjustedProcessingRatePopulation(population, individualBuilder, PROCESSING_RATE_LEVEL.MORE));
105                result.addAll(population);
106                return result;
107        }
108 
109        
110        private Collection<DSEIndividual> getAdjustedProcessingRatePopulation(Collection<DSEIndividual> population, IndividualBuilder individualBuilder, PROCESSING_RATE_LEVEL processingRateLevel) {
111                CopyDesignDecisionGenotype copy = new CopyDesignDecisionGenotype();
112                Collection<DSEIndividual> result = new LinkedList<DSEIndividual>();
113                for (DSEIndividual individual : population) {
114                        DSEIndividual newIndividual = (DSEIndividual)individualBuilder.build(copy.copy((DesignDecisionGenotype)individual.getGenotype()));
115                        result.add(newIndividual);
116                }
117                for (DSEIndividual individual : result) {
118                        for (Choice choice : individual.getGenotype()) {
119                                if (choice instanceof ContinousRangeChoice) {
120                                        ContinousRangeChoice continousRangeChoice = (ContinousRangeChoice) choice;
121                                        DegreeOfFreedomInstance DegreeOfFreedomInstance = choice.getDegreeOfFreedomInstance();
122                                        if (DegreeOfFreedomInstance instanceof ContinuousProcessingRateDegree) {
123                                                ContinuousProcessingRateDegree processingRateDegree = (ContinuousProcessingRateDegree) DegreeOfFreedomInstance;
124                                                // actually adjust processing rate. Respect
125                                                // maximum and minimum allowed value of processing rate
126                                                double newProcessingRate = continousRangeChoice.getChosenValue();
127                                                switch (processingRateLevel) {
128                                                case MIN:
129                                                        newProcessingRate = processingRateDegree.getFrom();
130                                                        break;
131                                                case LESS:
132                                                        newProcessingRate = (processingRateDegree.getFrom() + continousRangeChoice.getChosenValue())/2;
133                                                        break;
134                                                case DEFAULT:
135                                                        newProcessingRate = continousRangeChoice.getChosenValue();
136                                                        break;
137                                                case MORE:
138                                                        newProcessingRate = (processingRateDegree.getTo() + continousRangeChoice.getChosenValue())/2;
139                                                        break;
140                                                case MAX:
141                                                        newProcessingRate = processingRateDegree.getTo();
142                                                        break;
143                                                }
144                                                continousRangeChoice.setChosenValue(newProcessingRate);
145                                        }
146                                }
147                        }
148                }
149                return result;
150        }
151 
152//        public Collection<DSEIndividual> getStartingPopulation(Completer completer, IndividualBuilder individualBuilder, int populationSize, DSEIndividual firstIndividual) {
153//                Collection<DSEIndividual> population = new LinkedList<DSEIndividual>();
154//                CopyDesignDecisionGenotype copy = new CopyDesignDecisionGenotype();
155//                if (minNumberOfResourceContainers > maxNumberOfResourceContainers) {
156//                        throw new IllegalArgumentException("Minimum number of resource containers cannot be larger than maximum number of containers.");
157//                }
158//                if (maxNumberOfResourceContainers > getResourceContainers().size()) {
159//                        throw new IllegalArgumentException("There are not enough resource containers available.");
160//                }
161//                int tries = 0;
162//                while (population.size() < populationSize && tries < populationSize + MAX_TRIES) {
163//                        int randomNumberOfResourceContainers = getRandomInt(minNumberOfResourceContainers, maxNumberOfResourceContainers);
164//                        ArrayList<Integer> allocation = getNumberOfComponentsPerResourceContainer(getAllocationContexts().size(), randomNumberOfResourceContainers);
165//                        DSEIndividual newIndividual = (DSEIndividual)individualBuilder.build(copy.copy((DesignDecisionGenotype)firstIndividual.getGenotype()));
166//                        newIndividual = (DSEIndividual) getRandomIndividual(allocation, newIndividual);
167//                        if (!population.contains(newIndividual)) {
168//                                try {
169//                                        completer.complete(newIndividual);
170//                                        if(UtilisationHelper.getMaxUtilisation((DSEIndividual) newIndividual) <= thresholdMaxUtilisation) {
171//                                                population.add(newIndividual);
172//                                        }
173//                                } catch (TerminationException e) {
174//                                        // nothing to do here. we don't add the individual to the population
175//                                } catch (NullPointerException e) {
176//                                        // nothing to do here. we don't add the individual to the population
177//                                }
178//                                
179//                        }
180//                        tries++;
181//                }
182//                return population;
183//        }
184        
185        private Collection<DSEIndividual> getStartingPopulationWithDefaultProcessingRate(Completer completer, IndividualBuilder individualBuilder,
186                        DSEIndividual firstIndividual) {
187                Collection<DSEIndividual> population = new LinkedList<DSEIndividual>();
188                CopyDesignDecisionGenotype copy = new CopyDesignDecisionGenotype();
189                if (minNumberOfResourceContainers > maxNumberOfResourceContainers) {
190                        throw new IllegalArgumentException(
191                                        "Minimum number of resource containers cannot be larger than maximum number of containers. Check your starting population heuristic settings.");
192                }
193                if (maxNumberOfResourceContainers > getResourceContainers().size()) {
194                        throw new IllegalArgumentException("There are not enough resource containers available. Decrease the \"maximum number of resource containers\" setting in the starting population heuristic configuration in your launch configuration.");
195                }
196                for (int numberOfResourceContainers = minNumberOfResourceContainers; numberOfResourceContainers <= maxNumberOfResourceContainers; numberOfResourceContainers++) {
197                        List<DSEIndividual> individualsForAllocation = new ArrayList<DSEIndividual>();
198                        int tries = 0;
199                        while (individualsForAllocation.size() < numberOfCandidatesPerAllocationLevel && tries <= numberOfCandidatesPerAllocationLevel + MAX_TRIES) {
200                                ArrayList<Integer> allocation = getNumberOfComponentsPerResourceContainer(getAllocationContexts()
201                                                .size(), numberOfResourceContainers);
202                                DSEIndividual newIndividual = (DSEIndividual) individualBuilder.build(copy
203                                                .copy((DesignDecisionGenotype) firstIndividual.getGenotype()));
204                                newIndividual = (DSEIndividual) getRandomIndividual(allocation, newIndividual);
205                                if (!individualsForAllocation.contains(newIndividual)) {
206                                        try {
207                                                completer.complete(newIndividual);
208                                                individualsForAllocation.add(newIndividual);
209                                        } catch (TerminationException e) {
210                                                // nothing to do here. we don't add the individual to
211                                                // the population
212                                        } catch (NullPointerException e) {
213                                                // nothing to do here. we don't add the individual to
214                                                // the population
215                                        }
216                                }
217                                tries++;
218                        }
219                        population.addAll(getParetoOptimalIndividuals(individualsForAllocation));
220                }
221                return population;
222        }
223        
224        
225        private List<DSEIndividual> getParetoOptimalIndividuals(List<DSEIndividual> individuals) {
226                if (individuals.isEmpty()) {
227                        return null;
228                }
229                List<DSEIndividual> toBeRemoved = new ArrayList<DSEIndividual>(individuals.size());
230                List<DSEIndividual> result = new ArrayList<DSEIndividual>(individuals.size());
231                
232                result.addAll(individuals);
233                
234                for (int i = 0; i < individuals.size(); i++) {
235                        DSEIndividual indiv1 = individuals.get(i);
236                        for (int j = i + 1; j < individuals.size(); j++){
237                                DSEIndividual indiv2 = individuals.get(j);
238                                if (indiv1.getObjectives().dominates(indiv2.getObjectives())){
239                                        toBeRemoved.add(indiv2);
240                                } else if (indiv2.getObjectives().dominates(indiv1.getObjectives())){
241                                        toBeRemoved.add(indiv1);
242                                }
243                        }
244                        
245                }
246                
247                result.removeAll(toBeRemoved);
248                return result;
249        }
250        
251        private Individual getRandomIndividual(ArrayList<Integer> allocation, Individual individual) {
252                ArrayList<Integer> contexts = new ArrayList<Integer>();
253                for (int i = 0; i < getAllocationContexts().size(); i++) {
254                        contexts.add(new Integer(i));
255                }
256                for (int i = 0; i < allocation.size(); i++) {
257                        allocateRandomlyToContainer(individual, getResourceContainers().get(i), allocation.get(i), contexts);
258                }
259                return individual;
260        }
261        
262        private void allocateRandomlyToContainer(Individual individual, ResourceContainer container, int numberOfAllocationContexts,
263                        ArrayList<Integer> contexts) {
264                
265                for (int i = 1; i <= numberOfAllocationContexts; i++) {
266                        int randomIndex = getRandomInt(0, contexts.size()-1);
267                        int randomContext = contexts.get(randomIndex);
268                        allocateContextToContainer(container, randomContext, (DSEIndividual)individual);
269                        contexts.remove(randomIndex);
270                }
271        }
272        
273        private void allocateContextToContainer(ResourceContainer container, int allocationContext,
274                        DSEIndividual individual) {
275                int iterationCounter = 0;
276                for (Choice choice : individual.getGenotype()) {
277                        if (choice instanceof ClassChoice) {
278                                ClassChoice ClassChoice = (ClassChoice)choice;
279                                if (ClassChoice.getDegreeOfFreedomInstance() instanceof AllocationDegree) {
280                                        if (iterationCounter == allocationContext) {
281                                                boolean foundMatchingServer = false;
282                                                DegreeOfFreedomInstance dof = ClassChoice.getDegreeOfFreedomInstance();
283                                                if (dof instanceof AllocationDegree){
284                                                        List<EObject> domain = ((AllocationDegree) dof).getClassDesignOptions();
285                                                        for (EObject entity : domain) {
286                                                                if (entity instanceof Entity && ((Entity)entity).getId().equals(container.getId())){
287                                                                        ClassChoice.setChosenValue(container);
288                                                                        foundMatchingServer = true;
289                                                                        break;
290                                                                }
291                                                        }
292                                                }
293                                                if (!foundMatchingServer){
294                                                        throw new RuntimeException("Start Population Heuristic only supports design decision files that allow all components to be allocated to all servers. Sorry! Please disable the Starting population heuristic for this model.");
295                                                }
296                                                
297                                        }
298                                }
299                                iterationCounter++;
300                        }
301                }
302        }
303 
304        /**
305         * Generates random int between from (inclusive) and to (inclusive) based on uniform distribution
306         * @param from
307         * @param to
308         * @return Random int with from <= return value <= to
309         */
310        private static int getRandomInt(int from, int to) {
311                Random random = new Random();
312                return random.nextInt(to - from + 1) + from;
313        }
314 
315}

[all classes][de.uka.ipd.sdq.dsexplore.opt4j.optimizer.heuristic.startingPopulation.impl]
EMMA 2.0.9414 (unsupported private build) (C) Vladimir Roubtsov