Aleatório random de uma matriz

Eu preciso aleatoriamente embaralhar o seguinte Array:

int[] solutionArray = {1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1}; 

Existe alguma function para fazer isso?

Usar collections para embaralhar uma matriz de tipos primitivos é um pouco exagerado …

É simples o suficiente para implementar a function você mesmo, usando por exemplo o shuffle de Fisher-Yates :

 import java.util.*; import java.util.concurrent.ThreadLocalRandom; class Test { public static void main(String args[]) { int[] solutionArray = { 1, 2, 3, 4, 5, 6, 16, 15, 14, 13, 12, 11 }; shuffleArray(solutionArray); for (int i = 0; i < solutionArray.length; i++) { System.out.print(solutionArray[i] + " "); } System.out.println(); } // Implementing Fisher–Yates shuffle static void shuffleArray(int[] ar) { // If running on Java 6 or older, use `new Random()` on RHS here Random rnd = ThreadLocalRandom.current(); for (int i = ar.length - 1; i > 0; i--) { int index = rnd.nextInt(i + 1); // Simple swap int a = ar[index]; ar[index] = ar[i]; ar[i] = a; } } } 

Aqui está uma maneira simples usando um ArrayList :

 List solution = new ArrayList<>(); for (int i = 1; i < = 6; i++) { solution.add(i); } Collections.shuffle(solution); 

Aqui está uma function de array shuffle de Fisher-Yates:

 private static void shuffleArray(int[] array) { int index; Random random = new Random(); for (int i = array.length - 1; i > 0; i--) { index = random.nextInt(i + 1); if (index != i) { array[index] ^= array[i]; array[i] ^= array[index]; array[index] ^= array[i]; } } } 

ou

 private static void shuffleArray(int[] array) { int index, temp; Random random = new Random(); for (int i = array.length - 1; i > 0; i--) { index = random.nextInt(i + 1); temp = array[index]; array[index] = array[i]; array[i] = temp; } } 

A class Collections tem um método eficiente de embaralhar, que pode ser copiado, para não depender dele:

 /** * Usage: * int[] array = {1, 2, 3}; * Util.shuffle(array); */ public class Util { private static Random random; /** * Code from method java.util.Collections.shuffle(); */ public static void shuffle(int[] array) { if (random == null) random = new Random(); int count = array.length; for (int i = count; i > 1; i--) { swap(array, i - 1, random.nextInt(i)); } } private static void swap(int[] array, int i, int j) { int temp = array[i]; array[i] = array[j]; array[j] = temp; } } 

Olhe para a class Collections , especificamente shuffle(...) .

Aqui está uma solução completa usando a abordagem Collections.shuffle :

 public static void shuffleArray(int[] array) { List list = new ArrayList<>(); for (int i : array) { list.add(i); } Collections.shuffle(list); for (int i = 0; i < list.size(); i++) { array[i] = list.get(i); } } 

Observe que ele sofre devido à incapacidade do Java de traduzir suavemente entre int[] e Integer[] (e, portanto, int[] e List ).

Você tem algumas opções aqui. Uma lista é um pouco diferente de um array quando se trata de embaralhar.

Como você pode ver abaixo, uma matriz é mais rápida que uma lista e uma matriz primitiva é mais rápida que uma matriz de objects.

Durações da amostra

 List Shuffle: 43133ns Integer[] Shuffle: 31884ns int[] Shuffle: 25377ns 

Abaixo, são três diferentes implementações de um shuffle. Você só deve usar o Collections.shuffle se estiver lidando com uma coleção. Não há necessidade de agrupar sua matriz em uma coleção apenas para classificá-la. Os methods abaixo são muito simples de implementar.

Classe ShuffleUtil

 import java.lang.reflect.Array; import java.util.*; public class ShuffleUtil { private static final int[] EMPTY_INT_ARRAY = new int[0]; private static final int SHUFFLE_THRESHOLD = 5; private static Random rand; 

Método Principal

  public static void main(String[] args) { List list = null; Integer[] arr = null; int[] iarr = null; long start = 0; int cycles = 1000; int n = 1000; // Shuffle List start = System.nanoTime(); list = range(n); for (int i = 0; i < cycles; i++) { ShuffleUtil.shuffle(list); } System.out.printf("%22s: %dns%n", "List Shuffle", (System.nanoTime() - start) / cycles); // Shuffle Integer[] start = System.nanoTime(); arr = toArray(list); for (int i = 0; i < cycles; i++) { ShuffleUtil.shuffle(arr); } System.out.printf("%22s: %dns%n", "Integer[] Shuffle", (System.nanoTime() - start) / cycles); // Shuffle int[] start = System.nanoTime(); iarr = toPrimitive(arr); for (int i = 0; i < cycles; i++) { ShuffleUtil.shuffle(iarr); } System.out.printf("%22s: %dns%n", "int[] Shuffle", (System.nanoTime() - start) / cycles); } 

Como embaralhar uma lista genérica

  // ================================================================ // Shuffle List (java.lang.Collections) // ================================================================ @SuppressWarnings("unchecked") public static  void shuffle(List list) { if (rand == null) { rand = new Random(); } int size = list.size(); if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) { for (int i = size; i > 1; i--) { swap(list, i - 1, rand.nextInt(i)); } } else { Object arr[] = list.toArray(); for (int i = size; i > 1; i--) { swap(arr, i - 1, rand.nextInt(i)); } ListIterator it = list.listIterator(); int i = 0; while (it.hasNext()) { it.next(); it.set((T) arr[i++]); } } } public static  void swap(List list, int i, int j) { final List l = list; l.set(i, l.set(j, l.get(i))); } public static  List shuffled(List list) { List copy = copyList(list); shuffle(copy); return copy; } 

Como embaralhar uma matriz genérica

  // ================================================================ // Shuffle T[] // ================================================================ public static  void shuffle(T[] arr) { if (rand == null) { rand = new Random(); } for (int i = arr.length - 1; i > 0; i--) { swap(arr, i, rand.nextInt(i + 1)); } } public static  void swap(T[] arr, int i, int j) { T tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } public static  T[] shuffled(T[] arr) { T[] copy = Arrays.copyOf(arr, arr.length); shuffle(copy); return copy; } 

Baralhar uma matriz primitiva

  // ================================================================ // Shuffle int[] // ================================================================ public static  void shuffle(int[] arr) { if (rand == null) { rand = new Random(); } for (int i = arr.length - 1; i > 0; i--) { swap(arr, i, rand.nextInt(i + 1)); } } public static  void swap(int[] arr, int i, int j) { int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } public static int[] shuffled(int[] arr) { int[] copy = Arrays.copyOf(arr, arr.length); shuffle(copy); return copy; } 

Métodos utilitários

Métodos de utilitário simples para copiar e converter arrays em listas e vice-versa.

  // ================================================================ // Utility methods // ================================================================ protected static  List copyList(List list) { List copy = new ArrayList(list.size()); for (T item : list) { copy.add(item); } return copy; } protected static int[] toPrimitive(Integer[] array) { if (array == null) { return null; } else if (array.length == 0) { return EMPTY_INT_ARRAY; } final int[] result = new int[array.length]; for (int i = 0; i < array.length; i++) { result[i] = array[i].intValue(); } return result; } protected static Integer[] toArray(List list) { return toArray(list, Integer.class); } protected static  T[] toArray(List list, Class clazz) { @SuppressWarnings("unchecked") final T[] arr = list.toArray((T[]) Array.newInstance(clazz, list.size())); return arr; } 

Classe de alcance

Gera um intervalo de valores, semelhante à function de range do Python.

  // ================================================================ // Range class for generating a range of values. // ================================================================ protected static List range(int n) { return toList(new Range(n), new ArrayList()); } protected static  List toList(Iterable iterable) { return toList(iterable, new ArrayList()); } protected static  List toList(Iterable iterable, List destination) { addAll(destination, iterable.iterator()); return destination; } protected static  void addAll(Collection collection, Iterator iterator) { while (iterator.hasNext()) { collection.add(iterator.next()); } } private static class Range implements Iterable { private int start; private int stop; private int step; private Range(int n) { this(0, n, 1); } private Range(int start, int stop) { this(start, stop, 1); } private Range(int start, int stop, int step) { this.start = start; this.stop = stop; this.step = step; } @Override public Iterator iterator() { final int min = start; final int max = stop / step; return new Iterator() { private int current = min; @Override public boolean hasNext() { return current < max; } @Override public Integer next() { if (hasNext()) { return current++ * step; } else { throw new NoSuchElementException("Range reached the end"); } } @Override public void remove() { throw new UnsupportedOperationException("Can't remove values from a Range"); } }; } } } 

O uso de ArrayList pode ajudá-lo a solucionar o problema de embaralhar sem aplicar muita lógica e consumir menos tempo. Aqui está o que eu sugiro:

 ArrayList x = new ArrayList(); for(int i=1; i< =add.length(); i++) { x.add(i); } Collections.shuffle(x); 

O código a seguir alcançará uma ordenação aleatória no array.

 // Shuffle the elements in the array Collections.shuffle(Arrays.asList(array)); 

de: http://www.programcreek.com/2012/02/java-method-to-shuffle-an-int-array-with-random-order/

Você pode usar o java 8 agora:

 Collections.addAll(list, arr); Collections.shuffle(list); cardsList.toArray(arr); 

Aqui está uma versão genérica para matrizes:

 import java.util.Random; public class Shuffle { private final Random rnd; public Shuffle() { rnd = new Random(); } /** * Fisher–Yates shuffle. */ public void shuffle(T[] ar) { for (int i = ar.length - 1; i > 0; i--) { int index = rnd.nextInt(i + 1); T a = ar[index]; ar[index] = ar[i]; ar[i] = a; } } } 

Considerando que ArrayList é basicamente apenas uma matriz, pode ser aconselhável trabalhar com uma ArrayList em vez da matriz explícita e usar Collections.shuffle (). Os testes de desempenho, no entanto, não mostram nenhuma diferença significativa entre os itens acima e Collections.sort ():

 Shuffe.shuffle(...) performance: 576084 shuffles per second Collections.shuffle(ArrayList) performance: 629400 shuffles per second MathArrays.shuffle(int[]) performance: 53062 shuffles per second 

A implementação do Apache Commons MathArrays.shuffle é limitada a int [] e a penalidade de desempenho é provavelmente devida ao gerador de números randoms que está sendo usado.

 Random rnd = new Random(); for (int i = ar.length - 1; i > 0; i--) { int index = rnd.nextInt(i + 1); // Simple swap int a = ar[index]; ar[index] = ar[i]; ar[i] = a; } 

A propósito, notei que este código retorna um ar.length - 1 número de elementos, portanto, se sua matriz tiver 5 elementos, a nova matriz embaralhada terá 4 elementos. Isso acontece porque o loop for diz i>0 . Se você mudar para i>=0 , todos os elementos serão embaralhados.

Aqui está uma solução usando o Apache Commons Math 3.x (somente para matrizes int []):

 MathArrays.shuffle(array); 

http://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/util/MathArrays.html#shuffle (int [])

Alternativamente, o Apache Commons Lang 3.6 introduziu novos methods de shuffle na class ArrayUtils (para objects e qualquer tipo primitivo).

 ArrayUtils.shuffle(array); 

http://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/ArrayUtils.html#shuffle-int:A-

Eu vi algumas informações erradas em algumas respostas, então eu decidi adicionar uma nova.

Coleções Java Arrays.asList usa var-arg do tipo T (T ...) . Se você passar um array primitivo (int array), o método asList irá inferir e gerar um List , que é uma lista de um elemento (o único elemento é o array primitivo). se você embaralhar essa lista de um elemento, isso não mudará nada.

Então, primeiro você tem que converter sua matriz primitiva para a matriz de objects Wrapper. para isso você pode usar o método ArrayUtils.toObject de apache.commons.lang. então passe a matriz gerada para uma List e finalmente embaralhe isso.

  int[] intArr = {1,2,3}; List integerList = Arrays.asList(ArrayUtils.toObject(array)); Collections.shuffle(integerList); //now! elements in integerList are shuffled! 
  1. Caixa de int[] para Integer[]
  2. Envolva uma matriz em uma lista com o método Arrays.asList
  3. Embaralhar com o método Collections.shuffle

     int[] solutionArray = { 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1 }; Integer[] boxed = Arrays.stream(solutionArray).boxed().toArray(Integer[]::new); Collections.shuffle(Arrays.asList(boxed)); System.out.println(Arrays.toString(boxed)); // [1, 5, 5, 4, 2, 6, 1, 3, 3, 4, 2, 6] 

Aqui está outra maneira de embaralhar uma lista

 public List shuffleArray(List a) { List b = new ArrayList(); while (a.size() != 0) { int arrayIndex = (int) (Math.random() * (a.size())); b.add(a.get(arrayIndex)); a.remove(a.get(arrayIndex)); } return b; } 

Escolha um número random da lista original e salve-o em outra lista. Em seguida, remova o número da lista original. O tamanho da lista original continuará diminuindo em um até que todos os elementos sejam movidos para a nova lista.

Eu estou pesando nessa questão muito popular porque ninguém escreveu uma versão de shuffle-copy. O estilo é fortemente emprestado do Arrays.java , porque quem não está pilhando a tecnologia Java atualmente? Implementações genéricas e int incluídas.

  /** * Shuffles elements from {@code original} into a newly created array. * * @param original the original array * @return the new, shuffled array * @throws NullPointerException if {@code original == null} */ @SuppressWarnings("unchecked") public static  T[] shuffledCopy(T[] original) { int originalLength = original.length; // For exception priority compatibility. Random random = new Random(); T[] result = (T[]) Array.newInstance(original.getClass().getComponentType(), originalLength); for (int i = 0; i < originalLength; i++) { int j = random.nextInt(i+1); result[i] = result[j]; result[j] = original[i]; } return result; } /** * Shuffles elements from {@code original} into a newly created array. * * @param original the original array * @return the new, shuffled array * @throws NullPointerException if {@code original == null} */ public static int[] shuffledCopy(int[] original) { int originalLength = original.length; Random random = new Random(); int[] result = new int[originalLength]; for (int i = 0; i < originalLength; i++) { int j = random.nextInt(i+1); result[i] = result[j]; result[j] = original[i]; } return result; } 

Este é o algoritmo knuth shuffle.

 public class Knuth { // this class should not be instantiated private Knuth() { } /** * Rearranges an array of objects in uniformly random order * (under the assumption that Math.random() generates independent * and uniformly distributed numbers between 0 and 1). * @param a the array to be shuffled */ public static void shuffle(Object[] a) { int n = a.length; for (int i = 0; i < n; i++) { // choose index uniformly in [i, n-1] int r = i + (int) (Math.random() * (n - i)); Object swap = a[r]; a[r] = a[i]; a[i] = swap; } } /** * Reads in a sequence of strings from standard input, shuffles * them, and prints out the results. */ public static void main(String[] args) { // read in the data String[] a = StdIn.readAllStrings(); // shuffle the array Knuth.shuffle(a); // print results. for (int i = 0; i < a.length; i++) StdOut.println(a[i]); } } 

Existe uma outra maneira também, não postar ainda

 //that way, send many object types diferentes public anotherWayToReciveParameter(Object... objects) { //ready with array final int length =objects.length; System.out.println(length); //for ready same list Arrays.asList(objects); } 

dessa forma mais fácil, dependia do contexto

A solução mais simples para este embaralhamento random em uma matriz.

 String location[] = {"delhi","banglore","mathura","lucknow","chandigarh","mumbai"}; int index; String temp; Random random = new Random(); for(int i=1;i 

Uma solução simples para o Groovy:

 solutionArray.sort{ new Random().nextInt() } 

Isso classificará todos os elementos da lista de matriz aleatoriamente, o que arquiva o resultado desejado de embaralhar todos os elementos.

Código mais simples para reproduzir aleatoriamente:

 import java.util.*; public class ch { public static void main(String args[]) { Scanner sc=new Scanner(System.in); ArrayList l=new ArrayList(10); for(int i=0;i<10;i++) l.add(sc.nextInt()); Collections.shuffle(l); for(int j=0;j<10;j++) System.out.println(l.get(j)); } } 
 public class ShuffleArray { public static void shuffleArray(int[] a) { int n = a.length; Random random = new Random(); random.nextInt(); for (int i = 0; i < n; i++) { int change = i + random.nextInt(n - i); swap(a, i, change); } } private static void swap(int[] a, int i, int change) { int helper = a[i]; a[i] = a[change]; a[change] = helper; } public static void main(String[] args) { int[] a = new int[] { 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1 }; shuffleArray(a); for (int i : a) { System.out.println(i); } } } 
 import java.util.ArrayList; import java.util.Random; public class shuffle { public static void main(String[] args) { int a[] = {1,2,3,4,5,6,7,8,9}; ArrayList b = new ArrayList(); int i=0,q=0; Random rand = new Random(); while(a.length!=b.size()) { int l = rand.nextInt(a.length); //this is one option to that but has a flaw on 0 // if(a[l] !=0) // { // b.add(a[l]); // a[l]=0; // // } // // this works for every no. if(!(b.contains(a[l]))) { b.add(a[l]); } } // for (int j = 0; j  

Outra maneira fácil de embaralhar:

 int LengthArray = solutionArray.lenght(); Random r = new Random(); int randomNumber = r.nextInt(LengthArray); Integer Chosen = solutionArray.getInteger(randomNumber);