Posição 2D randomica

6 respostas
vitu

Preciso obter de tempo em tempos pontos 2D (x, y) randômicos.
Sendo que estes pontos não podem se repetir.
O ponto x varia de 1 a 20, e o ponto y de 1 a 10 (isso não é fixo, e pode vir a mudar).
Eu guardo apenas a informação dos pontos preenchidos.

Pensei em duas estratêgias.

Estratêgia 1: Um while com random de x e y, até pegar um ponto que ainda não tenha sido utilizado.

Problema: O while pode tanto terminar imediatamente, quanto demorar horrores para encontrar um ponto.

Estratêgia 2: Guardar todos os pontos que ainda não estejam sendo utilizados em uma lista, pegar um ponto randômico dentro da lista depois remover ele da mesma.

Problema: Criar um número muito grande de instâncias que podem nunca ser utilizadas.

Pensei também em assumir a estratêgia 1 até certo número de pontos preenchidos e assumir a estratêgia 2 apartir de então.

6 Respostas

J

vc pode armazenar os pontos possíveis em uma lista.
e pode usar o método shuffle da classe Collections para randomizá-la
vc randomiza, retira um, radomiza novamente, retira um, e assim por diante.

List<Point> list = new ArrayList<Point>();
Collections.shuffle(list);

[]'s

E

Uma vez eu inventei de fazer um screen saver que ficava preenchendo a tela com quadradinhos em posições aleatórias na tela. Para que as posições não se repitam, há duas maneiras de fazer isso:

a) Anotar as posições que já foram usadas (você pode usar uma matriz de booleanos, por exemplo), ou

b) Usar um gerador de números aleatórios que percorra exatamente uma vez cada um dos valores.

Por exemplo, digamos que a tela tenha 1366 x 768 pontos (resolução comum em monitores widescreen). Isso quer dizer que você precisa usar um gerador que gere 1.049.088 posições. O menor primo maior que esse número é 1.049.089.

Você pode procurar os coeficientes corretos (já lhe passei um deles, que é o menor primo maior que o número desejado) para usar no método de Lehmer. Por favor, veja esta página:

http://www.brpreiss.com/books/opus4/html/page472.html

E faça as contas adequadas.

M

Uma possível implementação da estratégia 2:

LinkedList<Point> points = new LinkedList<Point>();
for (int i = 0; i < maxX; i++) {
    for (int j = 0; j < maxY; j++) {
        points.add(new Point(i, j));
    }
}
Collections.shuffle(points);

Quando precisar resgatar:

Point p = points.poll(); // resgata e remove o primeiro ponto
vitu

jhonatandarosa essa é a estratêgia 2.

entanglement desculpe-me minha ignorância, mas não entendi direito a implementação desse algoritiomo.

(X + C) % M

Vou gerar uma sequência numerica entre 0 e M.
C e M devem ser primos.
C deve ser um primo randomico entre 1 e M.
M deve ser o menor primo maior que o maior número da sequencia desejada.
X deve ser um número aleatório entre 0 e M.

marcobiscaro2112 tinha feito algo parecido aqui, mas sem o shufle. Em uma coleção muito grande acho que ficaria muito custoso:

for (int x = 0; x < this.width; x++)
	for (int y = 0; y < this.height; y++)
		this.emptyPositions.add(new Position(x, y));

Random random = new Random();
	return this.emptyPositions.remove(random.nextInt(this.emptyPositions.size()));
vitu

entanglement

cheguei a seguinte simulação

Random rand = new Random();
		int m = 23;
		int c = rand.nextInt(m - 2) + 1;
		int next = rand.nextInt(m);
		for (int x = 0; x <= m; x++) {
			System.out.print(next + ",");
			next = (next + c) % m;
		}

O problema e que “m” e conhecido, e conhecendo os 2 ultimos números determino “c” .
Então posso determinar todos os proximos pontos usando essa aboradagem.

M
vitu:
marcobiscaro2112 tinha feito algo parecido aqui, mas sem o shufle. Em uma coleção muito grande acho que ficaria muito custoso:
for (int x = 0; x < this.width; x++)
	for (int y = 0; y < this.height; y++)
		this.emptyPositions.add(new Position(x, y));

Random random = new Random();
	return this.emptyPositions.remove(random.nextInt(this.emptyPositions.size()));
Quanto é "muito grande"? Pode ser que não fique tão custoso assim (ou ao menos seja menos custoso que implementar um algoritmo próprio que talvez não seja tão otimizado quanto poderia ser).
Criado 17 de fevereiro de 2010
Ultima resposta 18 de fev. de 2010
Respostas 6
Participantes 4