001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: /**
028: * Wraps Java's random number generator class. This is a
029: * singleton class, to get a reference to the singleton
030: * instance use the instanceOf() method.
031: */package org.cougaar.lib.util;
032:
033: import java.util.Random;
034:
035: import org.cougaar.util.log.Logger;
036: import org.cougaar.util.log.LoggerFactory;
037:
038: public final class UTILRandom extends Random {
039: private static Logger logger = LoggerFactory.getInstance()
040: .createLogger("UTILRandom");
041:
042: /**
043: * Get an instance of the class
044: * @return UTILRandom
045: */
046: public static UTILRandom instanceOf() {
047: if (my_instance == null)
048: my_instance = new UTILRandom();
049: return my_instance;
050: }
051:
052: /**
053: * Get an instance of the class, if an instance of the class
054: * already exists it will just reseed.
055: * @return UTILRandom
056: */
057: public static UTILRandom instanceOf(long seed) {
058: if (my_instance == null)
059: my_instance = new UTILRandom(seed);
060: else
061: my_instance.setSeed(seed);
062: return my_instance;
063: }
064:
065: /**
066: * Pseudo-random number between 0 and range-1
067: * @return int, ArithmeticException if range is 0
068: */
069: public int randomInt(int range) {
070: if (range == 0)
071: throw new ArithmeticException("this does not make sense");
072: else if (range == 1)
073: return 0;
074: else
075: return Math.abs(this .nextInt()) % range;
076: }
077:
078: /**
079: * Filps a coin, true == head, false == tails
080: * @return boolean
081: */
082: public boolean flipCoin() {
083: return (this .randomInt(2) == 1);
084: }
085:
086: /**
087: * Computes a pseudo-random integer between min and max
088: * @return int, ArithmeticException is min > max
089: */
090: public int randomInt(int min, int max) {
091: if (max < min)
092: throw new ArithmeticException("this does not make sence");
093: else if (max == min)
094: return min;
095: else
096: return this .randomInt(max - min + 1) + min;
097: }
098:
099: // noone should be accessing the contructors
100: private UTILRandom(long seed) {
101: super (seed);
102: }
103:
104: private UTILRandom() {
105: super ();
106: }
107:
108: private static UTILRandom my_instance = null;
109:
110: protected void finalize() {
111: my_instance = null;
112: }
113:
114: /**
115: * TEST CODE
116: */
117: public static void main(String[] argc) {
118: int[] counter = new int[4];
119: int x;
120: boolean b;
121: UTILRandom r = instanceOf();
122:
123: counter[0] = 0;
124: counter[1] = 0;
125: counter[2] = 0;
126: counter[3] = 0;
127:
128: logger.debug("::: Test for UTILRandom class :::");
129:
130: // test several times to ensure
131: // predictability after seeding
132: for (int j = 0; j < 3; j++) {
133:
134: // TESTING flipCoin Function
135: for (int i = 0; i < 100000; i++) {
136: b = r.flipCoin();
137: if (b)
138: counter[0]++;
139: else
140: counter[1]++;
141: }
142:
143: logger.debug("Number of HEADS: " + counter[0]);
144: logger.debug("Number of TAILS: " + counter[1]);
145:
146: counter[0] = 0;
147: counter[1] = 0;
148: counter[2] = 0;
149: counter[3] = 0;
150:
151: r = instanceOf(1);
152: logger.debug("");
153: }
154:
155: r = UTILRandom.instanceOf(500);
156: // The follwing throws a runtime exception by design
157: // x = r.randomInt(0);
158: // uncomment to tet it.
159: for (int i = 0; i < 5; i++) {
160: x = r.randomInt(1);
161: if (x != 0)
162: logger.debug("failed");
163: else
164: logger.debug("OK");
165: }
166: logger.debug("");
167:
168: // TESTING RandomIint(int) Function
169: // test several times to ensure
170: // predictability after seeding
171: for (int j = 0; j < 3; j++) {
172: for (int i = 0; i < 100000; i++) {
173: x = r.randomInt(4);
174: switch (x) {
175: case 0:
176: counter[0]++;
177: break;
178: case 1:
179: counter[1]++;
180: break;
181: case 2:
182: counter[2]++;
183: break;
184: case 3:
185: counter[3]++;
186: break;
187: default:
188: logger.debug("there is an error " + x);
189: logger.debug("we should never be here");
190: break;
191: }
192: }
193:
194: logger.debug("Number of 0: " + counter[0]);
195: logger.debug("Number of 1: " + counter[1]);
196: logger.debug("Number of 2: " + counter[2]);
197: logger.debug("Number of 3: " + counter[3]);
198:
199: // TESTING randomInt(int, int) Function
200: counter[0] = 0;
201: counter[1] = 0;
202: counter[2] = 0;
203: counter[3] = 0;
204: logger.debug("");
205:
206: r = UTILRandom.instanceOf(1000);
207: logger.debug("");
208: }
209:
210: r = UTILRandom.instanceOf(1500);
211: // The follwing throws a runtime exception by design
212: //x = r.randomInt(5,4);
213: // uncomment to test it.
214: for (int i = 0; i < 5; i++) {
215: x = r.randomInt(4, 4);
216: if (x != 4)
217: logger.debug("failed");
218: else
219: logger.debug("OK");
220: }
221: logger.debug("");
222:
223: // TESTING RandomIint(int) Function
224: // test several times to ensure
225: // predictability after seeding
226: for (int j = 0; j < 3; j++) {
227:
228: for (int i = 0; i < 100000; i++) {
229: x = r.randomInt(100, 103);
230: switch (x) {
231: case 100:
232: counter[0]++;
233: break;
234: case 101:
235: counter[1]++;
236: break;
237: case 102:
238: counter[2]++;
239: break;
240: case 103:
241: counter[3]++;
242: break;
243: default:
244: logger.debug("there is an error " + x);
245: logger.debug("we should never be here");
246: break;
247: }
248: }
249:
250: logger.debug("Number of 100: " + counter[0]);
251: logger.debug("Number of 101: " + counter[1]);
252: logger.debug("Number of 102: " + counter[2]);
253: logger.debug("Number of 103: " + counter[3]);
254:
255: // TESTING randomInt(int, int) Function
256: counter[0] = 0;
257: counter[1] = 0;
258: counter[2] = 0;
259: counter[3] = 0;
260: logger.debug("");
261:
262: r = UTILRandom.instanceOf(2000);
263: }
264: }
265: }
|