elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Rompecabezas de Bitcoin, Medio millón USD en premios


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  Java
| | | |-+  Valores aleatorios
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Valores aleatorios  (Leído 978 veces)
Beginner Web


Desconectado Desconectado

Mensajes: 627


youtu.be/0YhflLRE-DA


Ver Perfil
Valores aleatorios
« en: 16 Agosto 2019, 03:20 am »

Una pregunta, porque cuando cargo una matriz con valores aleatorios con un objeto creado con la clase Random este se llena y da valores repetidos como la siguiente matriz, lo que no se es porque al busca un numero en especifico el "7" por ejemplo a veces no me da la posicion exacta que es la primera aparicion del numero "7"  que es fila 1, columna 4, me puede dar esa posicion o sino otra que contenga al numero "7", y para agregar me parece que es un problema con los valores generados de forma aleatorio y repetidos de paso.
 :huh:

1 2 3 4 5
3 3 4 9 7
5 6 7 8 8
6 6 6 7 7



En línea

7w7
Serapis
Colaborador
***
Desconectado Desconectado

Mensajes: 3.267


Ver Perfil
Re: Valores aleatorios
« Respuesta #1 en: 17 Agosto 2019, 01:37 am »

Imagina el siguiente caso:
Tomamos una bolsa y pedimos a todos los alumnos de tu clase, que escriban su nombre, lo doblen y lo metan en la bolsa.
ahora pedimos que se saque un nombre y lo anotasmos en la pizarra, volvemos a guardar el papelito en la bolsa, y pedimos otro... y así tantos como quieras.

Entiendes que la posibilidad de que salgan nombres reptidos resulta inevitable?.

Vamos a hacer que sea evitable... todo lo que necesitamos sabes es cuantos números queremos tener (o alumnos de tu clase con nombre distintos), pongamos que aunque en tu clase haya 35 alumnos solo hay 20 nombres distintos, el resto se repiten.

Bien, como solo queremos que salgan una única vez, solo escribimos el nombre de esos 20 únicos en un papelito, l odoblamos y lo metemos en la bolsa... la agitamos (barajamos), y ahora cuando se saque uno de la bolsa, se queda fuera...(lo metemos en otra bolsa, por ejemplo)... el resultado es que saldrán nombres sin repetirse.

Si lo has entendido hasta aquí, ahora un poco de pseudocódigo:

Código:
array bytes Lista()

// los metemos en la bolsa (1 vez cada uno distinto)
// permitimos elegir desde 0 a 19, lo mismo que desde 35 a 54
//     (para 20 elementos de cantidad, del ejemplo).
Funcion GenerarListaSinRepeticion(array entero Lista(), entero Cantidad, entero Inicial = 0)
    entero k    

    alojar memoria para Lista(0 a Cantidad-1)
    bucle para k desde Inicial hasta Cantidad-1+Inicial
        lista(k-inicial) = k
    siguiente
Fin funcion

// ahora los barajamos: pero en vez de meterlos en otra bolsa (array)
//   lo depositamos al final y el que está allí, lo dejamos en el índice obtenido al azar,
//    estos es intercambian su posición...
Funcion Barajar(array entero Lista(),  entero Cantidad)
    entero k, index, tmp

    Bucle para k desde Cantidad-1 hasta 1 regresivamente
        index = random(entre k y 0)
  
        tmp = lista(index)
        lista(index) = lista(k)
        lista(k) = tmp
    Siguiente
Fin funcion

Ahora los ítems en el array están barajados, de forma aleatoria, aparecen una sola vez, y puedes tomarlos linealmente , cuando los consumas (llegues al último), debes barajarlos nuevamente. Y si necesitas cambiar la cantidad invocas de nuevo la función GenerarListaSinRepeticion.

Fíjate que se puede personalizar todo lo que se quiera... imagina que quiero que salga 5 veces 3 de ellos, 4 veces 10 de ellos, 2 veces 25 de ellos y 1 sola vez 500 elementos...
Lo primero es totalizar cuantos elementos  se necesitan:
Cantidad    ---  Repetidos:
   3 x   5 =   15
  10 x  3 =   30
  25 x  2 =   50
 500 x 1 = 500
-------------------
TOTAL   = 595

Luego debemos crear un array con 595 elementos, y luego condiconarlos a que se repitan las veces pedidas...
Como interesa que no haya que hacer cada vez una función distinta para cada caso, es mejor parametrizarlo para reutilizarlo una y otra vez con solo 2 funciones:
Código:
estructura Articulos
   entero Cantidad
   entero Repeticiones
fin estructura

Array entero Lista() = funcion GenerarArray(array de articulo Reparto() )
     entero Total, k, n

    // Calcular cuantos ítems totales hay.
    Bucle para k desde 0 hasta reparto.Length-1  // cantidad de ítems en el array.
        total += Reparto(K).Cantidad * Reparto(k).Repeticiones    
    Siguiente

    // dimensionar el array en memoria al tamaño total recién calculado
    alojar array Lista(0 hasta Total -1)

    // Introducir la cantidad de repetidos de cada 'clase'
    n = 0
    v = 0
    Bucle para k desde 0 hasta reparto.Length-1
        AddReparto(Lista, n,v, Reparto(k).Cantidad,  Reparto(k).Repetidos)
        // mejor que sean pasados por referencia y se actualizan allí con cada llamada.
        //n += (Reparto(k).Cantidad *  Reparto(k).Repetidos)
        //v + = Reparto(k).Cantidad
    Siguiente
Fin funcion

// Index y Valor son parámetros pasados por referencia
//      (para recibir de vuelta valores actualizados para el siguiente ciclo).
Funcion AddReparto(array entero Lista(), entero Index, entero Valor, entero Cantidad, entero Repes)
    entero j, k

    Bucle para j desde 1 hasta Cantidad
        Bucle para k desde 1 hasta Repes
            Lista(index) = Valor
            Index += 1
        Siguiente
        Valor += 1
    Siguiente
Fin funcion

Para probarlo, metamos en el array Reparto, los valores que dimos antes de ejemplo:
Cantidad    ---  Repetidos:
   3 x   5 =   15
  10 x  3 =   30
  25 x  2 =   50
 500 x 1 = 500
-------------------
TOTAL   = 595

Código de ejemplo para llamar a las funciones
Código:
   Array Articulos Reparto(0 hasta 3)
    Reparto(0).Cantidad = 3
    Reparto(0).Repetidos = 5

    Reparto(0).Cantidad = 10
    Reparto(0).Repetidos = 3

    Reparto(0).Cantidad = 25
    Reparto(0).Repetidos = 2

    Reparto(0).Cantidad = 500
    Reparto(0).Repetidos = 1

    Lista = GenerarArray(Reparto() )
    
    //ImprimirLista(Lista, Lista.Lenght)
    //Barajar(Lista, Lista.Lenght)
    //ImprimirLista(Lista, Lista.Lenght)
Si imprimes el array antes de barajar... ahí verás:

Indice - repeticiones del valor
(3 valores se repiten 5 veces cada uno)
0 - 0
1 - 0
2 - 0
3 - 0
4 - 0
5 - 1
6 - 1
7 - 1
8 - 1
9 - 1
10 - 2
11 - 2
12 - 2
13 - 2
14 - 2
-----------
(10 valores se repiten 3 veces cada uno)
15 - 3
16 - 3
17 - 3
18 - 4
19 - 4
20 - 4
...  (si no me equivoco, esto acaba en)
42 - 12
43 - 12
44 - 12
--------------
(25 valores se repiten 2 veces cada uno)
....
(xx .... .... ... ...)
.....
(500 valores sin repetirse (solo 1 vez aparece)
95 - 38
96 - 39
97 - 40
.....
593 - 536
594 - 537
--- FIN ---

Para terminar, te propongo un sencillo ejercicio: Imagina un mazo de cartas, que son típicamente 4 palos de baraja con valores del 1 al 10-12 (baraja española)
Date cuenta como cambiaría el código de crear la lista, pués ahora cada uno se repite 4 veces... crea dicha función y luego barájala, saca por pantalla todo el array y verifica que en efecto han salido 4 veces cada 'carta'.

Unos años atrás redacté en wikipedia el siguiente artículo bastante exhaustivo al respecto sobre el barajado aleatorio... te podría interesar hecharle un ojo, cuando tengas tiempo.
https://es.wikipedia.org/wiki/Algoritmo_de_Fisher-Yates


p.d. Olvidaba señalarte que Java contiene este barajado, localiza un método llamado 'Shuffle' en la clase random (OJO: La función de barajado, no la que hace los repartos en las cantidades que interese), pero aprenderás más entendiendo el tocho que te he redactado.


« Última modificación: 17 Agosto 2019, 15:47 pm por NEBIRE » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
NUMEROS ALEATORIOS EN VB
Programación Visual Basic
WCIETE 3 3,557 Último mensaje 30 Agosto 2005, 01:19 am
por Slasher-K
valores de array aleatorios en C#...URGENTE PORFAVOR
Dudas Generales
kanlet 7 4,882 Último mensaje 23 Junio 2011, 02:12 am
por kanlet
DEVOLVER VALORES ALEATORIOS DE UNA ARRAY EN C#?????'
.NET (C#, VB.NET, ASP)
kanlet 0 3,774 Último mensaje 19 Junio 2011, 20:22 pm
por kanlet
Hacer valores aleatorios sin Select Case
Programación Visual Basic
oskoa 7 2,659 Último mensaje 14 Noviembre 2011, 19:28 pm
por BlackZeroX
Sacar valores par y valores impar
Programación C/C++
nolasco281 7 3,462 Último mensaje 6 Mayo 2014, 09:29 am
por eferion
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines