Buenas, quiero calcular un array que contenta valores que representan la llegada de un cliente a un establecimiento, quiero que los clientes lleguen con una tasa de x clientes por hora.
Ejemplo. Array que muestra la llegada de 6 clientes con una tasa de 4 clientes por hora en los minutos que empiezan desde cero:
0, 19, 38, 61, 77, 99
¿Alguna idea para generar dicho array?
Si lo he entendido bien lo que necesitas es aplicar la teoria de colas (suena raro pero es asi), estoy refrescando la memoria que hace tiempo que me examine. En resumen seria una probabilidad que aumenta cada tiempo, es decir "probabilidad de que llegue un cliente en el minuto 0 es 0.2344" que llege en el minuto tal es....
Lo miro y te cuento.
Otra cosa mas simple es generar un numero aleatorio de 1 a 60 tantas veces como clientes por hora quieras. Por ejemplo array de 2 horas con 4 clientes hora:
1 - 35
2 - 42
3 - 12
4 - 27
5 - 05 + 60=65
.....
Había pensado en lo segundo, pero habría que ordenarlo. Aparte que así siempre se quedaría todo muy "homogeneo", nunca se daría el caso de que vengan más o menos de 4 clientes en una hora, que podría pasar aunque sea menos probable... además pensaba que habría una fórmula más "automática" :P
Esto es de lo mas simple y menos estadistico:
vector<int> llegadas;
int min_cph=2, max_cph=4;
int nHoras=4, nClientes;
for(int h=0; h<Horas; h++)
{
nClientes=rand()%(max_cph-min_cph)+min_cph // Un numero entre 2 y 4
for(int c=0; c<nClientes; c++)
{
llegadas.push_back(rand()%60 + h*60); // Numero de 0 a 59 mas la hora
}
}
// y ahora a ordenar!!!
bool cambio=false;
do
{
cambio=false;
for(int i=0; i<llegadas.size()-1; i++)
{
if(llegadas[i]>llegadas[i+1])
{
int aux=llegadas[i];
llegadas[i]=aux;
llegadas[i+1]=aux;
cambio=true;
}
}
}while(cambio);
Puede que haya errores xq no le he probado. El numero de clientes por hora es aleatorio con un minimo y un maximo.
Como ha dicho Martinez, la teoría de colas proporciona el tratamiento formal de estos temas.
Para modelar tu problema pueden ser útiles los procesos markovianos (http://en.wikipedia.org/wiki/Markovian_arrival_processes), y en particular el proceso de Poisson.
qué recuerdos de cuando estudiaba, aún recuerdo aquello de la distribución de poisson. Mi aportación en python
from random import random;
N_PER_HOUR = 4.0;
inv = N_PER_HOUR/60.0;
N_HOURS = 100;
min = [x for x in range(N_HOURS*60) if random() < inv];
media_cl = float(len(min))/N_HOURS;
print ("media clientes por hora: %f" % media_cl)
dist = [min[d+1] - min[d] for d in range(0,len(min)-1)];
media = sum(dist)/(len(min)-1.0);
print ("media entre clientes %f" % (media));
== resultado
media clientes por hora: 4.090000
media entre clientes 14.661765
Calculando la varianza en el primer caso me sale muy alta, en torno a la media (como es lógico para una función random uniforme). Para hacerlo un poco más decente se puede usar una campana de gauss para amoldar la varianza:
versión 2 del programa:
from random import random, gauss;
from math import sqrt;
N_PER_HOUR = 4.0;
inv = N_PER_HOUR/60.0;
N_HOURS = 100;
def printData(min):
media_cl = float(len(min))/N_HOURS;
print ("media clientes por hora: %f" % media_cl)
dist = [min[d+1] - min[d] for d in range(0,len(min)-1)];
media = sum(dist)/(len(min)-1.0);
print ("media entre clientes %f" % (media));
print("varianza: %f" % sqrt((sum(map(lambda x: x*x,[d - media for d in dist]))/len(min))));
min = [x for x in range(N_HOURS*60) if random() < inv];
printData(min);
min = [];
minute = 0;
while(minute < N_HOURS*60):
min.append(minute);
minute += gauss(60.0/float(N_PER_HOUR),5.0);
printData(min);
== salida
C:\wrk>clientes.py
media clientes por hora: 3.920000
media entre clientes 15.281330
varianza: 14.627610
media clientes por hora: 4.020000
media entre clientes 14.930669
varianza: 4.845198
Gracias a todos, aunque sigo sin saber generar el array :D
Martínez, gracias por el código, sin embargo y por lo que comenté antes (no es real), no vale tal que así.
Gracias también a tí, ethernet, aunque no es lo que pedía, sino el código que genere el array en sí, no las medias, varianzas, etc. Por lo que tampoco me vale, aparte que no tengo ni idea de Phyton :D. Pero desempolvaré el libro de estadística a ver si Poisson me resuelve el tema.
Gracias a ti también davur, miraré como he dicho Poisson.
Por aquí van los tiros: http://www.um.es/or/ampliacion/node8.html, mañana me lo miro con calma.
Generalmente existen otro tipo de restricciones para la generacion de niveles, y antes de que pierdas tiempo buscando la solución analitica la cual tendras que modificar por cada cambio que hagas te conviene la solución bruta.
Esto siempre que quieras crear los niveles por anticipación y guardarlos en un archivo, cosa altamente recomendada si queires asegurar un balance adecuado en el juego.
const int cantidad_de_clientes;
const float tiempo_total = 60.0f * 4.0f;
const int restriccion_de_clientes_por_hora = 4;
const int restriccion_de_clientes_por_media_hora = 2;
const float restriccion_de_separacion_de_clientes = 45.0f;
float tiempos[ cantidad_de_clientes ];
bool Comprobar_Restricciones()
{
for(int i=0; i<cantidad_de_clientes - restriccion_de_clientes_por_hora-1; i++)
if(tiempos[i]+60.0f>tiempos[i+restriccion_de_clientes_por_hora+1]) return false;
...
...
return true;
}
void calcular()
{
bool todo_ok = false;
while(!todo_ok)
{
for(int i=0; i<cantidad_de_clientes; ++i)
tiempos[i] = frand(tiempo_total);
ordenar(tiempos, cantidad_de_clientes);
todo_ok = comprobar_restricciones();
}
Guardar_En_Archivo();
}
De esta manera puedes ir probando los niveles y cuando ves un patron que no te gusta lo agregas a las restricciones, por ejemplo 3 personajes iguales, todos agrupados a la ves y demas.
Saludos
Hey, gracias por esa otra idea adicional!
En realidad esto no es para el juego (en el juego las peticiones de los clientes van en una línea de tiempos, no por azar), es para una práctica de la universidad, por lo que tiene que ser matemáticamente precisa. Pero vamos creo que he encontrado el método adecuado aquí: http://books.google.com/books?id=3oHztjMSuL8C&pg=PA658&lpg=PA658&dq=utilizaci%C3%B3n+promedio+del+local&source=web&ots=nKyC877OBM&sig=v49m_oyl62t-UkKMnVDDq2KimQw#PPA648,M1
Que describe la siguiente fórmula:
T = -(1/tasa) * ln (1 - R)
Siendo R un número aleatorio entre (0 y 1)
¡Perfect!
Cita de: "Loover"es para una práctica de la universidad
¿Y lo dices ahora, eh, pillín? :D
Si no llegas a ser tú y además lo hubieses dicho en tu mensaje inicial, te hubiesen llovido piedras xDDD
:P
... también es muy útil para juegos... ¿no? :P
A mi no me dejabas otra idea que pensar ... es como que yo estuviera haciendo un juego de aviones y vengo a un foro de desarrollo de juegos donde tengo 3 threads abiertos sobre este juego y pregunto
Yo: tengo que simular un misil, como hago?
Respuesta: Y depende del contexto que no lo estas dando, pero suponiendo que por casualidad sea para tu juego, has esto ...
Yo: No en realidad es para fisica I que tengo que rendir la semana que viene.
Yo caí como tonto ... no se que otra interpretación podria haberle dado.
Jajajaj
Juas juas yo pensaba que era para el juego!!! XDXD
Pero no me dijiste que lo segundo!! (creo que no llegue a entenderte). Bueno no iba mal encaminado con lo de las teorias de colas, ya que se usan distribuciones exponenciales, entre otras la de Poisson. Me alegro que lo hayas solucionado.
Nos vemos.
loover: he puesto la media y varianza para comprobar que el resultado es bueno, los valores de los minutos están en la variable min, que es un array que contiene los minutos en los que llegan los cientes.
En resumen mi código era así:
min = [];
minute = 0;
while(minute < N_HOURS*60):
min.append(minute);
minute += gauss(60.0/float(N_PER_HOUR),5.0);
donde min es lo que te he dicho. Está claro que no vale para tu propósito, ya nos contarás como lo resuelves.
Citarloover: he puesto la media y varianza para comprobar que el resultado es bueno, los valores de los minutos están en la variable min, que es un array que contiene los minutos en los que llegan los cientes.
Ahh! Gracias! Vi el código en phyton y me asusté. La verdad es que manejarlo debe ser brutal a la hora de ahorrar tiempo.
De momento lo estoy probando con la formulilla esta:
T(i) = T(i-1) + [ -(1/tasa) * ln (1 - R) ]
Cita de: "Martinez"Juas juas yo pensaba que era para el juego!!! XDXD
Pero no me dijiste que lo segundo!! (creo que no llegue a entenderte). Bueno no iba mal encaminado con lo de las teorias de colas, ya que se usan distribuciones exponenciales, entre otras la de Poisson. Me alegro que lo hayas solucionado.
Nos vemos.
me ha pasado lo mismo, según leí el mensaje creí que era para las motos que se acercan con los pedidos !
Os engañé a todos :P por lo que veo, jaja. La verdad es que cuando estaba escribiendo lo de "clientes" me olía que igual ibais a pensar eso :P
En el juego todo va por línea de tiempo, cada personaje/bicho/lo que sea, tiene su script, y dentro de él una línea de tiempos.
Los repartidores que vienen el bici vienen x tiempo después de la petición y se van encolando, no aparece uno hasta que has cogido lo de otro.
Y la colisión triángulo / triángulo no era ni para el juego, ni para clase :P, pero no creo que pueda dedicarle tiempo a la LooverLib hasta dentro de unos meses :(
Aquí os pongo una simulación del sistema que quería hacer:
T. Servicio T. Llegada T. Salida Wq Ws
13.9938 0 13.9938 0 14
12.2 0.55 26.2 13.4 25.7
12.8 6.3 39.1 19.9 32.8
12.4 10.8 51.4 28.3 40.7
11.3 15.5 62.7 36 47.3
14.2 36.8 77 26 40.2
14.7 64 91.7 13 27.7
13.9 71.7 106 19.9 33.8
12 73.1 118 32.5 44.5
12 73.3 130 44.3 56.3
11.6 110 141 19.8 31.4
14 110 155 31.4 45.4
13.1 119 168 35.9 49
10.2 120 178 48.5 58.8
14.7 164 193 14.7 29.3
12.4 182 206 11.5 23.9
11 189 217 16.2 27.2
11 206 228 10.4 21.4
10.4 233 244 0 10.4
14.9 239 259 4.77 19.7
Aquí os pongo la simulación final.
He sacado ideas de aquí: http://books.google.com/books?id=oNuXccZkWfIC&pg=PA595&lpg=PA595&dq=longitud+promedio+de+la+cola&source=web&ots=-RktCU3Yts&sig=eeQGd0-9wM8hl-ATFcvPvbe7D2g#PPA577,M1
Y de aquí: http://books.google.com/books?id=3oHztjMSuL8C&pg=PA658&lpg=PA658&dq=utilizaci%C3%B3n+promedio+del+local&source=web&ots=nKyC877OBM&sig=v49m_oyl62t-UkKMnVDDq2KimQw#PPA648,M1
Y alguna cosa de los apuntes... que no es que fueran gran cosa, la verdad.
Primero muestro los 4 valores "reales", luego hago una simulación (en esta he lanzado un muestreo de 5000 veces) y veo si los valores resultantes se parecen o no a los esperados. Se ve que están muy próximos :) (señal necesaria pero no suficiente [frase que les encanta a los profesores] de que el ejercicio está bien).
Gracias a todos y espero que os haya sido de utilidad recordar estas cosillas, ¡un saludo!
---------------------------------------------
Colas M / M / 1
---------------------------------------------
Utilización promedio: 0.666667
Longitud promedio de la cola: 1.33333
Tiempo promedio de espera en la cola 0.333333
Tiempo promedio en el sistema 0.5
---------------------------------------------
Simulación
---------------------------------------------
Utilización promedio Long. promedio de la cola Tiempo promedio espera en cola Tiempo promedio en el sistema
Replicación 1 0.6713 1.367 20.53 30.61
Replicación 2 0.6698 1.372 20.59 30.64
Replicación 3 0.6651 1.325 19.92 29.91
Replicación 4 0.6746 1.34 19.99 30.06
Replicación 5 0.6642 1.328 20.08 30.13
Media 0.669 1.346 20.22 30.27
Desv. std 0.004326 0.02205 0.3142 0.333
In. con. inf. 0.6636 1.319 19.83 29.86
In. con. sup. 0.6744 1.374 20.61 30.68