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}