De hecho, este problema es más de matemáticas que de programación.
Al fijar la suma, los resutados entre sí ya no son independientes, sino que están ligados de alguna manera (probabilidad condicionada)
Cada uno debe ser como mínimo =1, por lo tanto, ninguno de ellos debe superar 71
(A tener en cuenta: la funcion rnd(a,b) devuelve un numero entre a y b-1)
Una aproximación NO uniforme, que serviría por ejemplo en un caso como el siguiente: tenemos 75 bolas en una caja, viene una primera persona y saca un numero definido entre 1 y 71, luego una segunda, saca un numero aleatorio entre uno y las que queden menos 3, etc....
Sub Lista_Aleatorios(cuantos As Int, maximo As Int) As Int()
If cuantos>maximo Then Return Null
Dim numeros(cuantos) As Int
Dim k As Int
Dim parcial_acumulado As Int=0
For k=1 To cuantos
numeros(k-1)=Rnd(1,maximo+1-(cuantos-k)-parcial_acumulado)
parcial_acumulado = parcial_acumulado + numeros(k-1)
Next
Return numeros
End Sub
Sin embargo, si quieres distribuciones realmente independientes (que cada conjunto de 5 numeros cuya suma sea 75 tenga la misma probabilidad que otro conjunto), la aproximación dada aquí es muy buena:
Por ejemplo, si tenemos: suma=75 y num_valores=5
Crea una lista
Genera 4 ( = num_valores-1) numeros aleatorios entre 1 y 74 ( = suma-1) --> lo generaremos mediante rnd(1,75) , ya que rnd(a,b) genera numeros entre a y b-1
Si no está en la lista, lo añadimos
Si ya lo está, generamos otro hasta que no esté en la lista.
Ordena la lista de menor a mayor.
Nuestros numeros serán:
numero(0) = lista(0)
numero(1) = lista(1)-lista(0)
numero(2) = lista(2)-lista(1)
numero(3) = lista(3)-lista(2)
numero(4) = 75 - lista(3)
Ya que estamos, añado el código
B4X:
Sub Lista_Aleatorios2(cuantos As Int, maximo As Int) As Int()
If cuantos>maximo Then Return Null
Dim l_dist As List
l_dist.Initialize
Dim k As Int =1
Dim Num As Int
Do While k<cuantos
Num = Rnd(1,maximo)
If l_dist.IndexOf(Num)=-1 Then 'Si no existe, lo añadimos a la lista
l_dist.Add(Num)
k=k+1
End If
Loop
l_dist.Add(maximo) 'per al bucle que ve
l_dist.Sort(True)
Dim myNumbers(cuantos) As Int
myNumbers(0)=l_dist.Get(0)
For k=1 To cuantos-1
myNumbers(k)=l_dist.Get(k)-l_dist.Get(k-1)
Next
Return myNumbers
End Sub
Joder, menuda respuesta. Es un placer leer réplicas tan extensas y detalladas
Estoy realizando pruebas y funciona a la perfección excepto que si aleatoriamente se genera un número elevado y próximo a la suma, el resto de números pendientes quedan MUY condicionados a la baja.
Hola!!!! pues copie el código como tal y agregue un:
log y un EditText1.text
con la opción de:
#BridgeLogger: True
pero no me entrega ningún dato.
los datos se los mando así:
Sub Button1_Click
xui.MsgboxAsync("Hello world!", "B4X")
Lista_Aleatorios2(1,25)
End Sub
pero no obtengo ningun dato, alguna idea del porque???
Sub Lista_Aleatorios2(cuantos As Int, maximo As Int) As Int()
If cuantos>maximo Then Return Null
Dim l_dist As List
l_dist.Initialize
Dim k As Int =1
Dim Num As Int
Do While k<cuantos
Num = Rnd(1,maximo)
If l_dist.IndexOf(Num)=-1 Then 'Si no existe, lo añadimos a la lista
l_dist.Add(Num)
k=k+1
End If
Loop
l_dist.Add(maximo) 'per al bucle que ve
l_dist.Sort(True)
Dim myNumbers(cuantos) As Int
myNumbers(0)=l_dist.Get(0)
For k=1 To cuantos-1
myNumbers(k)=l_dist.Get(k)-l_dist.Get(k-1)
Next
Log(myNumbers)
Return myNumbers
EditText1.text=myNumbers
End Sub
Es mejor que cuando postees código, lo pongas entre [ CODE] ...aqui el código... [ /CODE], así es más legible
(sin los espacios después del "[" )
Hay un par de cosas a modificar en tu código
B4X:
Sub Button1_Click
xui.MsgboxAsync("Hello world!", "B4X")
Lista_Aleatorios2(4,25) '<-- con Lista_Aleatorios(1,25) funcionaba, pero siempre devuelve un solo elemento que vale 25
End Sub
Sub Lista_Aleatorios2(cuantos As Int, maximo As Int) As Int()
If cuantos>maximo Then Return Null
Dim l_dist As List
l_dist.Initialize
Dim k As Int =1
Dim Num As Int
Do While k<cuantos
Num = Rnd(1,maximo)
If l_dist.IndexOf(Num)=-1 Then 'Si no existe, lo añadimos a la lista
l_dist.Add(Num)
k=k+1
End If
Loop
l_dist.Add(maximo) 'per al bucle que ve
l_dist.Sort(True)
Dim myNumbers(cuantos) As Int
myNumbers(0)=l_dist.Get(0)
For k=1 To cuantos-1
myNumbers(k)=l_dist.Get(k)-l_dist.Get(k-1)
Next
'Log(myNumbers) '<-- Para hacer un log de un array, se debe hacer de cada uno de sus elementos
Dim resultString As String
For k=0 to myNumbers.length-1 '<-- Convertimos uno a uno y lo ponemos a un string
resultString = resultString & myNumbers(k) & ","
Next
Log( resultString)
'Return myNumbers '<-- Lo comentamos, o ya no se ejecutará lo de después
'EditText1.text=myNumbers '<-- Lo mismo que el Log(), no se puede convertir todo un array a texto, se tiene que hacer elemento a elemento o con alguna funcion intermedia
EditText1.text = resultString
Return myNumbers '<-- Lo ponemos aquí
End Sub
Es mejor que cuando postees código, lo pongas entre [ CODE] ...aqui el código... [ /CODE], así es más legible
(sin los espacios después del "[" )
Hay un par de cosas a modificar en tu código
B4X:
Sub Button1_Click
xui.MsgboxAsync("Hello world!", "B4X")
Lista_Aleatorios2(4,25) '<-- con Lista_Aleatorios(1,25) funcionaba, pero siempre devuelve un solo elemento que vale 25
End Sub
Sub Lista_Aleatorios2(cuantos As Int, maximo As Int) As Int()
If cuantos>maximo Then Return Null
Dim l_dist As List
l_dist.Initialize
Dim k As Int =1
Dim Num As Int
Do While k<cuantos
Num = Rnd(1,maximo)
If l_dist.IndexOf(Num)=-1 Then 'Si no existe, lo añadimos a la lista
l_dist.Add(Num)
k=k+1
End If
Loop
l_dist.Add(maximo) 'per al bucle que ve
l_dist.Sort(True)
Dim myNumbers(cuantos) As Int
myNumbers(0)=l_dist.Get(0)
For k=1 To cuantos-1
myNumbers(k)=l_dist.Get(k)-l_dist.Get(k-1)
Next
'Log(myNumbers) '<-- Para hacer un log de un array, se debe hacer de cada uno de sus elementos
Dim resultString As String
For k=0 to myNumbers.length-1 '<-- Convertimos uno a uno y lo ponemos a un string
resultString = resultString & myNumbers(k) & ","
Next
Log( resultString)
'Return myNumbers '<-- Lo comentamos, o ya no se ejecutará lo de después
'EditText1.text=myNumbers '<-- Lo mismo que el Log(), no se puede convertir todo un array a texto, se tiene que hacer elemento a elemento o con alguna funcion intermedia
EditText1.text = resultString
Return myNumbers '<-- Lo ponemos aquí
End Sub
Muchas Gracias!!!!
Con eso de que el post es del 2015
no pensé que alguien responderia...
estoy muy agradecido, me has ayudado a generar números para generar una " licencia"
así cómo se hacia con los seriales de windows jejejje
Gracias de nuevo y feliz día!!!
Hola!! de nuevo
y para el caso en que yo tenga esos números 2 4 6 8 16 (que suman 36) dentro de un edittext.text
y quiera sumarlos, cómo tendría que proceder??
Gracias
y
F3l1z c0d1f1c4c10n
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.