A figura abaixo ilustra um cenário que foi mapeado para um simulador computacional.
Os retângulos representam os blocos estáticos: um bloco de entrada, um bloco que é o balcão de atendimento e um bloco de saída. Um modelo de simulação tem dois blocos especiais que são os BlocoChegada (quando uma entidade chega no modelo) e o BlocoSaida (quando a entidade deixa o modelo).
No exemplo da figura, a pessoa que será atendida é uma entidade. Ela é criada no BlocoChegada em uma periodicidade que deve ser programada: as pessoas podem chegar, por exemplo, com um intervalo de tempo fixado, aleatório, conforme um distribuição normal ou qualquer outra forma que for adequada para simular o cenário.
Um simulador é uma aplicação single-thread. O algoritmo principal de um simulador consiste no seguinte pseudocódigo:
relogioSimulação = 0.0;
enquanto (listaEventosFuturos.tamanho() > 0) {
evento = listaEventosFuturos.getProximo();
relogioSimulação = evento.getHorario();
evento.executar();
}
// fim da simulação
Os blocos têm dois possíveis eventos associados: um de chegada (a entidade está chegando àquele bloco) ou de saída (a entidade está deixando o bloco). Sempre que um evento ocorre, outro evento deve ser criado e agendado para ser executado em alguma iteração futura do simulador.
Observe que a simulação só ocorre enquanto há eventos na lista de eventos futuros. Esta condição é imprescindível para que a simulação continue acontecendo.
Nota: você pode examinar o código-fonte no pacote
atendimentopara acompanhar as explicações que seguem.
O código-fonte está incluído com o simulador, que pode ser baixado aqui.
As linhas abaixo foram produzidas pela execução do exemplo do balcão de atendimento.
0.0: Pessoa(1) passou na porta e está indo para o balcão.
0.0: Pessoa(1) chegou direto ao balcão, sem fila.
11.0: Pessoa(2) passou na porta e está indo para o balcão.
11.0: Pessoa(2) foi colocada na fila de espera.
12.0: Pessoa(1) está deixando o balcão e indo para a saída.
12.0: Pessoa(2) está saindo da fila para ir ao balcão. Esperou 1.0 segundo(s).
12.0: Pessoa(1) chegou na porta de saída.
12.0: Pessoa(2) chegou direto ao balcão, sem fila.
18.0: Pessoa(3) passou na porta e está indo para o balcão.
18.0: Pessoa(3) foi colocada na fila de espera.
21.0: Pessoa(2) está deixando o balcão e indo para a saída.
21.0: Pessoa(3) está saindo da fila para ir ao balcão. Esperou 3.0 segundo(s).
21.0: Pessoa(2) chegou na porta de saída.
21.0: Pessoa(3) chegou direto ao balcão, sem fila.
25.0: Pessoa(4) passou na porta e está indo para o balcão.
25.0: Pessoa(4) foi colocada na fila de espera.
30.0: Pessoa(5) passou na porta e está indo para o balcão.
30.0: Pessoa(5) foi colocada na fila de espera.
43.0: Pessoa(3) está deixando o balcão e indo para a saída.
43.0: Pessoa(4) está saindo da fila para ir ao balcão. Esperou 18.0 segundo(s).
43.0: Pessoa(3) chegou na porta de saída.
43.0: Pessoa(4) chegou direto ao balcão, sem fila.
61.0: Pessoa(4) está deixando o balcão e indo para a saída.
61.0: Pessoa(5) está saindo da fila para ir ao balcão. Esperou 31.0 segundo(s).
61.0: Pessoa(4) chegou na porta de saída.
61.0: Pessoa(5) chegou direto ao balcão, sem fila.
70.0: Pessoa(5) está deixando o balcão e indo para a saída.
70.0: Pessoa(5) chegou na porta de saída.
As pessoas esperaram um total de 53 segundos.
O tempo médio de espera na fila foi de 13.25 segundos.
O número à esquerda é o relógio de simulação, em segundos. Ele mostra em que momento um certo evento ocorreu. Em seguida, o número da pessoa, para sabermos de quem se trata. E, por fim, a mensagem descrevendo o que ocorreu.
As duas últimas linhas mostram como se pode sumarizar informações estatísticas para serem analisadas após a simulação.
Agora vamos ao código-fonte.
// (1) instancia o simulador novo.
Simulador sim = new Simulador();
// (2) instancia o ponto de chegada das pessoas
PortaEntrada entrada = new PortaEntrada(sim);
BalcaoAtendimento balcao = new BalcaoAtendimento(sim);
PortaSaida saida = new PortaSaida(sim);
// (3) referências
entrada.setBalcaoAtendimento(balcao);
balcao.setPortaSaida(saida);
// (4) executa a simulação.
sim.executaSimulador();
Eis o que é feito: (1) instancia-se o simulador, vazio. Ele não tem nenhuma referência a nada. (2) Instancia-se os três blocos estáticos, PortaEntrada, BalcaoAtendimento e PortaSaida. (3) passamos a alguns blocos referências para os blocos seguintes, na seqüência em que se deslocam as entidades no modelo. (4) executa-se o simulador.
No momento em que PortaEntrada é instanciada, o construtor já cria o evento inicial de saída deste bloco. Confirme explicado, este evento é necessário para que a simulação seja iniciada.
--fim--
Conrado Vardanega - contato