No te voy a dar un trabajo que debes hacer tú,, pero si te voy a orientar, para que seas capaz de lograr algo decente, será más trabajo del que probablemente habíais previsto, pero el resultado merecerá el esfuerzo.
De entrada vuestro planteamiento falla porque es demasiado simple, le pedís mucho a una simple ecuación.
Los números nunca serán aleatorios, sino pseudoaleatroios, pero pueden serlo tanto que no resulten predecibles.
El algoritmo debe estar separado en 2 partes, IniciarTablas y GenerarNumero
IniciarTablas: podría constar en un preparativo de tablas que se calculan (y varían) cada vez que se reinicia el sistema. Y podría constar de los siguientes pasos
IniciarTablas:
1 - De entrada una buena semilla (sobretodo para iniciar el sistema generador) es tomar el
timer del sistema (una función que nos devuleve los milisegundos que han transcurrido desde
medianoche). Es bueno, porque no puedes programar al milisegundo cuando vas a llamar a una
función y que efectvamente suceda así.
Semilla= timer //la llamada exacta depende del lenguaje pero todos tiene una función similar
2 - Vuestra ecuación ofrece números pero son muy dependientes entre sí. Es preferible partir de
números primos, por tanto, partiendo de una tabla de 1000 primos previamente ya conocida, fijate
que puedes usar como, semilla el timer para elegir un número primo dentro de dicha tabla de
primos. Por ejemplo si el timer marcara 34.567.637 (el día tiene 86.400sg. * 1000 msg.) , y tu
tabla consta de 1000 primos, podría usar el:
primo = Tablaprimos( semilla modulo 1000 ) //es decir el primo guardado en la posición 637 de
la tabla.
3 - Ahora generar una buena dosis de números. El uso de los primos sería con cosas como, tomar
los 100 decimales de la raíz cuadrada del número primo elegido de la tabla. Tampoco tiene por
qué ser los 100 primeros decimales, pueden ser del 325 al 425... un poco de imaginación. Incluso
una vez obtenidos se pueden invertir su orden en la tabla de decimales 'T0', basandonos en si el
msg, del timer es par o impar.
Yo te digo raíz cuadrada, pero nada te impide que sea raíz cúbica, o 5ª... o que dicho valor se
tome de la semilla del timer. La raíz cuadrada siempre será más rápido...
El sistema no te da 100 decimales, los tipos de datos lo limitan. Tienes que preparar un algoritmo
para obtenerlo de forma similar a como lo hacemos manualmente cifra a cifra. Eso queda a vuestro
esfuerzo.
4 - Como verás las series de decimales que van ofreciendo los primos, es muy probable que no
den una buena entropia, habrá series donde unos números aparecerán con bastante más
frecuencia que otros. Esto se arregla si en vez de tomar 1 sola serie tomamos varias y sumamos
índice a índice cada valor de los 100 en la tabla y tomamos la unidad; un ejemplo:
Sean 5 tablas con 100 valores ( los 100 decimales calculados de 5 primos distintos), generamos un bucle:
Para 'n' desde 0 hasta 99 / recorremos todos los índices de la tabla
t0(n) = (t1(n) + t2(n) + t3(n) + t4(n) + t5(n) ) modulo 10
continuar bucle
5 - Ahora ya cuentas con una tabla cuya entropía desconoces, pero que probablemente sea
buena... conviene usar una serie más para obtener una tabla adicional puede ser otra partiendo
de los números primos o incluso una tabla tomando los decimales de pi, supongamos que es esta,
nuestra tabla ahora la calcularemos así:
Para 'n' desde 0 hasta 99 // recorremos todos los índices de la tabla
t0(n) = t0(n) XOR pi(n)
continuar bucle
IniciarTablas, ya está listo ahora podremos ceñirnos a GenerarNumero, que constaría de los
siguientes pasos:
GenerarNumero:
1 - Conviene tener 2 semillas, para la 1ª utilizaremos siempre el timer, la 2ª será uno de los
valores calculados en la fase, de entrada, es decir siendo la 1ª llamada valdra 0.
A la semilla del timer llamémosla 'SemT' y la otra 'Sem2'. Tendremos también un 'desplazador'
llamémosle 'Desp', luego verás para qué lo usamos....
SemT = (timer modulo 100) //esto es nos quedamos sólo con 2 cifras, porque la tabla 't0'
tiene sólo 100 elementos.
//*Sem2 = 0 // al iniciarse el sistema, vale 0, en lo sucesivo retiene el valor internamente
//*Desp = 0 // al inicarse el sistema, vale 0, en lo sucesivo retiene el valor internamente
2 - El número a generar (x) seguirá este camino:
A - Calcular Sem2:
Sem2 = (semT XOR Sem2)
B - Hallar el número a devolver:
x = t0((Sem2 + Desp) modulo 100)
C - Actualizar el desplazador:
Desp = ((Desp + 1) modulo 100)
Cada vez que se genera un número, actualizamos este valor, es como si la matriz entera se
rotase una posición. Pero como rotarla es costoso en tiempo, el desplazador consigue el mismo
efecto, con un coste de tiempo despreciable.
El desplazador consigue que tras cada petición, los números en la tabla ocupen una posición más
atrás. Esto hace que una semilla del timer igual que en otra ocasión y otra semilla secundaria igual
que en otra ocasión, no genere el mismo número que la vez previa a causa del desplazador (salvo
que en esa posición exista el mismo número que en la anterior).
Finalmente hay una tercera funcionalidad, que sería probar la entropía que ofrece nuestro
generador de números aleatorios. Esto no forma parte del algoritmo, pero si para estudiar su comportamiento.
ProbarEntropia:
1 - Para ello sería adecuado poner un bucle que genere pongamos 100.000 números y los
guarde en una matriz.
2 - Contar apariciones de cada número: Recorremos dicha tabla y contamos las veces que
aparece cada número, será buen generador siempre que la aparición de cada número se aproxime
a los 10.0000
3 - Contar repeticiones seguidas: como mínimo le pediríamos otra prueba a nuestro generador,
que nos diga cuantas veces seguidas aparece cada número.
Dado que si pidiéramos 10 números la probabilidad sería 1/10, para 100 números la probabilidad de
que saliera por ejemplo 6 y luego otra vez 6 sería 1/100, luego para 100.000 sería 5 veces
seguidas... es decir iniciaremos otro bucle que recorra los 100.000 números y contaremos cuantas
veces para cada número aparece seguido 5 o más veces.
Lo daremos por excelente si para cada número ocurre un máximo de 3 veces, (ojo 6 veces
seguidas un número(333333) no se ha de tomar como que 2 veces aparecen 5 veces seguidas un
número (33333x y x33333) o en total la media entre todos no supera 1'5 veces.
Bueno, como ves, tienes por donde guiarte para hacer algo decente... aunque más complejo que la simple ecuación de la que partíais.
La semilla se toma del timer, pero luego se combina (mediante XOR) con el resultado obtenido la vez anterior, a su vez se va rotando la tabla (virtualmente), en pasos de 1. y cada vez que el sistema se reinicia (por ejemplo cada vez que se enciende el ordenador) se eligen nuevas tablas, que son válidas hasta que de nuevo se apague el equipo.
p.d.: Olvidaba decirte, que los números generados serán en el rango 0-9, que imagino es lo que necesitais, no en el rango 0-10, como decías, creo que por error.