Este capítulo explica primeiro várias maneiras de gerar números aleatórios de Java e depois os demonstra através de exemplos.
Visão geral:
Você vai dizer aqui, qual é a dificuldade de gerar números aleatórios? Não é apenas usar o Java encapsulado aleatório? Obviamente, tudo bem em geral, e os algoritmos a serem explicados neste artigo também são baseados nessa função de biblioteca aleatória.
Este artigo se concentra principalmente no comportamento da amostragem, e a própria amostra tem uma regra implícita que não deve ter dados duplicados. OK, com estas instruções. Você pode primeiro tentar usar algumas de suas próprias idéias para gerar números aleatórios sem geração repetida.
Tentativas de algoritmo:
Alguns bons algoritmos aparecem, geralmente acompanhados por alguns algoritmos não tão bons. No entanto, para algoritmos que não são muito eficazes, eles geralmente têm um recurso comum, que é fácil de entender e implementar. A seguir, é apresentada uma breve explicação através de uma abordagem passo a passo.
Primeira tentativa: algoritmo aleatório ingênuo
Este algoritmo é fácil de entender, é aleatório! Cada vez que um número aleatório é gerado e adicionado ao conjunto.
private void simples e start, int end, int count) {System.out.println ("Algoritmo aleatório natural:"); StringBuffer buffer = new StringBuffer (); for (int i = 0; i <count; i ++) {int aleatory = numberils.randominteger (start, end); buffer.append (i == 0? ("[" + aleatório): ("," + aleatório)); } buffer.append ("]"); System.out.println (buffer); } A segunda tentativa: verifique o algoritmo aleatório existencial
Sabemos que há um problema com o método acima, ou seja, pode haver dados duplicados. Então, pensamos em verificar se o número já existe ao gerar um número aleatório e, se existir, será regenerado.
CheckRandom de vazio privado (int start, int end, int conting) {System.out.println ("Verifique o algoritmo aleatório existencial:"); StringBuffer buffer = new StringBuffer (); List <Integer> save = new ArrayList <> (); for (int i = 0; i <count; i ++) {int aleatory = numberils.randominteger (start, end); if (sai (salvar, aleatório)) {i--; continuar; } save.add (aleatório); buffer.append (i == 0? ("[" + aleatório): ("," + aleatório)); } buffer.append ("]"); System.out.println (buffer); } A terceira tentativa: algoritmo aleatório de remoção de elementos
O algoritmo acima resolveu o problema da duplicação de dados. No entanto, um problema muito ruim é que pode levar muito tempo para gerar números aleatórios de amostra (isso depende da face ...).
No entanto, aqui temos novas idéias. Isso é para usar aleatoriamente um número em um conjunto e removê -lo quando for selecionado. Então, você não atingirá aleatoriamente esse número novamente quando for aleatório? Isso resolve o problema da repetição de números aleatórios muito bem. O código é o seguinte:
Removenda de vazio privado (int start, int end, int conting) {System.out.println ("Algoritmo aleatório de remoção do elemento:"); StringBuffer buffer = new StringBuffer (); Lista <Teger> números = initList (start, end); for (int i = 0; i <contagem; i ++) {int aleatory = numberils.randominteger (contagem - i); buffer.append (i == 0? ("[" + números.get (aleatório)): ("," + números.get (aleatório))); números.remove (aleatório); } buffer.append ("]"); System.out.println (buffer); } Quarta tentativa: algoritmo aleatório de transferência de estado
Em muitos dos meus blogs anteriores, alguns são processos de transferência de estado em algoritmos. A transferência do estado também é um dos meus algoritmos favoritos. A Figura 1 abaixo marca a faixa de valor de números aleatórios, e o número laranja na sequência é a sequência aleatória no resultado. Existem algumas setas pontilhadas na sequência inferior, representando a transição do estado.
Figura 1 Amostragem algoritmo de geração de números aleatórios com base na transição do estado
Código de implementação:
Status de void privado (int start, int end, int conting) {System.out.println ("Algoritmo aleatório de transferência de status:"); StringBuffer buffer = new StringBuffer (); int [] status = new int [end + 1]; for (int i = 0; i <count; i ++) {int aleatory = numberils.randominteger (start, end); System.err.println (aleatório); if (status [aleatório] == 0) {buffer.append (i == 0? ("[" + aleatório): ("," + aleatório)); status [aleatório] = aleatória == fim? Iniciar: (aleatório + 1); // é impossível ter um número antes de iniciar} else {// status transferência int index = aleatória; do {index = status [index]; } while (status [index]! = 0); buffer.append (i == 0? ("[" + index): ("," + index)); status [índice] = index == END? Iniciar: (índice + 1); // é impossível ter um número antes do início}} buffer.append ("]"); System.out.println (buffer); } A quinta tentativa: algoritmo aleatório recursivo do Floyd
O algoritmo Floyd é, em última análise, um processo de transferência de estado. O algoritmo exigirá uma lista ou matriz para armazenar o número aleatório determinado. Como o nome sugere, usarei soluções recursivas aqui. No processo de recursão, transferimos o estado do número aleatório do I-és para o número aleatório da I-1. O código é o seguinte:
Lista privada <Teger> simplesfloyd (lista <Teger> List, int conting, int start, int end) {if (count == 0) {list Return; } list = simplesfloyd (lista, contagem - 1, start, end - 1); int aleatoriamente = numberUtils.RandomInteger (start, fim); if (list.contains (aleatório)) {list.add (end); } else {list.add (aleatório); } Lista de retorno; } Sexta tentativa: itera o algoritmo aleatório do Floyd
A idéia é semelhante ao algoritmo aleatório recursivo do Floyd acima, mas aqui adicionamos uma variável para otimizar. Não há mais necessidade de recorrer. O código é o seguinte:
Lista privada <Integer> iteationfloyd (int start, int end, int conting) {system.out.println ("algoritmo aleatório iterativo do Floyd:"); List <Integer> list = new ArrayList <> (); for (int i = end - contagem+1; i <end; i ++) {int aleatory = numberils.randominteger (start, i); if (list.contains (aleatório)) {list.add (i); } else {list.add (aleatório); }} Lista de retorno; } Resultados do teste:
Figura 2 Resultados do teste de algoritmo de geração de números aleatórios
Nos resultados dos testes acima, podemos ver claramente que o algoritmo aleatório ingênuo não apenas possui dados duplicados, mas também é o mais demorado. Portanto, evite usar esse algoritmo ao gerar números aleatórios amostrados. Entre os últimos algoritmos, o algoritmo aleatório de transferência de estado é o melhor, e o algoritmo aleatório iterativo do Floyd é o segundo. Isso pode ser feito de acordo com as preferências pessoais.