Cuando queremos números aleatorios en un intervalo como [-20-40] o parecido necesitamos usar una metodología, donde analizaremos lo siguiente,

Análisis de las características de los números
Dado un intervalo revisamos si
1. Puede tener signo +,-
2. Cuantos dígitos puede tener 1,2,3,...
3. Si tiene dígitos decimales y cuantos 1,2,3,...
4. Que números usaremos para ver y aplicar estas características

Enfoque de la posición

Dado un número de $n$ dígitos de la forma.

nnnnnnnnn...

Podemos aplicar lo siguiente

Signo $n_{1}$

nnnnnn...

Si el primer digito es par entonces signo = + si no signo = -

Cifras $[n_2:n_c]$

Depende del número de cifras que queramos

Cantidad de cifras probables Dígitos en posición a tomar Forma Regla
2 $n_2$ nnnnnn... Si el primer digito es par entonces digitos = 1 si no digitos = 2
3 $n_2-n_3$ nnnnn... El primer digito es par
Si el segundo digito es par entonces digitos = 1 si no digitos = 2

El primer digito es impar
Si el segundo digito es par entonces digitos = 3 si no retira la opción
4 $n_2-n_3$ nnnnn... El primer digito es par
Si el segundo digito es par entonces digitos = 1 si no digitos = 2

El primer digito es impar
Si el segundo digito es par entonces digitos = 3 si no digitos = 4
5 $n_2-n_4$ nnnnn... Si el primer digito es par
Si el segundo digito es par
Si el tercer digito es par digitos=1
Si el primer digito es par
Si el segundo digito es par
Si el tercer digito es impar digitos=2
Si el primer digito es par
Si el segundo digito es impar
Si el tercer digito es par digitos=3
Si el primer digito es par
Si el segundo digito es impar
Si el tercer digito es impar digitos=4
Si el primer digito es impar
Si el segundo digito es par
Si el tercer digito es par digitos=5
...
... ... ... ...

Decimales $[n_{c}:n_{d}]$

A partir de $n_{c}$ vas a seleccionar los números consecutivos de a cuerdo a las cifras que quieras.

[! note]
La forma se toma como si fuera solo de un decimal.

Cantidad de decimales Dígitos en posición Forma Extracción
1 $n_{c+1}$ nnnnnn... $(digito)(0.10)$
2 $n_{c+1}-n_{c+2}$ nnnnnn... $(digito)(0.100)$
3 $n_{c+1}-n_{c+3}$ nnnnnn... $(digito)(0.1000)$
... ... ... ...

Número a usar

Esto dependerá del total de cifras deseadas.

Cifras deseadas Dígitos en posición Forma
1 $n_{d+1}$ nnnn
2 $n_{d+1}$ - $n_{d+2}$ nnnnn
3 $n_{d+1}$ - $n_{d+3}$ nnnnnn
... ... ...

Código

# Función para generar números aleatorios en un intervalo con decimales
def filt_random(cantidad, min_val, max_val, decimales):
    # Generamos números aleatorios con la función original 'random'
    random_values = random(339917332563, 3650, 9)  # Se generan más números de los necesarios para filtrar

    filtered_values = []

    for i in range(len(random_values)):
        # Convertir el número generado a un valor dentro del intervalo [min_val, max_val]
        valor = random_values[i] % (max_val - min_val + 1) + min_val

        # Ajustar el número de decimales si es necesario
        if decimales > 0:
            # Añadimos decimales al número
            decimal_factor = 10 ** decimales
            valor = round(valor + random_values[i] % decimal_factor / decimal_factor, decimales)

        # Añadimos el valor filtrado a la lista
        filtered_values.append(valor)

        # Paramos cuando ya tengamos la cantidad deseada
        if len(filtered_values)  cantidad:
            break

    return filtered_values

# Ejemplo de uso
valores_filtrados = filt_random(365, -20, 40, 0)
print(valores_filtrados)

En ocasiones, es necesario generar una serie de números aleatorios que no solo se encuentren dentro de un intervalo específico, sino que también posean un número determinado de decimales. Para lograr esto, se puede utilizar una función que filtre y ajuste los números generados por un método de generación de números aleatorios, como el Método de Cuadrados Medios.

Descripción de la Función filt_random

La función filt_random tiene como objetivo generar una lista de números aleatorios que cumplan con las siguientes características:
- Cantidad: Número de valores a generar.
- Intervalo: Rango mínimo y máximo en el que deben encontrarse los números.
- Decimales: Cantidad de decimales que deben tener los números generados.

Definición de la Función

def filt_random(cantidad, min_val, max_val, decimales):
    # Generamos números aleatorios con la función original 'random'
    random_values = random(339917332563, 3650, 9)  # Se generan más números de los necesarios para filtrar

    filtered_values = []

    for i in range(len(random_values)):
        # Convertir el número generado a un valor dentro del intervalo [min_val, max_val]
        valor = random_values[i] % (max_val - min_val + 1) + min_val

        # Ajustar el número de decimales si es necesario
        if decimales > 0:
            # Añadimos decimales al número
            decimal_factor = 10 ** decimales
            valor = round(valor + random_values[i] % decimal_factor / decimal_factor, decimales)

        # Añadimos el valor filtrado a la lista
        filtered_values.append(valor)

        # Paramos cuando ya tengamos la cantidad deseada
        if len(filtered_values) == cantidad:
            break

    return filtered_values

Parámetros de la Función

  • cantidad (int): Número total de valores aleatorios que se desean generar.
  • min_val (int/float): Valor mínimo del intervalo.
  • max_val (int/float): Valor máximo del intervalo.
  • decimales (int): Número de decimales que deben tener los valores generados.

Funcionamiento Detallado

  1. Generación Inicial de Números Aleatorios:

    • Se llama a la función random con una semilla específica (339917332563), un número de iteraciones elevado (3650) y un máximo de dígitos (9).
    • Esto genera una lista random_values con una cantidad de números aleatorios mayores a los necesarios, permitiendo filtrar posteriormente los valores que cumplan con las condiciones deseadas.
  2. Inicialización de la Lista de Valores Filtrados:

    • Se crea una lista vacía filtered_values que almacenará los números aleatorios que cumplen con los criterios especificados.
  3. Iteración y Filtrado:

    • Se recorre cada número en random_values.
    • Conversión al Intervalo Deseado:
      • Se aplica la operación módulo % para restringir el número al tamaño del intervalo (max_val - min_val + 1).
      • Se suma min_val para desplazar el rango al intervalo deseado [min_val, max_val]. $$ valor = random\_values[i] \% (max\_val - min\_val + 1) + min\_val $$
  • Ajuste de Decimales:

    • Si se requieren decimales (decimales > 0), se calcula un factor de escala decimal_factor = 10 ** decimales.
    • Se añade una fracción al valor utilizando el residuo de la división módulo decimal_factor, asegurando que el número tenga la cantidad de decimales especificada.
    • Se redondea el valor al número de decimales deseados. $$ valor = round(valor + (random\_values[i] \% decimal\_factor) / decimal\_factor, decimales) $$
  • Almacenamiento del Valor Filtrado:

    • El valor ajustado se añade a la lista filtered_values.
  • Control de la Cantidad Deseada:

    • Una vez que se han generado la cantidad deseada de números (cantidad), el bucle se interrumpe para evitar generar números innecesarios.
  1. Retorno de la Lista Filtrada:
    • La función retorna la lista filtered_values que contiene los números aleatorios ajustados según los parámetros especificados.

Ejemplo de Uso

# Ejemplo de uso de la función filt_random
valores_filtrados = filt_random(365, -20, 40, 0)
print(valores_filtrados)

Resultado Esperado:
- Una lista de 365 números enteros aleatorios que se encuentran en el intervalo $[-20, 40]$.

Consideraciones Importantes

  • Generación de Más Números de los Necesarios:

    • Se generan más números aleatorios de los que se necesitan inicialmente para asegurar que, tras el filtrado y ajuste, se obtenga la cantidad deseada de números que cumplen con las condiciones.
  • Uniformidad de la Distribución:

    • El uso de la operación módulo puede introducir ciertas irregularidades en la distribución de los números generados. Para una distribución más uniforme, se recomienda utilizar métodos de escalado y desplazamiento.
  • Número de Decimales:

    • El ajuste de decimales se realiza sumando una fracción basada en los dígitos restantes del número aleatorio. Esto garantiza que el número final tenga la precisión decimal deseada.

Implementación y Resultados

A continuación, se muestra un ejemplo de cómo utilizar la función filt_random para generar números aleatorios y sus resultados.

Código Completo

# Librerias
import matplotlib.pyplot as plt
import pandas as pd

# Función para generar números aleatorios
def random(seed, iteration, max_digits):
    valores = []

    print(f"| {'n'.center(4)} | {'R(n)'.center(8)} | {'R(n)^2'.center(12)} | {'M.R(n)^2'.center(10)} | {'valores'.center(6)} | {'val2'.center(6)} |")
    print("-" * 62)  # Línea separadora

    for i in range (iteration):
        rn = seed

        # Elevar al cuadrado
        seed = seed ** 2
        rn2 = seed

        #Extraer digitos centrales
        lon = len(str(seed))
        dif = lon - max_digits

        if(lon <= max_digits):
            continue
        if(dif % 2 == 0):
            dif = dif // 2

            mr = int(str(seed)[dif:-dif])
            aux1 = int(str(seed)[dif+1:-dif])
            seed = int(str(seed)[dif:-dif-1])
        else:
            dif = (dif + 1) // 2

            mr = int(str(seed)[dif:-dif])
            aux1 = 0
            seed = int(str(seed)[dif:-dif])

        # Almacenar el número generado
        valores.append(seed)

        # Imprimir en forma de tabla
        print(f"| {str(i).center(4)} | {str(rn).center(8)} | {str(rn2).center(12)} | {str(mr).center(10)} | {str(seed).center(6)} | {str(aux1).center(6)} |")

    return valores


# Función para generar números aleatorios en un intervalo con decimales
def filt_random(cantidad, min_val, max_val, decimales):
    # Generamos números aleatorios con la función original 'random'
    random_values = random(339917332563, 3650, 9)  # Se generan más números de los necesarios para filtrar

    filtered_values = []

    for i in range(len(random_values)):
        # Convertir el número generado a un valor dentro del intervalo [min_val, max_val]
        valor = random_values[i] % (max_val - min_val + 1) + min_val

        # Ajustar el número de decimales si es necesario
        if decimales > 0:
            # Añadimos decimales al número
            decimal_factor = 10 ** decimales
            valor = round(valor + random_values[i] % decimal_factor / decimal_factor, decimales)

        # Añadimos el valor filtrado a la lista
        filtered_values.append(valor)

        # Paramos cuando ya tengamos la cantidad deseada
        if len(filtered_values) == cantidad:
            break

    return filtered_values

# Ejemplo de uso
valores_filtrados = filt_random(365, -20, 40, 0)
print(valores_filtrados)


# Opcional: graficar los resultados valores 
plt.hist(valores_filtrados, bins=20, edgecolor='black')

plt.title('Histograma de Números Generados (valores)')
plt.xlabel('Número')
plt.ylabel('Frecuencia')
plt.show()

# Crear un diagrama de dispersión valores
plt.scatter(range(len(valores_filtrados)), valores_filtrados, color='blue', alpha=0.5)  # Eje X: iteraciones, Eje Y: valores
plt.title('Diagrama de Dispersión de Números Generados (valores)')
plt.xlabel('Iteración')
plt.ylabel('Número Generado')
plt.grid(True)
plt.show()

Explicación de los Resultados

  1. Generación de Números Aleatorios:

    • Se generan 3650 números aleatorios utilizando el Método de Cuadrados Medios con una semilla inicial de 339917332563 y un máximo de 9 dígitos.
  2. Filtrado y Ajuste:

    • De los 3650 números generados, se filtran y ajustan para obtener 365 números que se encuentren en el intervalo ([-20, 40]).
    • Como se establecen decimales = 0, los números generados serán enteros.
  3. Visualización de los Resultados:

    • Histograma: Muestra la distribución de los números generados, permitiendo visualizar si están uniformemente distribuidos dentro del intervalo.
    • Diagrama de Dispersión: Representa la secuencia de números generados, lo que ayuda a identificar patrones o repeticiones en la serie.

Pasted image 20241009074706.png

Pasted image 20241009074725.png

Consideraciones y Mejoras

  • Uniformidad de la Distribución:

    • El método actual utiliza la operación módulo para ajustar los números al intervalo, lo cual puede introducir una ligera irregularidad en la distribución, especialmente si el tamaño del intervalo no es un divisor exacto del rango de números generados.
    • Para mejorar la uniformidad, se recomienda utilizar el método de Escalado y Desplazamiento descrito en la sección 2.3.
  • Optimización de la Generación:

    • La función random está configurada para generar una cantidad fija de números (3650). Para mayor flexibilidad, se podría ajustar la función filt_random para calcular dinámicamente cuántos números se necesitan generar en función de la cantidad deseada y la tasa de éxito del filtrado.
  • Manejo de Decimales:

    • Actualmente, el ajuste de decimales añade una fracción al número entero. Este enfoque puede no ser ideal si se requiere una distribución específica de decimales. Alternativamente, se podría normalizar el número y escalarlo para obtener los decimales deseados.