private void Simular() { var inicioFinInstance = new InicioFinDelegate(InicioFin); var columnasInstance = new ColumnasDelegate(AgregarColumnas); var filaInstance = new FilaDelegate(AgregarFila); var statusInstance = new StatusDelegate(ActualizarStatus); var resultadosInstance = new ResultadosDelegate(MostrarResultados); Invoke(inicioFinInstance, false); Boolean bContinua = false; int nTipoContinua = 0; if (rbTP6.Checked) { bContinua = true; if (rb_euler.Checked) { nTipoContinua = 1; } if (rb_rungekutta.Checked) { nTipoContinua = 2; } } // opcional: uso un generador congruencial mixto en vez de un generador del sistema. var generadorCongMixto = new CongruencialMixto(1000, 12, 17, 5000); var recepcionA = double.Parse(txt_recepcion_a.Text); var recepcionB = double.Parse(txt_recepcion_b.Text); //var distribucionRecepcion = new DistribucionUniforme(recepcionA, recepcionB); //uso generador del sistema var distribucionRecepcion = new DistribucionUniforme(recepcionA, recepcionB, generadorCongMixto); //uso generador cong. mixto. var colaRecepcion = new ColaFifo("Recepción"); var recepcion = new Servidor(distribucionRecepcion, colaRecepcion, "Recepción", false); //crea el objeto servidor de recepciony le pasa la cola y la distribucion var balanzaA = double.Parse(txt_balanza_a.Text); var balanzaB = double.Parse(txt_balanza_b.Text); //var distribucionBalanza = new DistribucionUniforme(balanzaA, balanzaB); //uso generador del sistema var distribucionBalanza = new DistribucionUniforme(balanzaA, balanzaB, generadorCongMixto); //uso generador cong. mixto. var colaBalanza = new ColaFifo("Balanza"); var balanza = new Servidor(distribucionBalanza, colaBalanza, "Balanza", false); //crea la balanza y le pasa la cola y la distribucion var litrosA = double.Parse(txt_litros_a.Text); var litrosB = double.Parse(txt_litros_b.Text); var distribucionLitros = new DistribucionUniforme(litrosA, litrosB, generadorCongMixto); var distribucionK = new DistribucionNormal(0.2, 0.7, generadorCongMixto); var darsenasA = double.Parse(txt_darsenas_a.Text); var darsenasB = double.Parse(txt_darsenas_b.Text); //var distribucionDarsenas = new DistribucionUniforme(darsenasA, darsenasB); //uso generador del sistema var distribucionDarsenas = new DistribucionUniforme(darsenasA, darsenasB, generadorCongMixto); //uso generador cong. mixto. var colaDarsenas = new ColaFifo("Dársenas"); var mediaRecalibracion = double.Parse(txt_recalibracion_media.Text); var varianzaRecalibracion = double.Parse(txt_recalibracion_varianza.Text); //var distribucionRecalibracion = new DistribucionNormal(mediaRecalibracion, varianzaRecalibracion); //uso generador del sistema var distribucionRecalibracion = new DistribucionNormal(mediaRecalibracion, varianzaRecalibracion, generadorCongMixto); //uso generador cong. mixto. var darsena1 = new Servidor(distribucionDarsenas, colaDarsenas, "Dársena 1", bContinua, distribucionRecalibracion, distribucionLitros, distribucionK, nTipoContinua); //crea las darsenas var darsena2 = new Servidor(distribucionDarsenas, colaDarsenas, "Dársena 2", bContinua, distribucionRecalibracion, distribucionLitros, distribucionK, nTipoContinua); //crea las darsenas IDistribucion distribucionLlegadas; var horaInicio = DateTime.Today.AddHours(5); var horaFin = DateTime.Today.AddHours(18); Llegada llegadas; if (rb_estrategia_a.Checked) //elije que estrategias va a usar si la exponencial o la uniforme para las llegadas { var lambda = double.Parse(txt_llegadas_lambda.Text); lambda = lambda / 24; // convierto el numero a su valor en formato de horas lambda = lambda / 60; // convierto el numero de formato horas a su valor en horas-minutos. distribucionLlegadas = new DistribucionExponencialNegativa(lambda); llegadas = new Llegada(distribucionLlegadas, DateTime.Today.AddHours(12), horaFin); } else { distribucionLlegadas = new DistribucionUniforme(7, 8); llegadas = new Llegada(distribucionLlegadas, horaInicio, horaFin); } var dias = int.Parse(txt_dias.Text); // cuantos dias se va a simular var desde = int.Parse(txt_desde.Text); var hasta = int.Parse(txt_hasta.Text); decimal promedioAtendidos = 0; decimal promedioNoAtendidos = 0; decimal promedioPermanencia = 0; var afuera = new List <Cliente>(); //lista de cuantos camiones quedaron afuera var simulacion = 0; var numCamion = 0; var clientes = new List <Cliente>(); _cancelar = false; for (var dia = 1; dia <= dias; dia++) //empieza la simulacion desde el dia 1 { if (_cancelar) { break; } var atendidos = 0; var noAtendidos = 0; decimal permanenciaDiaria = 0; llegadas.Abrir(); while (llegadas.EstaAbierto() || !recepcion.EstaLibre() || !balanza.EstaLibre() || !darsena1.EstaLibre() || !darsena2.EstaLibre()) //se fija que este abierto y esten libres los servidores { if (_cancelar) { break; } simulacion++; if (llegadas.EstaAbierto() && afuera.Count > 0) { foreach (var cliente in afuera) { if (_cancelar) { break; } cliente.Llegar(horaInicio); recepcion.LlegadaCliente(horaInicio, cliente); } afuera = new List <Cliente>(); } var eventos = new List <Evento> { new Evento("Llegada", llegadas.ProximaLlegada), new Evento("Cierre", llegadas.Cierre), new Evento("Fin Recepción", recepcion.ProximoFinAtencion), new Evento("Fin Balanza", balanza.ProximoFinAtencion), new Evento("Fin Dársena 1", darsena1.ProximoFinAtencion), new Evento("Fin Dársena 2", darsena2.ProximoFinAtencion) }; var relojActual = eventos.Where(ev => ev.Hora.HasValue).Min(ev => ev.Hora).Value; var eventoActual = eventos.First(ev => ev.Hora.Equals(relojActual)).Nombre; switch (eventoActual) { case "Llegada": numCamion++; var clienteLlegando = new Cliente($"Camión {numCamion}"); clienteLlegando.Llegar(relojActual); recepcion.LlegadaCliente(relojActual, clienteLlegando); if (rb_estrategia_a.Checked) { llegadas.ActualizarLlegada(1); } else { llegadas.ActualizarLlegada(0); } if (simulacion <= hasta) { clientes.Add(clienteLlegando); Invoke(columnasInstance, numCamion); } break; case "Fin Recepción": var clienteReceptado = recepcion.FinAtencion(); balanza.LlegadaCliente(relojActual, clienteReceptado); break; case "Fin Balanza": var clientePesado = balanza.FinAtencion(); if (darsena1.EstaLibre()) { darsena1.LlegadaCliente(relojActual, clientePesado); } else { darsena2.LlegadaCliente(relojActual, clientePesado); } break; case "Fin Dársena 1": var clienteSaliendo1 = darsena1.FinAtencion(); if (clienteSaliendo1 != null) { clienteSaliendo1.Salir(relojActual); permanenciaDiaria = (permanenciaDiaria * atendidos + clienteSaliendo1.TiempoEnSistema) / (atendidos + 1); atendidos++; } break; case "Fin Dársena 2": var clienteSaliendo2 = darsena2.FinAtencion(); if (clienteSaliendo2 != null) { clienteSaliendo2.Salir(relojActual); permanenciaDiaria = (permanenciaDiaria * atendidos + clienteSaliendo2.TiempoEnSistema) / (atendidos + 1); atendidos++; } break; case "Cierre": llegadas.Cerrar(); noAtendidos = colaRecepcion.Cantidad(); afuera.AddRange(colaRecepcion.Clientes); colaRecepcion.Vaciar(); promedioNoAtendidos = (promedioNoAtendidos * (dia - 1) + noAtendidos) / dia; break; } if (simulacion % 10 == 0) { Invoke(statusInstance, dia, relojActual, simulacion); } //termina la simulacion if (simulacion >= desde && simulacion <= hasta) { //esto invoca el metodo de llenado de la fila Invoke(filaInstance, relojActual, eventoActual, llegadas, colaRecepcion, recepcion, colaBalanza, balanza, colaDarsenas, darsena1, darsena2, atendidos, noAtendidos, permanenciaDiaria, clientes); } } var permanenciaAnterior = promedioPermanencia * promedioAtendidos * (dia - 1); promedioAtendidos = (promedioAtendidos * (dia - 1) + atendidos) / dia; promedioNoAtendidos = (promedioNoAtendidos * (dia - 1) + noAtendidos) / dia; if (promedioAtendidos != 0) { promedioPermanencia = (permanenciaAnterior + permanenciaDiaria * atendidos) / (promedioAtendidos * dia); } } Invoke(resultadosInstance, promedioAtendidos, promedioNoAtendidos, promedioPermanencia); Invoke(inicioFinInstance, true); var resultado = _cancelar ? "interrumpida" : "completa"; MessageBox.Show($@"Simulación {resultado}", @"Resultado"); }
private void Simular() { //delegates var inicioFinInstance = new InicioFinDelegate(InicioFin); var columnasInstance = new ColumnasDelegate(AgregarColumnas); var filaInstance = new FilaDelegate(AgregarFila); var statusInstance = new StatusDelegate(ActualizarStatus); var resultadosInstance = new ResultadosDelegate(MostrarResultados); //preparación inicial del formulario Invoke(inicioFinInstance, false); //clientes var entreLlegadas = double.Parse(txt_llegadas.Text); var distribucionLlegadas = new DistribucionUniforme(entreLlegadas, entreLlegadas); var minInicio = (double)DateTimeConverter.EnMinutos($"{txt_apertura.Text}:00"); var horaInicio = DateTime.Today.AddMinutes(minInicio); var minFin = (double)DateTimeConverter.EnMinutos($"{txt_cierre.Text}:00"); var horaFin = DateTime.Today.AddMinutes(minFin); var local = new Llegada(distribucionLlegadas, horaInicio, horaFin); var colaMax = int.Parse(txt_cola_max.Text); //grupos var probabilidadGrupo2 = double.Parse(txt_grupos_2.Text); var probabilidadGrupo4 = double.Parse(txt_grupos_4.Text); var grupos = new DistribucionAleatoria(new List <Probabilidad> { new Probabilidad(2, probabilidadGrupo2), new Probabilidad(4, probabilidadGrupo4) }); //menús var probabilidadMenu1 = double.Parse(txt_menu_1.Text); var probabilidadMenu2 = double.Parse(txt_menu_2.Text); var menus = new DistribucionAleatoria(new List <Probabilidad> { new Probabilidad(1, probabilidadMenu1), new Probabilidad(2, probabilidadMenu2) }); var demoraMenu1 = double.Parse(txt_demora_menu_1.Text); var distribucionMenu1 = new DistribucionUniforme(demoraMenu1, demoraMenu1); var demoraMenu2 = double.Parse(txt_demora_menu_2.Text); var distribucionMenu2 = new DistribucionUniforme(demoraMenu2, demoraMenu2); //mozo var demoraCarta = double.Parse(txt_carta.Text); var distribucionCarta = new DistribucionUniforme(demoraCarta, demoraCarta); var demoraPedido = double.Parse(txt_pedido.Text); var distribucionPedido = new DistribucionUniforme(demoraPedido, demoraPedido); //comida var media = double.Parse(txt_comida_media.Text); var varianza = double.Parse(txt_comida_varianza.Text); var distribucionComida = new DistribucionNormal(media, varianza); //eventos var inicio = int.Parse(txt_desde.Text); var fin = int.Parse(txt_hasta.Text); //servidores var colaMesas = new ColaVacia(); var mesa1 = new Servidor(distribucionComida, colaMesas, "Mesa 1"); var mesa2 = new Servidor(distribucionComida, colaMesas, "Mesa 2"); var mesa3 = new Servidor(distribucionComida, colaMesas, "Mesa 3"); var mesa4 = new Servidor(distribucionComida, colaMesas, "Mesa 4"); var mesa5 = new Servidor(distribucionComida, colaMesas, "Mesa 5"); var mesa6 = new Servidor(distribucionComida, colaMesas, "Mesa 6"); var mesa7 = new Servidor(distribucionComida, colaMesas, "Mesa 7"); var mesa8 = new Servidor(distribucionComida, colaMesas, "Mesa 8"); var mesa9 = new Servidor(distribucionComida, colaMesas, "Mesa 9"); var mesa10 = new Servidor(distribucionComida, colaMesas, "Mesa 10"); var mesas = new List <Ocupacion> { new Ocupacion(mesa1), new Ocupacion(mesa2), new Ocupacion(mesa3), new Ocupacion(mesa4), new Ocupacion(mesa5), new Ocupacion(mesa6), new Ocupacion(mesa7), new Ocupacion(mesa8), new Ocupacion(mesa9), new Ocupacion(mesa10) }; var colaMozo = new ColaPriorizada("mozo"); var mozo = new ServidorDoble(distribucionCarta, distribucionPedido, colaMozo, "mozo"); var colaCocina = new ColaFifo("cocina"); var cocina = new ServidorDoble(distribucionMenu1, distribucionMenu2, colaCocina, "cocina"); //simulación var simulacion = 0; var numCliente = 0; var colaLocal = new ColaFifo("local"); var clientes = new List <VectorCliente>(); var atendidos = 0; var perdidos = 0; var acumuladorEspera = new PromedioAcumulado(); decimal esperaPromedio = 0; local.Abrir(); _cancelar = false; while (local.EstaAbierto() || !mozo.EstaLibre() || !cocina.EstaLibre() || mesas.Any(m => !m.Mesa.EstaLibre())) { if (_cancelar) { break; } simulacion++; var eventos = new List <Evento> { new Evento("Llegada", local.ProximaLlegada), new Evento("Cierre", local.Cierre), new Evento("Fin Mozo", mozo.ProximoFinAtencion), new Evento("Fin Cocina", cocina.ProximoFinAtencion), new Evento("Fin Mesa 1", mesa1.ProximoFinAtencion), new Evento("Fin Mesa 2", mesa2.ProximoFinAtencion), new Evento("Fin Mesa 3", mesa3.ProximoFinAtencion), new Evento("Fin Mesa 4", mesa4.ProximoFinAtencion), new Evento("Fin Mesa 5", mesa5.ProximoFinAtencion), new Evento("Fin Mesa 6", mesa6.ProximoFinAtencion), new Evento("Fin Mesa 7", mesa7.ProximoFinAtencion), new Evento("Fin Mesa 8", mesa8.ProximoFinAtencion), new Evento("Fin Mesa 9", mesa9.ProximoFinAtencion), new Evento("Fin Mesa 10", mesa10.ProximoFinAtencion), }; // ReSharper disable once PossibleInvalidOperationException var relojActual = eventos.Where(ev => ev.Hora.HasValue).Min(ev => ev.Hora).Value; var eventoActual = eventos.First(ev => ev.Hora.Equals(relojActual)).Nombre; switch (eventoActual) { case "Llegada": local.ActualizarLlegada(); numCliente++; var clienteLlegando = new Cliente($"Grupo {numCliente}", 1); clienteLlegando.Llegar(relojActual); var cantidadGrupo = (int)grupos.ObtenerValor(); if (simulacion < fin) { clientes.Add(new VectorCliente { Cliente = clienteLlegando, Cantidad = cantidadGrupo }); //agrego las columnas para el vector de estados del cliente Invoke(columnasInstance, numCliente); } if (mesas.Any(m => m.EstaLibre())) { var mesaLibre = mesas.First(m => m.EstaLibre()); mesaLibre.Ocupar(clienteLlegando, cantidadGrupo); mozo.LlegadaGrupo(relojActual, clienteLlegando, cantidadGrupo); if (simulacion < fin) { clientes.Last().Mesa = mesaLibre.Mesa.Nombre; } } else if (colaLocal.Cantidad() < colaMax) { colaLocal.AgregarCliente(clienteLlegando); } else { clienteLlegando.Salir(relojActual); perdidos += cantidadGrupo; } break; case "Fin Mozo": var clienteAtendido = mozo.FinAtencion(); var mesa = mesas.Single(m => clienteAtendido.Equals(m.Cliente)); if (clienteAtendido.Prioridad.Equals(1)) { var pedido = (int)menus.ObtenerValor(); var cantidadPedidos = mesa.Cantidad; clienteAtendido.CambiarPrioridad(pedido); cocina.LlegadaGrupo(relojActual, clienteAtendido, cantidadPedidos); if (simulacion < fin) { clientes.Single(c => c.Cliente.Equals(clienteAtendido)) .Menu = $"Menu {pedido}"; eventoActual += " (Carta)"; } } else { mesa.Mesa.LlegadaCliente(relojActual, clienteAtendido); eventoActual += " (Pedido)"; } break; case "Fin Cocina": var clienteConPedido = cocina.FinAtencion(); clienteConPedido.CambiarPrioridad(2); mozo.LlegadaCliente(relojActual, clienteConPedido); break; case "Fin Mesa 1": var clienteSaliendo1 = mesa1.FinAtencion(); clienteSaliendo1.Salir(relojActual); var cantidadAtendidos1 = mesas.Single(m => m.Mesa.Equals(mesa1)).Cantidad; atendidos += cantidadAtendidos1; for (var i = 0; i < cantidadAtendidos1; i++) { esperaPromedio = acumuladorEspera.CalcularSiguiente(clienteSaliendo1.TiempoEspera); } mesas.Single(m => m.Mesa.Equals(mesa1)).Liberar(); if (!colaLocal.Vacia()) { var clienteEsperando = colaLocal.ProximoCliente(); var cantidadEsperando = (int)grupos.ObtenerValor(); mesas.First(m => m.EstaLibre()).Ocupar(clienteEsperando, cantidadEsperando); mozo.LlegadaGrupo(relojActual, clienteEsperando, cantidadEsperando); } break; case "Fin Mesa 2": var clienteSaliendo2 = mesa2.FinAtencion(); clienteSaliendo2.Salir(relojActual); var cantidadAtendidos2 = mesas.Single(m => m.Mesa.Equals(mesa2)).Cantidad; atendidos += cantidadAtendidos2; for (var i = 0; i < cantidadAtendidos2; i++) { esperaPromedio = acumuladorEspera.CalcularSiguiente(clienteSaliendo2.TiempoEspera); } mesas.Single(m => m.Mesa.Equals(mesa2)).Liberar(); if (!colaLocal.Vacia()) { var clienteEsperando = colaLocal.ProximoCliente(); var cantidadEsperando = (int)grupos.ObtenerValor(); mesas.First(m => m.EstaLibre()).Ocupar(clienteEsperando, cantidadEsperando); mozo.LlegadaGrupo(relojActual, clienteEsperando, cantidadEsperando); } break; case "Fin Mesa 3": var clienteSaliendo3 = mesa3.FinAtencion(); clienteSaliendo3.Salir(relojActual); var cantidadAtendidos3 = mesas.Single(m => m.Mesa.Equals(mesa3)).Cantidad; atendidos += cantidadAtendidos3; for (var i = 0; i < cantidadAtendidos3; i++) { esperaPromedio = acumuladorEspera.CalcularSiguiente(clienteSaliendo3.TiempoEspera); } mesas.Single(m => m.Mesa.Equals(mesa3)).Liberar(); if (!colaLocal.Vacia()) { var clienteEsperando = colaLocal.ProximoCliente(); var cantidadEsperando = (int)grupos.ObtenerValor(); mesas.First(m => m.EstaLibre()).Ocupar(clienteEsperando, cantidadEsperando); mozo.LlegadaGrupo(relojActual, clienteEsperando, cantidadEsperando); } break; case "Fin Mesa 4": var clienteSaliendo4 = mesa4.FinAtencion(); clienteSaliendo4.Salir(relojActual); var cantidadAtendidos4 = mesas.Single(m => m.Mesa.Equals(mesa4)).Cantidad; atendidos += cantidadAtendidos4; for (var i = 0; i < cantidadAtendidos4; i++) { esperaPromedio = acumuladorEspera.CalcularSiguiente(clienteSaliendo4.TiempoEspera); } mesas.Single(m => m.Mesa.Equals(mesa4)).Liberar(); if (!colaLocal.Vacia()) { var clienteEsperando = colaLocal.ProximoCliente(); var cantidadEsperando = (int)grupos.ObtenerValor(); mesas.First(m => m.EstaLibre()).Ocupar(clienteEsperando, cantidadEsperando); mozo.LlegadaGrupo(relojActual, clienteEsperando, cantidadEsperando); } break; case "Fin Mesa 5": var clienteSaliendo5 = mesa5.FinAtencion(); clienteSaliendo5.Salir(relojActual); var cantidadAtendidos5 = mesas.Single(m => m.Mesa.Equals(mesa5)).Cantidad; atendidos += cantidadAtendidos5; for (var i = 0; i < cantidadAtendidos5; i++) { esperaPromedio = acumuladorEspera.CalcularSiguiente(clienteSaliendo5.TiempoEspera); } mesas.Single(m => m.Mesa.Equals(mesa5)).Liberar(); if (!colaLocal.Vacia()) { var clienteEsperando = colaLocal.ProximoCliente(); var cantidadEsperando = (int)grupos.ObtenerValor(); mesas.First(m => m.EstaLibre()).Ocupar(clienteEsperando, cantidadEsperando); mozo.LlegadaGrupo(relojActual, clienteEsperando, cantidadEsperando); } break; case "Fin Mesa 6": var clienteSaliendo6 = mesa6.FinAtencion(); clienteSaliendo6.Salir(relojActual); var cantidadAtendidos6 = mesas.Single(m => m.Mesa.Equals(mesa6)).Cantidad; atendidos += cantidadAtendidos6; for (var i = 0; i < cantidadAtendidos6; i++) { esperaPromedio = acumuladorEspera.CalcularSiguiente(clienteSaliendo6.TiempoEspera); } mesas.Single(m => m.Mesa.Equals(mesa6)).Liberar(); if (!colaLocal.Vacia()) { var clienteEsperando = colaLocal.ProximoCliente(); var cantidadEsperando = (int)grupos.ObtenerValor(); mesas.First(m => m.EstaLibre()).Ocupar(clienteEsperando, cantidadEsperando); mozo.LlegadaGrupo(relojActual, clienteEsperando, cantidadEsperando); } break; case "Fin Mesa 7": var clienteSaliendo7 = mesa7.FinAtencion(); clienteSaliendo7.Salir(relojActual); var cantidadAtendidos7 = mesas.Single(m => m.Mesa.Equals(mesa7)).Cantidad; atendidos += cantidadAtendidos7; for (var i = 0; i < cantidadAtendidos7; i++) { esperaPromedio = acumuladorEspera.CalcularSiguiente(clienteSaliendo7.TiempoEspera); } mesas.Single(m => m.Mesa.Equals(mesa7)).Liberar(); if (!colaLocal.Vacia()) { var clienteEsperando = colaLocal.ProximoCliente(); var cantidadEsperando = (int)grupos.ObtenerValor(); mesas.First(m => m.EstaLibre()).Ocupar(clienteEsperando, cantidadEsperando); mozo.LlegadaGrupo(relojActual, clienteEsperando, cantidadEsperando); } break; case "Fin Mesa 8": var clienteSaliendo8 = mesa8.FinAtencion(); clienteSaliendo8.Salir(relojActual); var cantidadAtendidos8 = mesas.Single(m => m.Mesa.Equals(mesa8)).Cantidad; atendidos += cantidadAtendidos8; for (var i = 0; i < cantidadAtendidos8; i++) { esperaPromedio = acumuladorEspera.CalcularSiguiente(clienteSaliendo8.TiempoEspera); } mesas.Single(m => m.Mesa.Equals(mesa8)).Liberar(); if (!colaLocal.Vacia()) { var clienteEsperando = colaLocal.ProximoCliente(); var cantidadEsperando = (int)grupos.ObtenerValor(); mesas.First(m => m.EstaLibre()).Ocupar(clienteEsperando, cantidadEsperando); mozo.LlegadaGrupo(relojActual, clienteEsperando, cantidadEsperando); } break; case "Fin Mesa 9": var clienteSaliendo9 = mesa9.FinAtencion(); clienteSaliendo9.Salir(relojActual); var cantidadAtendidos9 = mesas.Single(m => m.Mesa.Equals(mesa9)).Cantidad; atendidos += cantidadAtendidos9; for (var i = 0; i < cantidadAtendidos9; i++) { esperaPromedio = acumuladorEspera.CalcularSiguiente(clienteSaliendo9.TiempoEspera); } mesas.Single(m => m.Mesa.Equals(mesa9)).Liberar(); if (!colaLocal.Vacia()) { var clienteEsperando = colaLocal.ProximoCliente(); var cantidadEsperando = (int)grupos.ObtenerValor(); mesas.First(m => m.EstaLibre()).Ocupar(clienteEsperando, cantidadEsperando); mozo.LlegadaGrupo(relojActual, clienteEsperando, cantidadEsperando); } break; case "Fin Mesa 10": var clienteSaliendo10 = mesa10.FinAtencion(); clienteSaliendo10.Salir(relojActual); var cantidadAtendidos10 = mesas.Single(m => m.Mesa.Equals(mesa10)).Cantidad; atendidos += cantidadAtendidos10; for (var i = 0; i < cantidadAtendidos10; i++) { esperaPromedio = acumuladorEspera.CalcularSiguiente(clienteSaliendo10.TiempoEspera); } mesas.Single(m => m.Mesa.Equals(mesa10)).Liberar(); if (!colaLocal.Vacia()) { var clienteEsperando = colaLocal.ProximoCliente(); var cantidadEsperando = (int)grupos.ObtenerValor(); mesas.First(m => m.EstaLibre()).Ocupar(clienteEsperando, cantidadEsperando); mozo.LlegadaGrupo(relojActual, clienteEsperando, cantidadEsperando); } break; case "Cierre": local.Cerrar(); foreach (var cliente in colaLocal.Clientes) { var cantidadAfuera = (int)grupos.ObtenerValor(); cliente.Salir(relojActual); perdidos += cantidadAfuera; } colaLocal.Vaciar(); break; } //agrego la fila del evento actual if (simulacion >= inicio && simulacion <= fin) { Invoke(filaInstance, relojActual, eventoActual, local, colaLocal, colaMozo, mozo, colaCocina, cocina, mesas, atendidos, perdidos, esperaPromedio, clientes); } //cada 10 eventos actualizo el status if (simulacion % 10 == 0) { Invoke(statusInstance, relojActual, simulacion); } } //muestro los resultados Invoke(resultadosInstance, atendidos, perdidos, esperaPromedio); //dejo el formulario como estaba Invoke(inicioFinInstance, true); }
private void Simular() { var inicioFinInstance = new InicioFinDelegate(InicioFin); var columnasInstance = new ColumnasDelegate(AgregarColumnas); var filaInstance = new FilaDelegate(AgregarFila); var statusInstance = new StatusDelegate(ActualizarStatus); var resultadosInstance = new ResultadosDelegate(MostrarResultados); Invoke(inicioFinInstance, false); var recepcionA = double.Parse(txt_recepcion_a.Text); var recepcionB = double.Parse(txt_recepcion_b.Text); var distribucionRecepcion = new DistribucionUniforme(recepcionA, recepcionB); var colaRecepcion = new ColaFifo("Recepción"); var recepcion = new Servidor(distribucionRecepcion, colaRecepcion, "Recepción"); var balanzaA = double.Parse(txt_balanza_a.Text); var balanzaB = double.Parse(txt_balanza_b.Text); var distribucionBalanza = new DistribucionUniforme(balanzaA, balanzaB); var colaBalanza = new ColaFifo("Balanza"); var balanza = new Servidor(distribucionBalanza, colaBalanza, "Balanza"); var darsenasA = double.Parse(txt_darsenas_a.Text); var darsenasB = double.Parse(txt_darsenas_b.Text); var distribucionDarsenas = new DistribucionUniforme(darsenasA, darsenasB); var colaDarsenas = new ColaFifo("Dársenas"); var mediaRecalibracion = double.Parse(txt_recalibracion_media.Text); var varianzaRecalibracion = double.Parse(txt_recalibracion_varianza.Text); var distribucionRecalibracion = new DistribucionNormal(mediaRecalibracion, varianzaRecalibracion); var darsena1 = new Servidor(distribucionDarsenas, colaDarsenas, "Dársena 1", distribucionRecalibracion); var darsena2 = new Servidor(distribucionDarsenas, colaDarsenas, "Dársena 2", distribucionRecalibracion); IDistribucion distribucionLlegadas; var horaInicio = DateTime.Today.AddHours(5); var horaFin = DateTime.Today.AddHours(18); Llegada llegadas; if (rb_estrategia_a.Checked) { var lambda = double.Parse(txt_llegadas_lambda.Text); distribucionLlegadas = new DistribucionExponencialNegativa(lambda); llegadas = new Llegada(distribucionLlegadas, DateTime.Today.AddHours(12), horaFin); } else { distribucionLlegadas = new DistribucionUniforme(7, 8); llegadas = new Llegada(distribucionLlegadas, horaInicio, horaFin); } var dias = int.Parse(txt_dias.Text); var desde = int.Parse(txt_desde.Text); var hasta = int.Parse(txt_hasta.Text); decimal promedioAtendidos = 0; decimal promedioNoAtendidos = 0; decimal promedioPermanencia = 0; var afuera = new List <Cliente>(); var simulacion = 0; var numCamion = 0; var clientes = new List <Cliente>(); _cancelar = false; for (var dia = 1; dia <= dias; dia++) { if (_cancelar) { break; } var atendidos = 0; var noAtendidos = 0; decimal permanenciaDiaria = 0; llegadas.Abrir(); while (llegadas.EstaAbierto() || !recepcion.EstaLibre() || !balanza.EstaLibre() || !darsena1.EstaLibre() || !darsena2.EstaLibre()) { if (_cancelar) { break; } simulacion++; if (llegadas.EstaAbierto() && afuera.Count > 0) { foreach (var cliente in afuera) { if (_cancelar) { break; } cliente.Llegar(horaInicio); recepcion.LlegadaCliente(horaInicio, cliente); } afuera = new List <Cliente>(); } var eventos = new List <Evento> { new Evento("Llegada", llegadas.ProximaLlegada), new Evento("Cierre", llegadas.Cierre), new Evento("Fin Recepción", recepcion.ProximoFinAtencion), new Evento("Fin Balanza", balanza.ProximoFinAtencion), new Evento("Fin Dársena 1", darsena1.ProximoFinAtencion), new Evento("Fin Dársena 2", darsena2.ProximoFinAtencion) }; // ReSharper disable once PossibleInvalidOperationException var relojActual = eventos.Where(ev => ev.Hora.HasValue).Min(ev => ev.Hora).Value; var eventoActual = eventos.First(ev => ev.Hora.Equals(relojActual)).Nombre; switch (eventoActual) { case "Llegada": numCamion++; var clienteLlegando = new Cliente($"Camión {numCamion}"); clienteLlegando.Llegar(relojActual); recepcion.LlegadaCliente(relojActual, clienteLlegando); llegadas.ActualizarLlegada(); if (simulacion <= hasta) { clientes.Add(clienteLlegando); Invoke(columnasInstance, numCamion); } break; case "Fin Recepción": var clienteReceptado = recepcion.FinAtencion(); balanza.LlegadaCliente(relojActual, clienteReceptado); break; case "Fin Balanza": var clientePesado = balanza.FinAtencion(); if (darsena1.EstaLibre()) { darsena1.LlegadaCliente(relojActual, clientePesado); } else { darsena2.LlegadaCliente(relojActual, clientePesado); } break; case "Fin Dársena 1": var clienteSaliendo1 = darsena1.FinAtencion(); if (clienteSaliendo1 != null) { clienteSaliendo1.Salir(relojActual); permanenciaDiaria = (permanenciaDiaria * atendidos + clienteSaliendo1.TiempoEnSistema) / (atendidos + 1); atendidos++; } break; case "Fin Dársena 2": var clienteSaliendo2 = darsena2.FinAtencion(); if (clienteSaliendo2 != null) { clienteSaliendo2.Salir(relojActual); permanenciaDiaria = (permanenciaDiaria * atendidos + clienteSaliendo2.TiempoEnSistema) / (atendidos + 1); atendidos++; } break; case "Cierre": llegadas.Cerrar(); noAtendidos = colaRecepcion.Cantidad(); afuera.AddRange(colaRecepcion.Clientes); colaRecepcion.Vaciar(); promedioNoAtendidos = (promedioNoAtendidos * (dia - 1) + noAtendidos) / dia; break; } if (simulacion % 10 == 0) { Invoke(statusInstance, dia, relojActual, simulacion); } if (simulacion >= desde && simulacion <= hasta) { Invoke(filaInstance, relojActual, eventoActual, llegadas, colaRecepcion, recepcion, colaBalanza, balanza, colaDarsenas, darsena1, darsena2, atendidos, noAtendidos, permanenciaDiaria, clientes); } } var permanenciaAnterior = promedioPermanencia * promedioAtendidos * (dia - 1); promedioAtendidos = (promedioAtendidos * (dia - 1) + atendidos) / dia; promedioNoAtendidos = (promedioNoAtendidos * (dia - 1) + noAtendidos) / dia; promedioPermanencia = (permanenciaAnterior + permanenciaDiaria * atendidos) / (promedioAtendidos * dia); } Invoke(resultadosInstance, promedioAtendidos, promedioNoAtendidos, promedioPermanencia); Invoke(inicioFinInstance, true); var resultado = _cancelar ? "interrumpida" : "completa"; MessageBox.Show($@"Simulación {resultado}", @"Resultado"); }