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

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