Example #1
0
        public void ObtenerTiempoLlegadaProximoCliente(long tiempo)
        {
            DistribucionExponencialNegativa distribucionExponencialNegativa = new DistribucionExponencialNegativa(condicionesIniciales.condicionesCliente.lamdaLlegada);
            var t = (double)(distribucionExponencialNegativa.ObtenerVariableAleatoria());

            tiempoLlegadaProximoCliente  = (long)t;
            tiempoLlegadaProximoCliente += tiempo;
        }
        public void ObtenerTiempoLlegadaProximoAlumno(int tiempo)
        {
            double lambda = 1.0 / (condicionesIniciales.MediaLlegadaAlumno);
            //double lambda = 1.0 / 2.0;
            DistribucionExponencialNegativa distribucion = new DistribucionExponencialNegativa(lambda);

            tiempoLlegadaProximoAlumno  = (int)(distribucion.ObtenerVariableAleatoria());
            tiempoLlegadaProximoAlumno += tiempo;
        }
Example #3
0
        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);

            //manejo de llegadas
            var horaInicio = DateTime.Today.AddHours(8);
            var horaFin    = DateTime.Today.AddHours(18);
            var media      = double.Parse(txt_llegadas_media.Text);
            //media = media / 24;
            //media = media / 60;
            var           lambda = 1 / media;
            IDistribucion distribucionLlegadas = new DistribucionExponencialNegativa(lambda);
            Llegada       llegadas             = new Llegada(distribucionLlegadas, horaInicio, horaFin);

            //manejo de Quitado de Alfombras
            DateTime tiempoQA         = DateTime.Parse(txt_tiempoQA.Text);
            var      colaQA           = new ColaFifo("Quitado de Alfombra");
            var      quitadoAlfombras = new Servidor(tiempoQA, colaQA, "Quitado de Alfombra", false, true);

            //manejo de Aspirado
            var generadorCongMixto   = new CongruencialMixto(1000, 12, 17, 5000);
            var aspirado_a           = double.Parse(txt_aspirado_a.Text);
            var aspirado_b           = double.Parse(txt_aspirado_b.Text);
            var distribucionAspirado = new DistribucionUniforme(aspirado_a, aspirado_b, generadorCongMixto);
            var colaAspirado         = new ColaFifo("Aspirado");
            var aspirado             = new Servidor(distribucionAspirado, colaAspirado, "Aspirado", false, false);

            //manejo de Lavado

            var lavado_a           = double.Parse(txt_lavado_a.Text);
            var lavado_b           = double.Parse(txt_lavado_b.Text);
            var distribucionLavado = new DistribucionUniforme(lavado_a, lavado_b, generadorCongMixto);
            //var distribucionLavado = new DistribucionUniforme(lavado_a, lavado_b);
            var colaLS    = new ColaFifo("Lavadero");
            var lavadero1 = new Servidor(distribucionLavado, colaLS, "Lavadero 1", false, false);
            var lavadero2 = new Servidor(distribucionLavado, colaLS, "Lavadero 2", false, false);

            //manejo de secado

            var secadora = new Servidor("Secadora", true, false);

            //manejo de puesta de alfombra
            DateTime tiempoPA      = DateTime.Parse(txt_puesta_alfombras.Text);
            var      colaPA        = new ColaFifo("Puesta de Alfombra");
            var      ponerAlfombra = new Servidor(tiempoPA, colaPA, "Puesta de Alfombra", false, true);


            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 promedioPermanencia = 0;

            var simulacion = 0;
            var numAutos   = 0;
            var clientes   = new List <Cliente>();
            int colaMax    = 0;
            var atendidos  = 0;

            _cancelar = false;
            for (var dia = 1; dia <= dias; dia++)
            {
                if (_cancelar == true)
                {
                    break;
                }


                decimal permanenciaDiaria = 0;
                llegadas.Abrir();

                while (llegadas.EstaAbierto() ||
                       !quitadoAlfombras.EstaLibre() ||
                       !aspirado.EstaLibre() ||
                       !aspirado.EstaLibre() ||
                       !secadora.EstaLibre() ||
                       !lavadero1.EstaLibre() ||
                       !lavadero2.EstaLibre() ||
                       !ponerAlfombra.EstaLibre())
                {
                    if (_cancelar)
                    {
                        break;
                    }

                    simulacion++;


                    var eventos = new List <Evento>
                    {
                        new Evento("Llegada", llegadas.ProximaLlegada),
                        new Evento("Cierre", llegadas.Cierre),
                        new Evento("Fin de Quitado de Alfombras", quitadoAlfombras.ProximoFinAtencion),
                        new Evento("Fin de Aspirado", aspirado.ProximoFinAtencion),
                        new Evento("Fin de Secado", secadora.ProximoFinAtencion),
                        new Evento("Fin de Lavadero 1", lavadero1.ProximoFinAtencion),
                        new Evento("Fin de Lavadero 2", lavadero2.ProximoFinAtencion),
                        new Evento("Fin Puesta de alfombras", ponerAlfombra.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":
                        numAutos++;
                        String tipoAuto         = ObtenerTipo();
                        var    alfombraLlegando = new Alfombra($"Alfombra de Auto {numAutos}");
                        var    clienteLlegando  = new Cliente($"Auto {numAutos}", tipoAuto, alfombraLlegando);
                        clienteLlegando.Llegar(relojActual);
                        quitadoAlfombras.LlegadaCliente(relojActual, clienteLlegando);
                        llegadas.ActualizarLlegada(1);
                        if (simulacion <= hasta)
                        {
                            clientes.Add(clienteLlegando);

                            Invoke(columnasInstance, numAutos);
                        }
                        break;

                    case "Fin de Quitado de Alfombras":
                        var clienteSinAlfombra = quitadoAlfombras.FinAtencion();
                        aspirado.LlegadaCliente(relojActual, clienteSinAlfombra);
                        if (lavadero1.EstaLibre())
                        {
                            lavadero1.LlegadaCliente(relojActual, clienteSinAlfombra);
                        }
                        else
                        {
                            lavadero2.LlegadaCliente(relojActual, clienteSinAlfombra);
                        }

                        break;

                    case "Fin de Aspirado":
                        var clienteAspirado = aspirado.FinAtencion();
                        if (clienteAspirado.Humedad <= 1)
                        {
                            ponerAlfombra.LlegadaCliente(relojActual, clienteAspirado);
                        }
                        break;

                    case "Fin de Lavadero 1":
                        if (lavadero1.ClienteActual.Humedad < 1)
                        {
                            var clienteSeco = lavadero1.FinAtencion();
                            ponerAlfombra.LlegadaCliente(relojActual, clienteSeco);
                        }
                        else
                        {
                            if (secadora.EstaLibre())
                            {
                                var clienteLavado1 = lavadero1.FinAtencion();
                                secadora.LlegadaCliente(relojActual, clienteLavado1);
                            }
                            else
                            {
                                lavadero1.cambiarEstado("Bloqueado");
                                lavadero1.ComenzarSecado(relojActual);
                            }
                        }


                        break;

                    case "Fin de Lavadero 2":
                        if (lavadero2.ClienteActual.Humedad < 1)
                        {
                            var clienteSeco = lavadero2.FinAtencion();
                            ponerAlfombra.LlegadaCliente(relojActual, clienteSeco);
                        }
                        else
                        {
                            if (secadora.EstaLibre())
                            {
                                var clienteLavado2 = lavadero2.FinAtencion();
                                secadora.LlegadaCliente(relojActual, clienteLavado2);
                            }
                            else
                            {
                                lavadero2.cambiarEstado("Bloqueado");
                                lavadero2.ComenzarSecado(relojActual);
                            }
                        }
                        break;

                    case "Fin de Secado":
                        Cliente clienteASecado = null;
                        Cliente clienteSecado  = secadora.FinAtencion();
                        if (lavadero1.EstaBloqueado() & lavadero2.EstaBloqueado())
                        {
                            clienteASecado = lavadero1.ClienteActual;
                            clienteASecado.CalcularSecado(relojActual);
                            lavadero1.cambiarEstado("Libre");
                            lavadero1.FinAtencion();
                            secadora.LlegadaCliente(relojActual, clienteASecado);
                        }
                        else
                        {
                            if (lavadero1.EstaBloqueado())
                            {
                                clienteASecado = lavadero1.ClienteActual;
                                clienteASecado.CalcularSecado(relojActual);
                                lavadero1.cambiarEstado("Libre");
                                lavadero1.FinAtencion();
                                secadora.LlegadaCliente(relojActual, clienteASecado);
                            }
                            else
                            {
                                if (lavadero2.EstaBloqueado())
                                {
                                    clienteASecado = lavadero2.ClienteActual;
                                    clienteASecado.CalcularSecado(relojActual);
                                    lavadero2.cambiarEstado("Libre");
                                    lavadero2.FinAtencion();
                                    secadora.LlegadaCliente(relojActual, clienteASecado);
                                }
                            }
                        }

                        ponerAlfombra.LlegadaCliente(relojActual, clienteSecado);

                        break;

                    case "Fin Puesta de alfombras":

                        var clienteSaliendo = ponerAlfombra.FinAtencion();
                        if (clienteSaliendo != null)
                        {
                            clienteSaliendo.Salir(relojActual);
                            permanenciaDiaria = (permanenciaDiaria * atendidos + clienteSaliendo.TiempoEnSistema) / (atendidos + 1);
                            atendidos++;
                        }
                        break;

                    case "Cierre":
                        llegadas.Cerrar();
                        colaQA.Vaciar();
                        break;
                    }

                    colaMax = quitadoAlfombras.MaxCola;
                    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, colaQA, quitadoAlfombras, colaAspirado,
                               aspirado, colaLS, lavadero1, lavadero2, secadora, colaPA, ponerAlfombra, atendidos, permanenciaDiaria, clientes);
                    }
                }

                var permanenciaAnterior = promedioPermanencia * promedioAtendidos * (dia - 1);
                promedioAtendidos = (promedioAtendidos * (dia - 1) + atendidos) / dia;


                if (promedioAtendidos != 0)
                {
                    promedioPermanencia = (permanenciaAnterior + permanenciaDiaria * atendidos) / (promedioAtendidos * dia);
                }
            }

            Invoke(resultadosInstance, promedioAtendidos, promedioPermanencia, colaMax, atendidos);
            Invoke(inicioFinInstance, true);
            var resultado = _cancelar ? "interrumpida" : "completa";

            MessageBox.Show($@"Simulación {resultado}", @"Resultado");
        }
        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");
        }
Example #5
0
        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");
        }