Quiero generar una secuencia de números para generar planetas procesales en un sector de galaxias. Cada planeta debe colocarse al azar, sin embargo, es muy poco probable que dos planetas estén directamente uno al lado del otro. ¿Cómo puedo lograr eso?
Sé que puede modificar las posibilidades aplicando una función de distribución, pero ¿cómo puedo controlarlas para hacer que los valores específicos sean más / menos probables?
mathematics
procedural-generation
random
API-Bestia
fuente
fuente
Respuestas:
Si conoce la distribución que desea, puede usar el muestreo de rechazo .
La forma más simple: en el gráfico anterior, elija puntos al azar hasta que encuentre que uno está debajo de la curva. Entonces solo usa el
x
-coordinado.Para la distribución real, hay varios enfoques plausibles. Por ejemplo, para el número de planeta
i
en la ubicaciónp
y algún parámetro de fuerzak
(por ejemplo0.5
), defina una funciónf_i(x)=abs(p-x)^k
y luego use la función de distribucióng(x)=f_1(x)*f_2(x)*...*f_n(x)
.En la práctica, calcule y almacene los resultados de
g(x)
a arrayt
(t[x]=g(x)
); recuerde el valor más alto vistoh
también. Elija una posición aleatoriax
ent
, elija un valor aleatorioy
entre0
yh
, repitaif y>t[x]
; de lo contrario, el valor de retorno esx
.fuente
No estoy seguro de que la pregunta especifique completamente el problema, pero puedo proporcionar algunas ideas simples, la segunda de ellas proporcionará números aproximadamente de acuerdo con lo que su imagen indica que desea.
De cualquier manera, como puede darse cuenta, la función de distribución está cambiando después de cada número generado y tiene una memoria (es decir, no es de Markovian ) y cualquiera de estos métodos puede resultar poco práctico cuando la 'memoria' (número de números extraídos previamente) muy grande.
Simple:
genere un número aleatorio a partir de una distribución plana, compárelo con números dibujados previamente, repita si está 'demasiado cerca'
Esta respuesta es más parecida a su figura (suponiendo que queremos extraer de 0..1):
Los puntos finales son un caso especial, pero debería ser lo suficientemente simple para que usted vea cómo manejarlos.
fuente
Piensa en la diferencia entre 1 dado y 3 dados . 1 dado le da una probabilidad uniforme para todos los valores, mientras que 3 dados tenderán a tener una probabilidad más alta para los valores hacia el medio.
Cuantos más "dados" haya en su ecuación, más posibilidades tendrá de obtener algo hacia el centro. Así que definamos una función que pueda manejar cualquier número de manera uniforme :
Ahora podemos definir una función de ejemplo para usar esto:
Ahora, lo primero en notar es que este código realmente no verifica si el selector ya coincide con uno de los puntos. Si lo hace, simplemente no va a generar un punto, posiblemente algo que le gustaría.
Para explicar lo que está sucediendo aquí, CenterRandom genera una especie de curva de campana. Esta función divide el plano en múltiples curvas de campana, una por par de puntos existentes. El selector nos dice desde qué curva de campana generar. Dado que elegimos linealmente, podemos asegurarnos de que los pares con espacios más grandes entre ellos se elijan con mayor frecuencia, pero aún lo dejamos completamente al azar.
Espero que esto te señale en la dirección correcta.
fuente
Sé que está preguntando acerca de una secuencia de posiciones aleatorias, pero si no está restringido a generar el conjunto secuencialmente, hay otro enfoque: generar un conjunto de puntos que tenga el espacio deseado.
Lo que creo que quieres es un conjunto de planetas que estén razonablemente espaciados con cierta aleatoriedad. En lugar de generar posiciones planetarias con un generador de números aleatorios, genere un espacio entre planetas con un generador de números aleatorios. Esto le permitirá controlar directamente la distribución del espaciado, mediante el uso de un generador de números aleatorios que selecciona de esa distribución. Esto es sencillo en 1 dimensión.
En 2 dimensiones, he visto algunos enfoques que generan "ruido azul", pero no conozco una forma de generar espacios con una distribución arbitraria. Este artículo cubre el enfoque estándar de "intenta colocarlo y rechaza si está demasiado cerca", pero puedes generarlos todos a la vez, con una solución "más suave" colocando todos tus puntos, luego usando Lloyd Relaxation para mover todos los planetas a más posiciones deseables Moverá los planetas demasiado cercanos más lejos. Los mosaicos Wang recursivos son otro enfoque que podría ser útil. Este papelextiende el problema a generar planetas con una densidad y algún otro objeto como los asteroides con otra densidad. También podría generar ruido azul utilizando la serie Fourier; No estoy seguro. El enfoque de la serie de Fourier también le permitiría usar distribuciones arbitrarias en lugar de solo ruido azul.
fuente