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

Last change on this file since 2026 was 2026, checked in by sherbold, 9 years ago
  • made generation of random sequences with an expected valid end and a predefined maximum length more robust. the generation now aborts after a user-defined number of attempts to create a valid sequence and returns an empty sequence instead.
  • Property svn:mime-type set to text/plain
File size: 7.2 KB
RevLine 
[927]1//   Copyright 2012 Georg-August-Universität Göttingen, Germany
2//
3//   Licensed under the Apache License, Version 2.0 (the "License");
4//   you may not use this file except in compliance with the License.
5//   You may obtain a copy of the License at
6//
7//       http://www.apache.org/licenses/LICENSE-2.0
8//
9//   Unless required by applicable law or agreed to in writing, software
10//   distributed under the License is distributed on an "AS IS" BASIS,
11//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//   See the License for the specific language governing permissions and
13//   limitations under the License.
14
[922]15package de.ugoe.cs.autoquest.testgeneration;
[523]16
17import java.util.Collection;
18import java.util.HashSet;
19import java.util.List;
20import java.util.Set;
21
[922]22import de.ugoe.cs.autoquest.eventcore.Event;
23import de.ugoe.cs.autoquest.usageprofiles.IStochasticProcess;
[523]24
25/**
26 * <p>
27 * Generates a test suite by randomly walking an {@link IStochasticProcess}.
28 * </p>
29 *
30 * @author Steffen Herbold
31 * @version 1.0
32 */
33public class RandomWalkGenerator {
34
[559]35    /**
36     * <p>
37     * Number of sequences in the test suite.
38     * </p>
39     */
40    private final int numSequences;
[523]41
[559]42    /**
43     * <p>
44     * Minimal length of a test sequence.
45     * </p>
46     */
47    private final int minLength;
[523]48
[559]49    /**
50     * <p>
51     * Maximal length of a test sequence.
52     * </p>
53     */
54    private final int maxLength;
[523]55
[559]56    /**
57     * <p>
58     * In case this member is true, only test cases that end in the global end event
59     * {@link Event#ENDEVENT} are generated. If it is false, the end event can be any event.
60     * </p>
61     */
62    private final boolean validEnd;
[523]63
[559]64    /**
65     * <p>
66     * Maximal number of random walks performed before aborting the test case generation and
67     * returning a test suite with less than {@link #numSequences} test cases. This can happen if
68     * too many generated random walks have to be discarded because their length is not between
69     * {@link #minLength} and {@link #maxLength}.
70     * </p>
71     */
72    private final long maxIter;
[523]73
[559]74    /**
75     * <p>
[2026]76     * Maximal number of attempts for creating a valid sequence. If this value is reached, the
77     * sequence generation will be aborted.
78     * </p>
79     */
80    private final long maxIterValidSequence;
81
82    /**
83     * <p>
[559]84     * Actual number of random walks performed to generate the test suite.
85     * </p>
86     */
87    private long actualIter = -1;
[523]88
[559]89    /**
90     * <p>
91     * Constructor. Creates a new RandomWalkGenerator and ensures the validity of the parameters:
92     * <ul>
93     * <li>numSequences must at least be 1
94     * <li>maxLength must at least be 1
95     * <li>minLength must be less than or equal to maxLength
96     * <li>maxIter must be greater than or equal to numSequences
97     * </ul>
[766]98     * If one of these conditions is violated an {@link IllegalArgumentException} is thrown.
[559]99     * </p>
100     *
101     * @param numSequences
102     *            number of sequences desired for the test suite
103     * @param minLength
104     *            minimal length of a test sequence
105     * @param maxLength
106     *            maximal length of a test sequence
107     * @param validEnd
108     *            defines if test cases have to end with the global end event {@link Event#ENDEVENT}
109     *            (see {@link #validEnd})
110     * @param maxIter
111     *            maximal number of random walks before aborting the test case generation (see
112     *            {@link #maxIter})
[2026]113     * @param maxIterValidSequence
114     *            maximal number of attempts to create a valid sequence within the given restrictions
[559]115     */
116    public RandomWalkGenerator(int numSequences,
117                               int minLength,
118                               int maxLength,
119                               boolean validEnd,
[2026]120                               long maxIter,
121                               long maxIterValidSequence)
[559]122    {
123        // check validity of the parameters
124        if (numSequences < 1) {
[766]125            throw new IllegalArgumentException("number of sequences must be at least 1 but is " +
[559]126                numSequences);
127        }
128        if (maxLength < 1) {
[766]129            throw new IllegalArgumentException(
[2026]130                                               "maximal allowed length of test cases must be at least 1 but is " +
131                                                   maxLength);
[559]132        }
133        if (minLength > maxLength) {
[766]134            throw new IllegalArgumentException(
[2026]135                                               "minimal allowed length of test cases must be less than or equal to the maximal allowed length (min length: " +
136                                                   minLength + " ; max length: " + maxLength + ")");
[559]137        }
138        if (maxIter < numSequences) {
[766]139            throw new IllegalArgumentException(
[2026]140                                               "maximal number of iterations must greater than or equal to the number of sequences (number of sequences: " +
141                                                   numSequences +
142                                                   " ; max iterations: " +
143                                                   maxIter +
144                                                   ")");
[559]145        }
[2026]146        if( maxIterValidSequence < 1) {
147            throw new IllegalArgumentException("maximal number of attempts to get a valid sequence must be positive, but is: " + maxIterValidSequence);
148        }
[559]149        this.numSequences = numSequences;
150        this.minLength = minLength;
151        this.maxLength = maxLength;
152        this.validEnd = validEnd;
153        this.maxIter = maxIter;
[2026]154        this.maxIterValidSequence = maxIterValidSequence;
[559]155    }
[523]156
[559]157    /**
158     * <p>
159     * Generates a test suite by repeatedly randomly walking a stochastic process.
160     * </p>
161     *
162     * @param model
163     *            stochastic process which performs the random walks
164     * @return the test suite
165     */
166    public Collection<List<Event>> generateTestSuite(IStochasticProcess model) {
167        if (model == null) {
[766]168            throw new IllegalArgumentException("model must not be null!");
[559]169        }
[523]170
[559]171        Set<List<Event>> sequences = new HashSet<List<Event>>(numSequences);
172        actualIter = 0;
173        while (sequences.size() < numSequences && actualIter < maxIter) {
[2026]174            List<Event> generatedSequence = model.randomSequence(maxLength, validEnd, maxIterValidSequence);
[559]175            if (generatedSequence.size() >= minLength && generatedSequence.size() <= maxLength) {
176                ((List<Event>) generatedSequence).add(0, Event.STARTEVENT);
177                if (validEnd) {
178                    ((List<Event>) generatedSequence).add(Event.ENDEVENT);
179                }
180                sequences.add(generatedSequence);
181            }
182            actualIter++;
183        }
[523]184
[559]185        return sequences;
186    }
[523]187
[559]188    /**
189     * <p>
190     * Returns the actual number of random walks performed during the last call of
191     * {@link #generateTestSuite(IStochasticProcess)} or -1 if
192     * {@link #generateTestSuite(IStochasticProcess)} has not been called yet.
193     * </p>
194     *
195     * @return actual number of random walks or -1 if {@link #generateTestSuite(IStochasticProcess)}
196     *         has not been called
197     */
198    public long getActualIter() {
199        return actualIter;
200    }
[523]201}
Note: See TracBrowser for help on using the repository browser.