C - Numeros aleatorios

ethernal-

Necesito rellenar una matriz de probabilidades tal forma que los elementos sean numeros aleatorios, y cada columna sume 1.

El problema es que no se utilizar bien las funciones para generar los numeros aleatorios, a ver si alguien me echa un cable.

He leido que con srand48 y drand48 generas numeros entre 0 y 1, lo cual seria lo ideal para empezar.

Hago primero srand48(time(NULL)) y luego genero numeros pero me salen todos 0 y los dos ultimos nan ;(

PD: utilizo kubuntu, por si sirviera de algo xD

T

estas usando un array de enteros... casi que al 80%, usalo de double y tirando, así almacenará decimales.

ethernal-

Pues no ;(

Aqui esta el codigo que llevo:

http://pastebin.com/m21eb8253
http://pastebin.com/mcd9a26b

SicKneSs

tienes declarada una matriz 7 por 7. Se te quedarán posiciones de la matriz sin inicializar si el parámetro que le pasas a la función rellenarMatriz es < 7

Nose qué hacen las funciones srand48 ni drand48

ethernal-

Lo del tamaño de la matriz es otra historia...

Esta asi porque no se me ocurre otra forma de que el tamaño sea elegido por el usuario, ya que si la paso como parametro hay que declarar como minimo el numero de columnas, por lo que se pierde la opcion de elegir el tamaño.

Asi que declaro una de 7 que es el tamaño maximo que da el enunciado, y si el usuario elige menos no hay problemas.

Los ejemplos que colgaron de practicas tambien lo hacen asi vaya, si hay una opcion mejor pues soy todo orejas xD

maRc

Una manera sería generar tantos números enteros aleatorios como filas tenga la columna y los divides por la suma de todos ellos.

Lo segundo lo podrías hacer con punteros y memoria dinámica, pero si no os han enseñado, dejalo ;)

B

Que coño son esas funciones? XD

Usa el rand o random de toda la vida tio.

En ese programa, no esta por ningun lado la condicion de que una columna sume 1.

Para ello se me ocurria algo simple, caso particular si fueran de 4 numeros la columna.

Generas el primero aleatorio entre 0 y 1, el segundo aleatorio entre 0 y 1-(el primero), el tercero entre 0 y 1-(el primero+segundo), el cuarto y ultimo, 1-(el primero+segundo+tercero).

Hacer este ejercicio con punteros y memoria dinamica (si no va dirigido el ejemplo a utilizarlos) es como construir el coliseo con palillos xD, trabajo para nada, a no ser que sea algo didactico.

Tampoco pasa nada que haya campos sin inicializar si nunca (ni por accidente) vas a hacer referencia a ellos, es como otra posicion de memoria cualquiera sin mas.

IAF

Para hacer una matriz del tamaño que quiera el usuario algo fácil es hacer una variable global DIM

ethernal-

#7 antes de hacer que sumen uno quiero aprender a hacer los numeros aleatorios. No utilizo rand() porque siempre genera los mismos, segun he leido. Asi que se pone srand con una semilla aleatoria (la hora o la id del proceso).

#8 no nos dejan usar variables globales en las practicas :P

Khanser

Si usas lo que dice #7, no es seguro que siempre te sume 1 la fila, o columna, o lo que sea

Soltrac

Lo q no se es como te compila :S

Para llamar a la función time si no recuerdo mal tienes q poner #include <time.h>

Y tb creo q srand48 y drand48 estaban en #include <stdlib.h>

MTX_Anubis

#10 como que no? si el útlimo número es 1-(suma de los otros números) la suma de todos los números por obligación tiene que ser 1

1-x=y <-> 1=y+x

B

#9

no tiene pq generar siempre el mismo, es mucha casualidad eso.

tanto rand como rand48 utilizan una serie de esas raras matematicas para generar un numero, la ventaja del rand48 es que tu le puedes decir la condicion inicial, es lo que he leido por ahi mas o menos.

pero vamos, ya es mucha casualidad (q puede ocurrir) que rand genere el mismo numero

_kRuStY_

la funcion rand() te devuelve un numero pseudoaleatorio entre 0 y RAN_MAX que tiene un valor que no macuerdo pero era muy grande.

Para generar numeros aleatorios entre 2 limites utiliza esto:

int aleatnum(int iP,int iU){
int num;

num=rand()%(iU-iP+1)+iP;

return num;

}

en el programa desde donde llames utiliza:
srand(time(NULL)); /Inicializa la semilla/
aleatnum(0,1);

PirLo_21

mb krusty... codigo completamente correcto... xD xD

ethernal-

A ver...

#14 tu codigo esta perfect, pero no vale para numeros decimales que es el objetivo. Probé a dividir y despues multiplicar por 100 con un casting a int, pero al ejecutar da error de coma flotante.

Al final #11 tenia razon, para utilizar srand48 y drand48 hay que incluir la stdlib.h. Lo raro es que si no la incluyo compila sin errores, pero los numeros salen 0 y nan como posteé al principio. Pero vamos, que ahora la incluyo y funciona sin problemas.

Aqui esta el codigo final, haciendo que las columnas sumen 1:
principal.c: http://pastebin.com/mcd9a26b
funciones.c : http://pastebin.com/m3ebf4bb5

Gracias a todos :D :D

_kRuStY_

No sabia que los querias con decimales pero vamos...

x=aleatnum(0,1000);
x/=1000;

No era tan dificil amigo xD. Yo lo haria asi, lo del sradn48 no me convence nada, nunca lo habia visto, seguro que es standar?? Porque no se si te dejaran cosas que no sean standar

Saludos ^^

LOc0


for (j = 0; j < dimension; j++) {
total = 1.0;
suma = 0.0;
for (i = 0; i < dimension; i++) {
matriz[j] = drand48() * total;
total -= matriz[j];
}
}


Yo tengo mis dudas de que ese algoritmo te haga que la suma de todos los elementos de la columna sea 1. Un contraejemplo:

Matriz de 2x2. Empiezas con el elemento [0][0]. Generas tu numerito aleatorio [0-1] con drand48(). Pongamos que te sale un 0.3, que multiplicado por total sale 0.3*1 = 0.3 Restas al total (1) el numerito que te ha salido, con lo que total ahora vale 0.7 y matriz[0][0] es 0.3

Ahora te vas a generar el elemento [1][0]. Drand48() te devuelve un 0.4 por ejemplo. Igual que antes, lo multiplicas por total, quedándote 0.4*0.7 = 0.28 Se lo restas al total (0.7), y te queda que total ahora vale 0.42 y matriz[1][0] es 0.28

Si sumas matriz[0][0] + matriz[1][0] sale 0.3 + 0.28 != 1

Algo huele mal en Black Mesa ¬ ¬...

Salu2 ;)

ethernal-

No se, lo probe metiendo la variable suma en cada iteracion y sumando todos los randoms de cada columna, y daba 0.99 aprox.

Si te fijas en el pastebin se me quedo una linea con la variable suma a la hora de limpiar el codigo y tuve que arreglarlo xD

[/i]Edit: Pues tienes razon, no suma 1 y es logico. Lo que pasa que estaba probando con matrices de 6 y 7 y por probabilidad las sumas daban casi 1 xD.

Lo dejo por hoy que tengo que marchar, a ver si a alguien se le ocurre alguna idea fantasticosa :D
[/i]

LOc0

Haz lo que dice #6.


for (j = 0; j < dimension; j++)
{

	for (i = 0, suma=0; i < dimension; suma+=matriz[i++][j])

matriz[j] = drand48();

       for (i = 0; i < dimension; i++)
		matriz[i][j]/=suma;

}
[/i]

Salu2 ;)

_kRuStY_

Cierto, tu codigo estaba mal , no se ni pa que hacias las multiplicacion pero weno, te iba a poner el codigo corregido pero lo que te dice Loco esta bien (mola el for xD, no puedes poner i++ como las personas normales? xD )

Saludos ^^

B

como se me pudo olvidar que sumar 1 es normalizar... ¬¬'

LOc0

#22

Será la edad Seuron xD...

Salu2 ;)

PD: aún así hay bastantes cosas que si se olvidan tampoco se echan de menos...

B

xDDDD ni que lo digas tio

Y0K3S3

#14

Se te olvido el randomize() que si no va a ser un poco lol que le salgan todo el rato los mismo...xD

PirLo_21

#25

randomize es en pascal.... ya esta puesto en C --> srand(time(NULL));

Y0K3S3

#26

En C tambien...

PirLo_21

#27
No se si en C habrá randomize... pero de todas maneras con srand es suficiente...

PirLo_21

He mirado lo de randomize... esta en stdlib pero es similar al codigo que puso #14

randomize:

void randomize (void);

randomize initializes the random number generator with a random value (picked from the timer).

Spank

ay doña eva lucrecia
que por culo da xD

Usuarios habituales