source: trunk/quest-core-testgeneration/src/main/java/de/ugoe/cs/quest/testgeneration/DrawFromAllSequencesGenerator.java @ 655

Last change on this file since 655 was 655, checked in by pharms, 12 years ago
  • removed old copyright file header
  • Property svn:mime-type set to text/plain
File size: 6.2 KB
Line 
1package de.ugoe.cs.quest.testgeneration;
2
3import java.security.InvalidParameterException;
4import java.util.ArrayList;
5import java.util.Collection;
6import java.util.HashSet;
7import java.util.LinkedHashSet;
8import java.util.LinkedList;
9import java.util.List;
10import java.util.Random;
11import java.util.Set;
12import java.util.logging.Level;
13
14import de.ugoe.cs.quest.eventcore.Event;
15import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
16import de.ugoe.cs.util.console.Console;
17
18/**
19 * <p>
20 * Generates a test suite by drawing from all possible sequences of a fixed length according to the
21 * probabilities of the sequences in a {@link IStochasticProcess}.
22 * </p>
23 *
24 * @author Steffen Herbold
25 * @version 1.0
26 */
27public class DrawFromAllSequencesGenerator {
28
29    /**
30     * <p>
31     * Number of sequences in the test suite.
32     * </p>
33     */
34    private final int numSequences;
35
36    /**
37     * <p>
38     * Minimal length of a test sequence.
39     * </p>
40     */
41    private final int minLength;
42
43    /**
44     * <p>
45     * Maximal length of a test sequence.
46     * </p>
47     */
48    private final int maxLength;
49
50    /**
51     * <p>
52     * In case this member is true, only test cases that end in the global end event
53     * {@link Event#ENDEVENT} are generated. If it is false, the end event can be any event.
54     * </p>
55     */
56    private final boolean validEnd;
57
58    /**
59     * <p>
60     * If this member is true, the generated test suite contains all possible sequences and
61     * {@link #numSequences} is ignored.
62     * </p>
63     */
64    private final boolean generateAll;
65
66    /**
67     * <p>
68     * Constructor. Creates a new DrawFromAllSequencesGenerator and ensures the validity of the
69     * parameters:
70     * <ul>
71     * <li>numSequences must at least be 1
72     * <li>maxLength must at least be 1
73     * <li>minLength must be less than or equal to maxLength
74     * </ul>
75     * If one of these conditions is violated an {@link InvalidParameterException} is thrown.
76     * </p>
77     *
78     * @param numSequences
79     *            number of sequences desired for the test suite
80     * @param minLength
81     *            minimal length of a test sequence
82     * @param maxLength
83     *            maximal length of a test sequence
84     * @param validEnd
85     *            defines if test cases have to end with the global end event {@link Event#ENDEVENT}
86     *            (see {@link #validEnd})
87     * @param generateAll
88     *            if this parameter is true, the test suite contains all possible sequences and
89     *            numSequences is ignored
90     */
91    public DrawFromAllSequencesGenerator(int numSequences,
92                                         int minLength,
93                                         int maxLength,
94                                         boolean validEnd,
95                                         boolean generateAll)
96    {
97        // check validity of the parameters
98        if (numSequences < 1) {
99            throw new InvalidParameterException("number of sequences must be at least 1 but is " +
100                numSequences);
101        }
102        if (maxLength < 1) {
103            throw new InvalidParameterException(
104                                                "maximal allowed length of test cases must be at least 1 but is " +
105                                                    maxLength);
106        }
107        if (minLength > maxLength) {
108            throw new InvalidParameterException(
109                                                "minimal allowed length of test cases must be less than or equal to the maximal allowed length (min length: " +
110                                                    minLength + " ; max length: " + maxLength + ")");
111        }
112        this.numSequences = numSequences;
113        this.minLength = minLength;
114        this.maxLength = maxLength;
115        this.validEnd = validEnd;
116        this.generateAll = generateAll;
117    }
118
119    /**
120     * <p>
121     * Generates a test suite by drawing from all possible sequences with valid lengths.
122     * </p>
123     *
124     * @param model
125     *            model used to determine the probability of each possible sequence
126     * @return the test suite
127     */
128    public Collection<List<Event>> generateTestSuite(IStochasticProcess model) {
129        if (model == null) {
130            throw new InvalidParameterException("model must not be null!");
131        }
132
133        Collection<List<Event>> sequences = new LinkedHashSet<List<Event>>();
134        for (int length = minLength; length <= maxLength; length++) {
135            if (validEnd) {
136                sequences.addAll(model.generateValidSequences(length + 2));
137            }
138            else {
139                sequences.addAll(model.generateSequences(length + 1, true));
140            }
141        }
142        Console.traceln(Level.INFO, "" + sequences.size() + " possible");
143        if (!generateAll && numSequences < sequences.size()) {
144            List<Double> probabilities = new ArrayList<Double>(sequences.size());
145            double probSum = 0.0;
146            for (List<Event> sequence : sequences) {
147                double prob = model.getProbability(sequence);
148                probabilities.add(prob);
149                probSum += prob;
150            }
151            Set<Integer> drawnSequences = new HashSet<Integer>(numSequences);
152            Random r = new Random();
153            while (drawnSequences.size() < numSequences) {
154                double randVal = r.nextDouble() * probSum;
155                double sum = 0.0d;
156                int index = -1;
157                while (sum < randVal) {
158                    index++;
159                    double currentProb = probabilities.get(index);
160                    sum += currentProb;
161                }
162                if (!drawnSequences.contains(index)) {
163                    drawnSequences.add(index);
164                    probSum -= probabilities.get(index);
165                    probabilities.set(index, 0.0d);
166                }
167            }
168            Collection<List<Event>> retainedSequences = new LinkedList<List<Event>>();
169            int index = 0;
170            for (List<Event> sequence : sequences) {
171                if (drawnSequences.contains(index)) {
172                    retainedSequences.add(sequence);
173                }
174                index++;
175            }
176            sequences = retainedSequences;
177        }
178        return sequences;
179    }
180
181}
Note: See TracBrowser for help on using the repository browser.