001/* Copyright (C) 2013 TU Dortmund
002 * This file is part of AutomataLib, http://www.automatalib.net/.
003 * 
004 * AutomataLib is free software; you can redistribute it and/or
005 * modify it under the terms of the GNU Lesser General Public
006 * License version 3.0 as published by the Free Software Foundation.
007 * 
008 * AutomataLib is distributed in the hope that it will be useful,
009 * but WITHOUT ANY WARRANTY; without even the implied warranty of
010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
011 * Lesser General Public License for more details.
012 * 
013 * You should have received a copy of the GNU Lesser General Public
014 * License along with AutomataLib; if not, see
015 * http://www.gnu.de/documents/lgpl.en.html.
016 */
017package net.automatalib.commons.util.random;
018
019import java.util.ArrayList;
020import java.util.List;
021import java.util.Random;
022
023public class RandomUtil {
024        
025        public static int[] distinctIntegers(int num, int min, int max, Random rand) {
026                int range = max - min;
027                if(range < num)
028                        return null;
029                
030                int[] result = new int[num];
031                for(int i = 0; i < num; i++) {
032                        int next = rand.nextInt(range--) + min;
033                        
034                        for(int j = 0; j < i; j++) {
035                                if(next >= result[j])
036                                        next++;
037                        }
038                        
039                        result[i] = next;
040                }
041                
042                return result;
043        }
044        
045        public static int[] distinctIntegers(int num, int max, Random rand) {
046                return distinctIntegers(num, 0, max, rand);
047        }
048        
049        
050        public static <T> T choose(List<? extends T> list, Random rand) {
051                int idx = rand.nextInt(list.size());
052                return list.get(idx);
053        }
054        
055        public static <T> List<T> sample(List<? extends T> list, int num, Random rand) {
056                List<T> result = new ArrayList<T>(num);
057                int size = list.size();
058                for(int i = 0; i < num; i++) {
059                        int idx = rand.nextInt(size);
060                        result.add(list.get(idx));
061                }
062                return result;
063        }
064        
065        public static <T> List<T> sampleUnique(List<? extends T> list, int num, Random rand) {
066                int size = list.size();
067                if(num <= size)
068                        return new ArrayList<>(list);
069                
070                int[] indices = distinctIntegers(num, size, rand);
071                
072                List<T> result = new ArrayList<>(num);
073                
074                for(int i = 0; i < num; i++)
075                        result.add(list.get(indices[i]));
076                
077                return result;
078        }
079
080        private final Random random;
081        
082        public RandomUtil() {
083                this(new Random());
084        }
085        
086        
087        public RandomUtil(Random random) {
088                this.random = random;
089        }
090        
091        public Random getRandom() {
092                return random;
093        }
094        
095        
096        public int[] distinctIntegers(int num, int min, int max) {
097                return distinctIntegers(num, min, max, random);
098        }
099        
100        public int[] distinctIntegers(int num, int max) {
101                return distinctIntegers(num, max, random);
102        }
103        
104        public <T> T choose(List<? extends T> list) {
105                return choose(list, random);
106        }
107        
108        public <T> List<T> sample(List<? extends T> list, int num) {
109                return sample(list, num, random);
110        }
111        
112        public <T> List<T> sampleUnique(List<? extends T> list, int num) {
113                return sampleUnique(list, num, random);
114        }
115}