46
Sim˜ ao: Rotinas de Simula¸ c˜aoDiscreta Clovis Perin

Sim~ao: Rotinas de Simula˘c~ao Discretaclovis/simao/simao.pdf · Esta vers~ao do pacote considera os seguintes tipos de estruturas para as vari aveis: entity, attribute, ... queue

Embed Size (px)

Citation preview

Simao:Rotinas de Simulacao Discreta

Clovis Perin

Conteudo

1 Introducao 31.1 Modelagem . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2 Exemplos 72.1 Fila com 1 servidor . . . . . . . . . . . . . . . . . . . . . . . . 72.2 Fone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82.3 Pub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

3 Simao em C 123.1 Estruturas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123.2 Rotinas de amostragem . . . . . . . . . . . . . . . . . . . . . . 123.3 Rotinas de manipulacao de entidades . . . . . . . . . . . . . . 143.4 Rotinas de manipulacao de filas . . . . . . . . . . . . . . . . . 143.5 Rotinas de controle . . . . . . . . . . . . . . . . . . . . . . . . 153.6 Rotinas de histogramas . . . . . . . . . . . . . . . . . . . . . . 163.7 Rotinas de estatısticas . . . . . . . . . . . . . . . . . . . . . . 163.8 Rotinas de reinicializacao . . . . . . . . . . . . . . . . . . . . . 173.9 Exemplo: fila com 1 servidor . . . . . . . . . . . . . . . . . . . 17

4 Simao em Pascal 234.1 Estruturas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234.2 Rotinas de amostragem . . . . . . . . . . . . . . . . . . . . . . 234.3 Rotinas de manipulacao de entidades . . . . . . . . . . . . . . 254.4 Rotinas de manipulacao de filas . . . . . . . . . . . . . . . . . 254.5 Rotinas de controle . . . . . . . . . . . . . . . . . . . . . . . . 254.6 Rotinas de histogramas . . . . . . . . . . . . . . . . . . . . . . 264.7 Rotinas de estatısticas . . . . . . . . . . . . . . . . . . . . . . 264.8 Rotinas de reinicializacao . . . . . . . . . . . . . . . . . . . . . 27

1

4.9 Rotinas para relatorios . . . . . . . . . . . . . . . . . . . . . . 274.10 Rotinas de informacao . . . . . . . . . . . . . . . . . . . . . . 284.11 Exemplo: fila com 1 servidor . . . . . . . . . . . . . . . . . . . 29

5 Simao em Matlab 335.1 Rotinas de amostragem . . . . . . . . . . . . . . . . . . . . . . 335.2 Rotinas de manipulacao de entidades . . . . . . . . . . . . . . 345.3 Rotinas de manipulacao de filas . . . . . . . . . . . . . . . . . 355.4 Rotinas de controle . . . . . . . . . . . . . . . . . . . . . . . . 355.5 Rotinas de estatısticas . . . . . . . . . . . . . . . . . . . . . . 365.6 Rotinas de reinicializacao . . . . . . . . . . . . . . . . . . . . . 375.7 Exemplo: fila com 1 servidor . . . . . . . . . . . . . . . . . . . 37

2

Capıtulo 1

Introducao

O pacote Simao tem por objetivo auxiliar o desenvolvimento de programaspara realizar simulacao de sistemas discretos. Esse pacote foi desenvolvidopelo Laboratorio de Matematica Aplicada (Labma) da Universidade Estadualde Campinas (Unicamp). Consiste de um conjunto de rotinas com versoesem Pascal, C e Matlab, http://www.ime.unicamp.br/~clovis/simao, etem objetivos academicos.

1.1 Modelagem

Considere que ha um processo conhecido de chegadas de clientes a uma es-tacao de atendimento com um unico servidor cujo processo de atendimentotem distribuicao conhecida. Considere que os clientes que ao chegar encon-tram o servidor ocupado posicionam-se no fim de uma fila. Suponha que oservidor utiliza a disciplina de atendimento primeiro a chegar primeiro a seratendido (FIFO) que e mantida com auxılio desta fila.

- - --

����

chegada

��

��fila servico ��

��partida�

���caixa ocioso

Figura 1.1: Diagrama de Fluxo das Entidades

3

Suponha a existencia de um problema a ser resolvido com o uso de si-mulacao discreta. Este problema esta associado a um sistema (e.g., unidadede atendimento de clientes) e deve ser representado atraves de um modeloque, neste caso, e um programa de computador. Este modelo e formado porcomponentes cujas atividades (e.g., atendimento) sao desenvolvidas por enti-dades (e.g., clientes, servidores); frequentemente entidades sao posicionadasem filas, linhas de espera ou listas. As atividades tem inıcio e fim marcadospor eventos (e.g., termino de atendimento) durante os quais o estado do sis-tema (e.g., numero de clientes) se altera. O acompanhamento da simulacaopermite que sejam feitas avaliacoes (e.g., tempo de espera dos clientes) sobreuma solucao ou cenario em estudo (e.g., numero de servidores). As entidadespodem ter atributos que as diferenciam entre si e que sao importantes parao desenvolvimento da simulacao.

Sistema e um conjunto estruturado de componentes que interagem demodo regular entre si e com o meio ambiente, satisfazendo a certas restricoesambientais, para atingir determinados objetivos.

Componentes sao subsistemas importantes que interagem entre si trocan-do e processando recursos. Cada um desenvolve a sua atividade absorvendocertos recursos, processando-os, transformando-os e liberando-os posterior-mente. O nıvel em que cada uma dessas atividades e desenvolvida defineuma variavel do sistema.

Entidades sao recursos importantes que representam produtos, materias-primas, dinheiro etc. As entidades podem ser temporarias ou permanentes.Uma entidade permanente existe durante todo o tempo em que o sistemase encontra sob observacao (exemplo, servidor de uma unidade de atendi-mento). Uma entidade temporaria existe apenas durante parte do tempo deobservacao do sistema; e criada e posteriormente destruıda.

Quando diversas entidades possuem as mesmas caracterısticas, elas for-mam uma classe de entidades. As entidades de uma mesma classe apre-sentam caracterısticas proprias que as diferenciam de outras classes. Taiscaracterısticas recebem o nome de atributos. Por exemplo, a distribuicao dotempo de atendimento pode ser um atributo dos servidores da mesma manei-ra que o tipo de servico solicitado individualmente pelos clientes caracterizaos clientes. Cada entidade possui um valor para cada um dos atributos daclasse a que pertence, o qual pode eventualmente ser modificado durante asimulacao. Entidades podem ser alinhadas em filas.

O estado do sistema, em cada instante de tempo, e formado pelos valorestomados pelas variaveis de estado do sistema. Uma variavel de estado pode

4

ser o nıvel de funcionamento da atividade de um componente ou o atributo deuma entidade. As variaveis de estado devem ser criteriosamente escolhidas,pois e com base nos valores tomados por essas variaveis que se avalia odesempenho do modelo. Tambem a realizacao da simulacao e feita com basenessas variaveis.

Mudancas no estado do sistema podem ser suaves (e contınuas) ou brus-cas (e instantaneas). Uma alteracao brusca no estado do sistema indica aocorrencia de um evento; por exemplo, a chegada de um cliente, pois ela causaum salto unitario no numero de clientes no sistema (variavel de estado). Mu-dancas suaves ocorrem devido ao desenvolvimento das atividades associadasaos componentes do sistema; por exemplo, o atendimento de um cliente. Nes-te texto sao considerados modelos discretos onde ocorrem mudancas bruscasno estado do sistema e que ocorrem em um conjunto enumeravel de instantesde tempo associados a eventos.

Parte do trabalho de modelagem do sistema pode ser facilitada com o usode diagramas de atividades do sistema, que permitem uma visualizacao decomo o sistema trabalha. Em tais diagramas de atividades, cada componentedo sistema que desenvolve uma atividade e representado por um retangulose e uma atividade do tipo ativa (exemplo, atendimento) ou por uma ovalse e do tipo passiva (exemplo, espera na fila). O tempo de realizacao deuma atividade ativa e conhecido ou pelo menos e gerado a partir de suadistribuicao de probabilidade que e supostamente conhecida. As atividadespassivas, em geral, representam filas ou linhas de espera e o seu tempo derealizacao nao e conhecido; alias, muitas vezes, um dos objetivos da simulacaoe justamente determinar a distribuicao de probabilidades do tempo de fila.O diagrama apresenta para cada classe de entidades a sequencia em que assuas atividades sao desenvolvidas por meio de vetores. Para as classes deentidades permanentes essas sequencias formam ciclos fechados e para asclasses de entidades temporarias essas sequencias formam caminhos de umponto de geracao ou criacao das entidades para um ponto de eliminacao oudestruicao das entidades da classe.

Esta versao do pacote considera os seguintes tipos de estruturas para asvariaveis: entity, attribute, queue, event, statistic, histogram e distribution.

5

Tipo Estrutura

entity entidadeattribute atributo de entidade

queue lista ou fila de entidadesevent tipo de evento

statistic estatısticahistogram histograma

distribution distribuicao de probabilidade

Tabela 1.1: Tipos definidos no Simao

6

Capıtulo 2

Exemplos

2.1 Fila com 1 servidor

Trata-se de um modelo bastante simples que serve como um bom exemplodevido a sua pequena complexidade.

Considere que ha um processo conhecido de chegadas de clientes a umaestacao de atendimento com um unico servidor cujo processo de atendimentotem distribuicao conhecida. Considere que os clientes que ao chegar encon-tram o servidor ocupado posicionam-se no fim de uma fila. Suponha que oservidor utiliza a disciplina de atendimento primeiro a chegar primeiro a seratendido (FIFO) que e mantida com auxılio desta fila.

- u u u uFILA ATENDIMENTO

-

Figura 2.1: Fila com 1 servidor

Neste caso, e natural considerar o modelo composto por

• uma classe de entidades temporarias de clientes,

• uma classe de entidades permanentes de atendentes com uma unicaentidade caixa,

7

• uma linha de espera fila,

• um tipo de evento chegada uma vez que supoe-se conhecida a distri-buicao dos intervalos entre chegadas e

• um tipo de evento servico para marcar os terminos de atendimentocuja duracao tem distribuicao supostamente conhecida.

2.2 Fone

Trata-se de um exemplo apresentado no livro do Gordon, System Simulation.

1 2 3 4 5 6 7 8

u uu u

Figura 2.2: Cabos & fones

Conisdere um conjunto de n telefones que podem conectar-se aos paresatraves de m cabos. Supoe-se conhecida a distribuicao da duracao das li-gacoes e a distribuicao dos intervalos entre tentativas de ligacoes. Considereque cada tentativa de ligacao e feita a partir de um telefone livre e se destinaa um outro telefone. Cada tentativa de ligacao pode concretizar-se ou naodependendo da disponibilidade de cabos (cada cabo pode conectar apenasum par de telefones distintos) e da condicao de ocupado ou nao do telefonechamado. Deseja-se contabilizar o numero total de tentativas de ligacao emum dado tempo de estudo, o numero de tentativas de ligacoes bloqueadas porfalta de cabos, o numero de tentativas de ligacoes nao efetuadas por causade chamadas ocupadas e o numero de ligacoes completadas.

Neste caso, e natural considerar o modelo composto por:

• uma classe de entidades permanentes com n telefones.

• uma classe de entidades permanentes com m cabos,

• um tipo de evento de tentativa de chamada uma vez que supoe-seconhecida a distribuicao dos intervalos entre chamadas e

8

Relogio

Prox. Chamada

Chamadas

3 7 23

blqd ocpd cnct

Linhas

0 1 0 0 1 0 1 1 0 0

Ligacoes

2 7

8 5

- - -

Figura 2.3: Modelo telefonico

• um tipo de evento termino de ligacao (ligacao) pois supoe-se conhecidaa distribuicao da duracao das ligacoes.

Observacao: uma tentativa de ligacao e feita a partir de um telefone livregerado aleatoriamente para um telefone distinto gerado aleatoriamente.

2.3 Pub

Trata-se de um exemplo proposto no pacote ELSE.Clientes que chegam a um bar para tomar cerveja posicionam-se no fim

de um linha de espera. Garcons desempenham as atividades de servir cer-veja e de lavar copos sujos. Copos limpos sao utilizados pelos garcons paraservir cerveja aos clientes e sao utilizados por estes enquanto desempenhama atividade de beber cerveja apos o que sao encaminhados para uma fila decopos sujos. Copos sujos sao lavados por garcons em uma unica pia apos oque sao encaminhados para um fila de copos limpos. A atividade de servirso e realizada quando ha simultaneamente um cliente esperando, um copolimpo e um garcom disponıvel. A atividade de beber e realizada logo apos ade servir mas somente por um par de entidades cliente e copo. A atividadelavar e executada somente quando ha um copo sujo e um garcom disponıvel.

9

@@��

#"

!Esperar

Servir Beber

��

@@

@@

��

��@@

#"

!Garcons

#"

!Cp.Limpos

#"

!Cp.SujosLavar

?

- - 6

6

- -

���

-

-

- pia

Figura 2.4: Modelo do Pub

Apos beber, o cliente decide sair do bar com probabilidade p e com proba-bilidade 1 − p decide tomar outra cerveja. neste caso ele e inserido logo noinıcio da linha de espera. Assim, e natural considerar o modelo compostopor:

• uma classe de entidades temporarias de clientes.

• uma classe de entidades permanentes com m garcons.

• uma classe de entidades permanentes com n copos.

• uma entidade permanente de classe pia.

• uma fila de clientes para serem servidos.

• uma fila de garcons disponıveis para servir ou lavar

• uma fila de copos limpos

• uma fila de copos sujos

• um tipo de evento chegada uma vez que supoe-se conhecida a distri-buicao dos intervalos entre chegadas

10

• um tipo de evento termino de servir pois supoe-se conhecida a distri-buicao do tempo de servir

• um tipo de evento termino de beber pois supoe-se conhecida a distri-buicao do tempo de beber

• um tipo de evento termino de lavar pois supoe-se conhecida a distri-buicao do tempo de lavar

Observacoes.

1. Esta sendo considerado o metodo das tres fases uma vez que ha ativida-des que sao desenvolvidas por tres entidades complicando a codificacaodos testes de inıcio de atividades. Assim, eles sao codificados umaunica vez e e dada uma prioridade para os garcons servirem clientesem detrimento a lavagem de copos

2. Utiliza a insercao de clientes ora no inıcio ora no fim da fila

3. Uma unica pia garante que so um garcom pode lavar copos em dadoinstante qualquer

11

Capıtulo 3

Simao em C

3.1 Estruturas

A versao deste pacote em C considera os seguintes tipos de estruturas paraas variaveis:

entity

attribute

queue

event

histogram

statistic

distribution

3.2 Rotinas de amostragem

Essas rotinas permitem a geracao de valores de variaveis aleatorias com distri-buicao preestabelecida. O parametro θ e uma variavel inteira positiva (long),sempre passada por referencia ou nome), que implicitamente e alterado parapermitir o calculo do valor desejado de modo automatico.

12

float aleat ( long * θ )Retorna um numero aleatorio; isto e, o valor de uma variavel aleatoria comdistribuicao uniforme no intervalo (0, 1). A semente θ e atualizada a cadachamada.

float uniform ( real a, b, long * θ )Retorna um valor com distribuicao uniforme no intervalo (a, b).

int random ( int a, b, long * θ )Retorna qualquer um dos valores inteiros de a..b com a mesma probabilidade.

int bernoulli ( float p, long * θ )Retorna um valor dentre 1=true e 0=false com distribuicao de Bernoullicom probabilidade p.

int geometric ( float p, long * θ )Retorna um valor com distribuicao geometrica com probabilidade p.

float triangular ( float a, b, c, long * θ )Retorna um valor com distribuicao triangular no intervalo (a, c) com modaem b.

float negexp ( float µ, long * θ )Retorna um valor com distribuicao exponencial negativa com esperanca µ.

float erlang ( float µ, int n, long * θ )Retorna um valor com distribuicao Erlang com n fases e esperanca µ.

float poisson ( float µ, long * θ )Retorna um valor com distribuicao de Poisson com esperanca µ.

float weibull ( float ρ, long * θ )Retorna um valor com distribuicao de Weibull com parametros ρ, 1.

float normal ( float µ, σ, long * θ )Retorna um valor com distribuicao normal com esperanca µ e desvio padraoσ.

float sample ( distribution D, long * θ )Retorna um valor com distribuicao pre-definida por D.

distribution newdist ( vector x, y, int n )Retorna a referencia da distribuicao criada para gerar valores com distri-buicao acumulada especificada pelos n-vetores x, y, onde y = P [X ≤ x] paraalguma variavel aleatoria X. O tipo vector e um array[0..20] de numerosreais declarado em Simao.

13

3.3 Rotinas de manipulacao de entidades

entity newentt()Retorna a referencia da entidade criada.

void old ( entity E )Destroi a entidade E.

attribute newatrb()Retorna a referencia do atributo de entidade criado.

void setatrb ( entity E, attribute A, float val )Atribui o valor val para o atributo A da entidade E.

float getatrb ( entity E, attribute A )Retorna o valor do atributo A da entidade E.

int idle ( entity E )Retorna true (1) quando a entidade E nao esta associada a nenhum eventoagendado na lista de eventos futuros; caso contrario retorna false (0).

3.4 Rotinas de manipulacao de filas

queue newqueue ( int n )Retorna a referencia da fila criada com n entidades que tambem sao criadaspor esta rotina.

void push ( int pos, queue Q, entity E )Insere a entidade E na posicao pos da fila Q. Aceita as constantes pos =front, back.

entity pop ( int pos, queue Q )Retorna a referencia da entidade na posicao pos da fila Q depois de remove-la.Aceita as constantes pos = front, back.

void pull ( entity E )Remove a entidade E de sua fila.

entity head ( queue Q)Retorna a referencia da primeira entidade da fila Q.

entity tail ( queue Q )Retorna a referencia da ultima entidade da fila Q.

14

entity next ( entity E)Retorna a proxima entidade na fila da entidade E.

int empty ( queue Q )Retorna true (1) quando a fila Q nao possui nenhuma entidade, caso con-trario retorna false (0).

int qsize ( queue Q)Retorna o numero de entidades na fila Q.

3.5 Rotinas de controle

void init ( float instante inicial )Inicializa as variaveis internas do Simao. Sua chamada e imprescindıvel paraa realizacao da simulacao. O parametro indica o valor inicial do relogio dasimulacao.

event newevnt ( )Retorna a referencia do evento criado.

void schedule ( event E, float t, entity E1, E2, E3 )Inicia a execucao da atividade com termino no evento E e agenda na lista deeventos futuros para o instante clock+ t (isto significa que a atividade tera aduracao t). O termo clock representa o instante de tempo de simulacao. Astres entidades E1, E2, E3 necessarias para o desenvolvimento da atividadeficam presas no evento. A constante none pode ser utilizada em lugar decada entidade nao necessaria; entretanto, a atual versao nao dispoe de umarotina para pendurar mais do que tres entidades.

event getevent ( entity ∗E1, ∗E2, ∗E3 )Retira o primeiro proximo evento da lista de eventos futuros e retorna a suareferencia no nome e retorna como parametro as entidades associadas. Casomenos de tres entidades estejam associadas, a lista de entidades e completadacom a constante none.

float simclock( )Retorna o instante de tempo de simulacao.

float nextclock ( )Retorna o instante de tempo do primeiro evento na lista de eventos futuros(proximo evento).

15

void summary ( )Imprime um sumario dos recursos de memoria utilizados na simulacao.

3.6 Rotinas de histogramas

histogram newhist( float a, b, c )Retorna a referencia do histograma criado para classificar valores no intervalo[a, b] em classes [a, a+ c, a+ 2c, ..b].

void loghist ( histogram H, float p, v )Inclui o valor v com peso p no histograma H.

void updatehist ( histogram H, float ∗p, v )Inclui o valor v com peso clock − p no histograma H e atribui o valor clockpara p, marcando dessa forma o instante da ultima atualizacao do histogramaH. O termo clock denota uma funcao que retorna o instante de tempo desimulacao.

float gethist ( histogram H, int i )Retorna a frequencia absoluta obtida no intervalo i = 0..n+ 1 do histogramaH. Os intervalos extremos (i = 0, i = n + 1) contabilizam as observacoesque extrapolaram o intervalo de definicao do histograma.

3.7 Rotinas de estatısticas

statistic newstat ( )Retorna a referencia da estatıstica criada.

void logstat ( statistic S, float p, v )Inclui o valor v com peso p na estatıstica S.

void updatestat ( statistic S, float ∗p, v )Inclui o valor v com peso clock − p na estatıstica S e atribui o valor clockpara p, marcando dessa forma o instante da ultima atualizacao da estatısticaS.

float getstat ( statistic S, float * med, * vrc, * min, * max, * som )Retorna a media, a variancia, o mınimo, o maximo e a soma dos pesos dasobservacoes computadas na estatıtica S.

16

3.8 Rotinas de reinicializacao

Essas rotinas fazem com que as estatısticas automaticamente associadas afilas, atividades e tambem aquelas definidas pelos histogramas e pelas es-tatısticas propriamente ditas sejam reinicializadas; isto e, faz com que os va-lores incluıdos ate o momento sejam retirados. Essas rotinas sao uteis paraa definicao do perıodo de simulacao em contraste com o perıodo de aqueci-mento, que em algumas simulacoes e necessario considerar para eliminar osefeitos das condicoes iniciais.

void renewhist ( histogram H)Reinicializa o histograma H.

void renewstat ( statistic S)Reinicializa a estatıstica S.

3.9 Exemplo: fila com 1 servidor

Nesta secao e discutida a programacao de uma versao bem simples de ummodelo de fila D/M/1 para a qual a tecnica de simulacao de sistemas naodeve ser empregada; entretanto, trata-se de um bom exemplo. Considere umsistema de fila com um servidor, com intervalos entre chegadas de compri-mento 10 e tempos de atendimento com distribuicao exponencial negativa deesperanca 8.

O programa em C esquematizadodo abaixo utiliza rotinas do Simao.Inicia, Simula e Encerra sao os nomes de tres procedimentos preparadospelo usuario.

Dec variaveisDec procedimentos

void main()

{Inicia();Simula();Encerra();

};

17

Em Dec variaveis (vide abaixo) encontram-se as declaracoes das entidadescaixa e cliente, da linha de espera (queue) fila, dos eventos chegada etermino de servico, alem da semente (long sem (inteiro sem sinal) paragerar valores aleatorios. Tambem sao declaradas as variaveis auxiliares E1,E2, E3, evento.

entity caixa, cliente, E1, E2, E3;queue fila;event chegada, servico, evento;long sem;

Em Dec procedimentos encontram-se codificados os procedimentos cha-mados no programa principal e que devem ser detalhados.

A inicializacao da simulacao e feita no procedimento Inicia. Em primei-ro lugar e necessario executar o comando init para inicializar as variaveisinternas do Simao. A seguir, e criada a entidade permanente caixa, a linhade espera (fila) e os dois eventos programaveis (chegada, servico (fim de)).A seguir e lida a semente (sem). Finalmente e feita a programacao da che-gada do primeiro cliente para o instante 10 (intervalo de comprimento 10contado a partir da origem) com o comando schedule. O sistema e iniciali-zado sem clientes. Para que a simulacao tenha inıcio e necessario dar partidaagendando o primeiro evento para a lista de eventos futuros.

void Inicia(){

init(0);caixa = newentt();fila = newqueue();chegada = newevent();servico = newevent();readln(sem);schedule(chegada, 10, none, none, none);

};

O termino da simulacao e efetuado com a execucao do procedimento En-cerra. E possıvel emitir uma serie de relatorios sobre as entidades, atividades

18

e filas, alem da construcao de histogramas e estatısticas especıficas do propriousuario. A tıtulo de exemplo e emitido um relatorio de resumo da simulacaocom o comando summary e um relatorio sobre a linha de espera (fila) com ocomando print queue.

void Encerra(){

summary;printqueue(fila, ”fila”);

};

A simulacao propriamente dita e realizada no procedimento Simula. Ocontrole da simulacao esta sendo feito por meio do tempo total de simulacaoque esta limitado em 500 (especificado pelo usuario). A funcao nextclock

retorna o valor do relogio da simulacao a cada vez que e chamada. Assim, acada instante de simulacao e selecionado o proximo evento a ocorrer atravesdo comando get event. O tipo do evento e reconhecido com os comandos ife as operacoes necessarias para a sua realizacao sao executadas atraves daschamadas de Proc Chegar ou Proc Servir. A rotina error emite a men-sagem que lhe e passada e interrompe a execucao da simulacao; idealmente,ela nunca e executada.

void Simula(){

while ( simclock() < 500 ) do{

evento = getevent(&E1,&E2,&E3);if ( evento == chegada ) Proc Chegar(); else

if ( evento == servico ) Proc Servir();else error(”evento desconhecido”);

};};

A chegada de um cliente e realizada em Proc Chegar. Uma entidadetemporaria cliente e gerada com o comando new entt. A seguir e testada acondicao de caixa ocioso (idle) com o comando if. Em caso de ociosidade,

19

o termino de servico do cliente e agendado na lista de eventos futuros como comando schedule. A duracao do servico tem distribuicao exponencialnegativa de esperanca 8 e e desenvolvida em conjunto pelas entidades caixae cliente. Em caso de caixa nao-ocioso, o comando push e executado paracolocar a entidade cliente no fim (back) da fila. Alem disto, e agendada umanova chegada com o comando schedule para acontecer apos um intervalo detempo de tamanho 10.

void Proc Chegar(){ / ∗ E1 == E2 == E3 == none ∗ /

schedule(chegada, 10, none, none, none);cliente = new entt();if ( idle(caixa) )

start(servico, negexp(8,&sem), caixa, cliente, none);else

push(back, fila, cliente);};

O termino de atendimento de um cliente e realizado em Proc Servir.As entidades caixa e cliente (nesta ordem) sao recuperadas, sendo que asegunda e destruıda com o comando old. A seguir e testada a condicao defila vazia (empty) com o comando if. Caso haja clientes na fila, o primeiro(first) e extraıdo com o comando pop e o seu servico e agendado, com ocomando schedule, por um perıodo com distribuicao exponencial negativade esperanca 8 e deve ser desenvolvido em conjunto pelas entidades caixa ecliente (nesta ordem).

procedure Proc Servir(){ / ∗ E1 == caixa, E2 == cliente ∗ /

old(E2);if ( !empty(fila) )

schedule(servico, negexp(8,&sem), E1, pop(first, fila), none);};

Para encerrar, convem ressaltar que a semente sem e atualizada auto-maticamente a cada chamada de neg exp. Alem disso, a entidade caixa

20

encontra-se ociosa (idle) somente quando nao esta presa a um evento servicoagendado na lista de eventos futuros; isso impede que duas ou mais atividadesdesse tipo se desenvolvam simultaneamente.

21

entity caixa, cliente, E1, E2, E3;

queue fila;

event chegada, servico, evento;

long sem;

init( 0 );

caixa = newentt();

fila = newqueue( 0 );

chegada = newevent();

servico = newevent();

readln( sem );

schedule ( chegada, 10, none, none, none );

while( nextclock() < 500 )

{

evento = getevent ( &E1, &E2, &E3 );

if( evento == chegada )

{

cliente = newentt();

if( idle( caixa ) )

start( servico, negexp(8,&sem), caixa, cliente, none );

else push( back, fila, cliente ) ;

schedule( chegada, 10, none, none, none );

} else

if( evento == servico )

{

old( E2 );

if( !empty ( fila ) )

schedule( servico, negexp(8,&sem), E1, pop(first,fila), none );

};

else error( "evento desconhecido" );

};

summary;

printqueue( fila );

22

Capıtulo 4

Simao em Pascal

4.1 Estruturas

A versao deste pacote em Pascal considera os seguintes tipos de estruturaspara as variaveis:

CLASS

ENTITY

ATTRIBUTE

QUEUE

EVENT

HISTOGRAM

STATISTIC

DISTRIBUTION

4.2 Rotinas de amostragem

Essas rotinas permitem a geracao de valores de variaveis aleatorias com dis-tribuicao preestabelecida. O parametro θ e uma variavel inteira positiva(word), sempre passada por nome (var), que implicitamente e alterado parapermitir o calculo do valor desejado de modo automatico.

23

function ALEAT ( var θ : word ) : realRetorna um numero aleatorio; isto e, o valor de uma variavel aleatoria comdistribuicao uniforme no intervalo (0, 1).

function UNIFORM ( a, b : real; var θ : word ) : realRetorna um valor com distribuicao uniforme no intervalo (a, b).

function RANDOM ( a, b : integer; var θ : word ) : integerRetorna qualquer um dos valores inteiros de a..b com a mesma probabilidade.

function BERNOULLI ( p : real; var θ : word ) : booleanRetorna um valor com distribuicao de Bernoulli com probabilidade p.

function GEOMETRIC ( p : real; var θ : word ) : integerRetorna um valor com distribuicao geometrica com probabilidade p.

function TRIANGULAR ( a, b, c : real; var θ : word ) : realRetorna um valor com distribuicao triangular no intervalo (a, c) com modaem b.

function NEG EXP ( µ : real; var θ : word ) : realRetorna um valor com distribuicao exponencial negativa com esperanca µ.

function ERLANG ( µ : real; n : byte; var θ : word ) : realRetorna um valor com distribuicao Erlang com n fases e esperanca µ.

function POISSON ( µ : real; var θ : word ) : wordRetorna um valor com distribuicao de Poisson com esperanca µ.

function WEIBULL ( ρ : real; var θ : word ) : realRetorna um valor com distribuicao de Weibull com parametros ρ, 1.

function NORMAL ( µ, σ : real; var θ : word ) : realRetorna um valor com distribuicao normal com esperanca µ e desvio padraoσ.

function SAMPLE ( d : distribution; var θ : integer ) : realRetorna um valor com distribuicao pre-definida por d.

function NEW DIST ( x, y : vector; n: byte ) : distributionRetorna a referencia da distribuicao criada para gerar valores com distri-buicao acumulada especificada pelos n-vetores x, y, onde y = P [X ≤ x] paraalguma variavel aleatoria X. O tipo vector e um array[0..20] de numerosreais declarado em Simao.

24

4.3 Rotinas de manipulacao de entidades

function NEW ENTT : entityRetorna a referencia da entidade criada.

procedure OLD ( var E: entity )Destroi a entidade E.

function NEW ATRB : attributeRetorna a referencia do atributo de entidade criado.

procedure SET ATRB ( E: entity; A: attribute v : real )Atribui o valor v para o atributo A da entidade E.

function GET ATRB ( E: entity; A: attribute ) : realRetorna o valor do atributo A da entidade E.

4.4 Rotinas de manipulacao de filas

function NEW QUEUE ( S: string ) : queue;Retorna a referencia da fila criada com identificador S.

function NEW SET ( S: string; n : byte ) : queue;Retorna a referencia da fila criada com identificador S com n entidades quesao criadas por esta rotina.

procedure PUSH ( pos : byte; Q : queue; E: entity )Insere a entidade E na posicao pos da fila Q. Aceita as constantes pos =FRONT, BACK.

function POP ( pos : byte; Q : queue ) : entityRetorna a referencia da entidade na posicao pos da fila Q depois de remove-la.Aceita as constantes pos = FRONT, BACK.

procedure PULL ( E: entity )Remove a entidade E de sua fila.

4.5 Rotinas de controle

procedure INIT ( instante inicial : real )Inicializa as variaveis internas do Simao. Sua chamada e imprescindıvel para

25

a realizacao da simulacao. O parametro indica o valor inicial do relogio dasimulacao.

function NEW EVNT ( S: string ) : activityRetorna a referencia do evento criado com identificador S.

procedure SCHEDULE ( E : event; Es : ents; t : real )Inicia a execucao da atividade com termino no evento E e agenda na lista deeventos futuros para o instante clock + t (isto significa que a atividade teraa duracao t). O termo clock representa o instante de tempo de simulacao.O vetor de entidades Es especifica an entidades que estao envolvidas nodesenvolvimento da atividade.

function GET EVENT ( var Es : ents ) : eventRetira o primeiro ou proximo evento da lista de eventos futuros e retorna asua referencia no nome e retorna como parametro as entidades associadas novetor Es.

4.6 Rotinas de histogramas

function NEW HIST ( a, b, c : real ) : histogramRetorna a referencia do histograma criado para classificar valores no intervalo[a, b] em classes [a, a+ c, a+ 2c, ..b].

procedure LOG HIST ( H : histogram; p, v : real )Inclui o valor v com peso p no histograma H.

procedure UPDATE HIST ( H : histogram; var p : real; v : real )Inclui o valor v com peso clock − p no histograma H e atribui o valor clockpara p, marcando dessa forma o instante da ultima atualizacao do histogramaH. O termo clock denota uma funcao que retorna o instante de tempo desimulacao.

4.7 Rotinas de estatısticas

function NEW STAT : statisticRetorna a referencia da estatıstica criada.

procedure LOG STAT ( S : statistic; p : real; v : real )Inclui o valor v com peso p na estatıstica S.

26

procedure UPDATE STAT ( S: statistic; var p : real; v : real )Inclui o valor v com peso clock − p na estatıstica S e atribui o valor clockpara p, marcando dessa forma o instante da ultima atualizacao da estatısticaS.

4.8 Rotinas de reinicializacao

Essas rotinas fazem com que as estatısticas automaticamente associadas afilas, atividades e tambem aquelas definidas pelos histogramas e pelas es-tatısticas propriamente ditas sejam reinicializadas; isto e, faz com que os va-lores incluıdos ate o momento sejam retirados. Essas rotinas sao uteis paraa definicao do perıodo de simulacao em contraste com o perıodo de aqueci-mento, que em algumas simulacoes e necessario considerar para eliminar osefeitos das condicoes iniciais.

procedure RENEW HIST ( H : histogram )Reinicializa o histograma H.

procedure RENEW STAT ( S : statistic )Reinicializa a estatıstica S.

4.9 Rotinas para relatorios

procedure PRINT SIMAOImprime na tela a identificacao do pacote Simao.

procedure PRINT SUMMARYImprime na tela o relatorio de resumo da simulacao.

procedure PRINT STAT ( S : statistic; t : string )Imprime na tela o relatorio da estatıstica S com tıtulo t.

procedure PRINT HIST ( H : histogram; t : string )Imprime na tela o relatorio do histograma h com tıtulo t.

As rotinas abaixo imprimem os mesmos relatorios no arquivo de textosf , pre-definido.

procedure WRITE SUMMARY( f : text )

procedure WRITE STAT ( f : text; S : statistic; t : string )

procedure WRITE HIST ( f : text; H : histogram; t : string )

27

4.10 Rotinas de informacao

function QNAME ( Q : queue ) : stringRetorna o identificador da fila Q.

function HEAD ( Q : queue ) : entityRetorna a referencia da primeira entidade da fila Q.

function TAIL ( Q : queue ) : entityRetorna a referencia da ultima entidade da fila Q.

function NEXT ( E: entity ) : entityRetorna a proxima entidade na fila da entidade E.

function QSIZE ( Q : queue ) : integerRetorna o numero de entidades na fila Q.

function EMPTY ( Q : queue ) : booleanRetorna true quando a fila Q nao possui nenhuma entidade, caso contrarioretorna false.

function ACTIVE ( E: entity ) : booleanRetorna true quando a entidade E esta associada a uma atividade; casocontrario, retorna false.

function PASSIVE ( E: entity ) : booleanRetorna true quando a entidade E esta associada a uma fila; caso contrario,retorna false.

function IDLE ( E: entity ) : booleanRetorna true quando a entidade E nao esta associada a uma atividade ou auma fila; caso contrario retorna false.

function CLOCK : realRetorna o instante de tempo de simulacao (mesmo que current clock)

function SIM CLOCK : realRetorna o instante de tempo de simulacao (mesmo que clock).

function INITIAL CLOCK : realRetorna o instante de tempo em que a simulacao teve inıcio.

function NEXT CLOCK : realRetorna o instante de tempo do primeiro evento na lista de eventos futuros(proximo evento).

28

4.11 Exemplo: fila com 1 servidor

Nesta secao e discutida a programacao de uma versao bem simples de ummodelo de fila D/M/1 para a qual a tecnica de simulacao de sistemas naodeve ser empregada; entretanto, trata-se de um bom exemplo. Considere umsistema de fila com um servidor, com intervalos entre chegadas de compri-mento 10 e tempos de atendimento com distribuicao exponencial negativa deesperanca 8.

O programa em Pascal, abaixo delineado, utiliza rotinas do Simao. Inicia,Simula e Encerra sao os nomes de tres procedimentos preparados pelo usua-rio.

program

Dec variaveisDec procedimentos

begin

Inicia;Simula;Encerra;

end.

Em Dec variaveis (vide abaixo) encontram-se as declaracoes das classesdas entidades cliente e caixa, da linha de espera (queue) fila, das atividadeschegada e servico, alem da semente (word ou numero inteiro sem sinal) sempara gerar valores aleatorios. Tambem e declarada uma variavel auxiliaratividade.

var

cliente, caixa : entity;fila : queue;chegada, servico, evento : event;es : ents;sem : word;

Em Dec procedimentos encontram-se codificados os procedimentos cha-mados no programa principal e que devem ser detalhados.

29

A inicializacao da simulacao e feita no procedimento Inicia. Em pri-meiro lugar e necessario executar o comando init simao para inicializar asvariaveis internas do Simao. A seguir, sao criadas as duas classes do sis-tema (cls cliente, cls caixa), a unica entidade permanente (caixa), a linhade espera (fila) e as duas atividades (chegada, servico). A seguir e lida asemente (sem). Finalmente e feita a programacao da chegada do primeirocliente para o instante 10 (intervalo de comprimento 10 contado a partir daorigem) com o comando start. O sistema e inicializado sem clientes. Paraque a simulacao tenha inıcio e necessario dar partida programando para oprimeiro evento para a lista de eventos futuros.

procedure Inicia;begin

init(0);caixa = new entt(′caixa′);fila = new queue(′fila′);chegada← new event(′chegada′);servico← new event(′servico′);readln(sem);schedule(chegada, 10, es);end;

O termino da simulacao e efetuado com a execucao do procedimento En-cerra. E possıvel emitir uma serie de relatorios sobre as entidades, atividadese filas, alem da construcao de histogramas e estatısticas especıficas do propriousuario. A tıtulo de exemplo e emitido um relatorio de resumo da simulacaocom o comando print simao e um relatorio sobre a linha de espera (fila)com o comando print queue.

procedure Encerra;begin

print summary;print queue(fila,′ fila′);end;

A simulacao propriamente dita e realizada no procedimento Simula. Ocontrole da simulacao esta sendo feito por meio do tempo total de simulacao

30

que esta limitado em 500 (especificado pelo usuario). A funcao clock re-torna o valor do relogio da simulacao a cada vez que e chamada. Assim, acada instante de simulacao e selecionado o proximo evento a ocorrer atravesdo comando get next event. A atividade que se encerra com este eventoe reconhecida com o comando if e as operacoes necessarias para o terminodessa atividade sao executadas atraves das chamadas de Proc Chegar ouProc Servir. A rotina error emite a mensagem que lhe e passada e inter-rompe a execucao da simulacao; em princıpio, ela nunca e executada.

procedure Simula;while ( next clock < 500 ) do

begin

event← get event(Es);if ( evento = chegada ) then Proc Chegar elseif ( evento = servico ) then Proc Servirelse error(′evento desconhecido′);end;

A chegada de um cliente e realizada em Proc Chegar. Uma entidadetemporaria cliente e gerada com o comando new entt. A seguir e testada acondicao de caixa ocioso (idle) com o comando if. No caso de ociosidade,o termino de servico do cliente e agendado na lista de eventos futuros como comando schedule. A duracao do servico tem distribuicao exponencialnegativa de esperanca 8 e e desenvolvida em conjunto pelas entidades caixae cliente. Em caso de caixa nao-ocioso o comando push e executado paracolocar a entidade cliente no fim (back) da fila. Finalmente e agendada achegada de mais um cliente com o comando schedule para acontecer aposum intervalo de tempo de tamanho 10.

procedure Proc Chegar;begin

schedule(chegada, 10, Es);cliente← new entt(′cliente′);if ( idle(caixa) )then

begin

31

Es[1]← caixa; Es[2]← cliente;start(servico, neg exp(8, sem), Es);end;

else push(back, fila, cliente);end;

O termino de atendimento de um cliente e realizado em Proc Servir. Asentidades caixa e cliente (nesta ordem) sao liberadas no vetor de entidadesEs sendo que a ultima e destruıda com o comando old. A seguir e testadaa condicao de fila vazia (empty) com o comando if. Caso haja cliente nafila, o primeiro (first) e extraıdo com o comando pop e o seu servico eprogramado, com o comando schedule, por um perıodo com distribuicaoexponencial negativa de esperanca 8 e deve ser desenvolvido em conjuntopelas entidades caixa e cliente (nesta ordem).

procedure Proc Servir;begin

caixa← Es[1];cliente← Es[2];old(cliente);if ( not empty(fila) )then

begin

cliente← pop(first, fila);Es[2]← cliente;schedule(servico, neg exp(8, sem), Es);end;

end;

Para encerrar, convem ressaltar que a semente sem e atualizada auto-maticamente a cada chamada de neg exp. Alem disso, a entidade caixaencontra-se ociosa (idle) somente quando nao esta presa a uma realizacaoda atividade servico; isso impede que duas ou mais atividades desse tipo sedesenvolvam simultaneamente.

32

Capıtulo 5

Simao em Matlab

A versao deste pacote para Matlab considera os seguintes tipos de variaveisinteiras:

entity

attribute

queue

event

histogram

statistic

distribution

5.1 Rotinas de amostragem

Essas rotinas permitem a geracao de valores de variaveis aleatorias com dis-tribuicao preestabelecida. O parametro θ e uma variavel inteira positiva(word), sempre passada por nome (var ), que implicitamente e alterado parapermitir o calculo do valor desejado de modo automatico.

function [ x, θ ] = aleat ( θ )Retorna um numero aleatorio x; isto e, o valor de uma variavel aleatoriacom distribuicao uniforme no intervalo (0, 1). O parametro e atualizadointernamente preparando-o para a proxima chamada.

33

function [ x, θ ] = uniform ( a, b, θ )Retorna um valor com distribuicao uniforme no intervalo (a, b).

function [ x, θ ] = random ( a, b, θ )Retorna qualquer um dos valores inteiros de a..b com a mesma probabilidade.

function [ x, θ ] = bernoulli ( p, θ )Retorna um valor com distribuicao de Bernoulli com probabilidade p.

function [ x, θ ] = geometric ( p, θ )Retorna um valor com distribuicao geometrica com probabilidade p.

function [ x, θ ] = triangular ( a, b, c, θ )Retorna um valor com distribuicao triangular no intervalo (a, c) com modaem b.

function [ x, θ ] = negexp ( µ, θ )Retorna um valor com distribuicao exponencial negativa com esperanca µ.

function [ x, θ ] = erlang ( µ, n, θ )Retorna um valor com distribuicao Erlang com n fases e esperanca µ.

function [ x, θ ] = poisson ( µ, θ )Retorna um valor com distribuicao de Poisson com esperanca µ.

function [ x, θ ] = normal ( µ, σ, θ )Retorna um valor com distribuicao normal de esperanca µ e desvio padrao σ

5.2 Rotinas de manipulacao de entidades

function entt = newenttRetorna a referencia da entidade criada.

function old ( entt )Destroi a entidade entt.

function atrb = newatrbRetorna a referencia do atributo criado.

function setatrb ( entt, atrb, val )Atribui o valor val para o atributo atbr da entidade entt.

function val = getatrb ( entt, atrb )Retorna o valor val do atributo atrb da entidade entt.

34

function bool = idle(entt)Retorna 1 (true) quando a entidade entt nao esta associada a uma atividade;caso contrario retorna 0 (false).

5.3 Rotinas de manipulacao de filas

function queue = newqueue ( num )Retorna a referencia da fila criada com identificador com num entidades;estas entidades tambem sao criadas por esta rotina.

function push ( entt, queue, pos )Insere a entidade entt na posicao pos da fila queue. Aceita as constantes pos= front, back.

function entt = pop ( queue )Retorna a referencia da entidade da primeira entidade da fila queue depoisde remove-la.

function pull ( queue, entt, action )Remove a entidade entt da fila queue.

function entt = head(queue)Retorna a referencia para a primeira entidade da fila queue.

function entt = tail(queue)Retorna a referencia da ultima entidade da fila queue.

function entt = next(ent)Retorna a referencia para a proxima entidade na fila da entidade ent.

fuction num = qsize(queue)Retorna o numero de entidades na fila queue.

function bool = empty(queue)Retorna 1 (true) quando a fila queue nao possui nenhuma entidade, casocontrario retorna 0 (false).

5.4 Rotinas de controle

function init ( instante inicial, n entt, n heap )Inicializa as variaveis internas do Simao. Sua chamada e imprescindıvel paraa realizacao da simulacao. O parametro opcional instante inicial define

35

o instante inicial de simulacao e n entt, n heap o tamanhos dos arrays deentidades e de eventos futuros.

function neweventRetorna a referencia do tipo de evento criado.

function time = clockRetorna o instante de tempo corrente de simulacao.

function time= nextclock ( )Retorna o instante de tempo do primeiro evento na lista de eventos futuros(proximo evento).

function schedule ( time, event, ents )Agenda (cria e coloca na lista de eventos futuros) um evento do tipo eventpara o instante clock + time; isso significa que a atividade associada estasendo iniciada e sera encerrada com este evento tera a duracao time.

function [ event, ents, clck ] = geteventRetira o primeiro (ou proximo) evento da lista de eventos futuros e retorna asua referencia, assim como as entidades associadas e o instante de simulacao.O evento e do tipo event, as entidades associadas encontram-se no vetor deentidades ents e clck e o novo valor do relogio.

function summaryImprime um resumo dos recursos de memoria utilizados na simulacao.

5.5 Rotinas de estatısticas

function stat = newstatRetorna a referencia da estatıstica criada.

function [time] = logstat ( stat, val, pes, option )Com tres parametros, inclui o valor val com peso pes na estatıstica stat.Com quatro parametros (option), inclui o valor val com peso clock − pes naestatıstica stat e atualiza a variavel time com o valor de clock.

function [vet] = getstat ( stat )Retorna o vetor vet = [count,mean, var,min,max] com os valores atuais daestatıstica stat: numero de observacoes, media, variancia, mınimo e maximo.

36

5.6 Rotinas de reinicializacao

Essas rotinas fazem com que as estatısticas automaticamente associadas afilas, atividades e tambem aquelas definidas pelos histogramas e pelas es-tatısticas propriamente ditas sejam reinicializadas; isto e, faz com que os va-lores incluıdos ate o momento sejam retirados. Essas rotinas sao uteis paraa definicao do perıodo de simulacao em contraste com o perıodo de aqueci-mento, que em algumas simulacoes e necessario considerar para eliminar osefeitos das condicoes iniciais.

function renewstatReinicializa as estatısticas.

function renewhistReinicializa os histogramas.

5.7 Exemplo: fila com 1 servidor

Nesta secao e discutida a programacao de uma versao bem simples de ummodelo de fila D/M/1 para a qual a tecnica de simulacao de sistemas naodeve ser empregada; entretanto, trata-se de um bom exemplo. Considere umsistema de fila com um servidor, com intervalos entre chegadas de compri-mento 10 e tempos de atendimento com distribuicao exponencial negativa deesperanca 8.

O programa em Matlab, abaixo delineado, utiliza rotinas do Simao. Ini-cialmente sao especificados:

cheg – duracao do intervalo entre chegadas,

serv – duracao da atividade servico,

tsim – tempo total de simulacao a partir do instante 0,

sem – semente para geracao de tempos de servico

Apos o comando init, sao criadas as estruturas

chegada – evento para os instantes de chegada de clientes

servico – evento para os instantes de termino da atividade de servico ouatendimento

37

cheg = 10; % intervalo entre chegadas (constante)

serv = ’negexp(8,sem)’; % distribuicao do tempo de atendimento

tsim = 100; % tempo total de simulacao

sem = 13; % semente

init;

chegada=newevent;

servico=newevent;

linha=newqueue;

caixa=newentt;

schedule(cheg,chegada);

while ( clock < tsim )

[event,ents] = getevent;

if ( event = chegada )

cliente=newentt;

if ( idle(caixa) )

[time,sem]=eval(serv);

schedule(time,servico,[caixa,cliente]);

else push(cliente,linha); end;

schedule(cheg,chegada);

elseif ( event = servico )

caixa=ents(1); cliente=ents(2);

old(cliente);

if ( ~empty(linha) )

cliente=pop(linha);

[time,sem]=eval(serv);

schedule(time,servico,[caixa,cliente]);

end;end;end;

summary;

Tabela 5.1: Fila com Um Servidor em Matlab

38

linha – fila para representar a linha de espera de cliente

caixa – representando a unica entidade permanente

A simulacao propriamente dita tem inıcio com o sistema vazio (linhavazia e caixa ocioso). Para dar partida na simulacao e necessario agendaro primeiro evento: uma chegada de cliente. Isto e feito com o comandoschedule que insere na lista de eventos futuros um evento do tipo chegadapara o instante de tempo clck + cheg = 10 (clck representa o instantecorrente de simulacao que esta inicializado com 0.

A simulacao propriamente dita e realizada no bloco definido pelo comandowhile sob a condicao clock < tsim; ou seja enquanto o instante de ocorrenciado prximo evento agendado (inserido na lista de eventos futuros) for inferiorao tempo total de simulacao, este proximo evento deve ser simulado.

Assim, o proximo evento e retirado da lista de eventos futuros com ocomando getevent que retorna o tipo do evento em event e as entidadespenduradas no vetor de entidades ents. E necessario reconhecer se o atualevento e do tipo chegada ou sevico utilizando os comando if com uma pernaelseif.

Em caso de evento do tipo chegada, e criada uma entidade temporariacliente e e verificado se o caixa encontra-se ocioso com a funcao idle. Emcaso afirmativo e agendado com o comando schedule um envento do tiposervico que marca o termino de atendimente para o instante clck + timede um servico com as entidades caixa e cliente (nesta ordem) com duracaotime gerada na avaliacao de serv que causa a chamada da funcao expneg;implicitamente a semente sem retorna atualizada do gerador de numerosaleatorios. Em caso de caixa ocupado (nao ocioso) e necessario inserir ocliente na fila linha com o comando push. Finalmente, em qualquer dosdois casos e necessario gerar a proxima chegada (evento do tipo chegada)com o comando schedule para apos um intervalo de tempo de comprimentocheg.

Em caso de evento do tipo termino de servico, as entidades caixa e clientesao recuperadas do vetor ents = [caixa cliente], a entidade cliente e des-truıda com o comando old e se houver cliente na linha de espera, o primeirodeve ser atendido. Neste caso, o comando pop retira este primeiro clienteda fila e e agendado um evento do tipo termino de servico para encerrar umatendimento com duracao time envolvendo as entidades caixa e cliente.

A simulacao se encerra quando nao ha eventos agendados para ocorrer

39

antes do tempo de simulacao tsim. Neste caso o comando summary encer-ra a corrida aprsentando uma estatıstica de usos das estruturas do pacote:numero de entidades criadas, numero maximo de entidades vivas ao mesmotempo, numero de filas criadas, numero de tipos de eventos criados, numerode eventos processados, numero maximo de eventos na lista de eventos futu-ros, etc.

40

% FILA - Simulacao de Fila com 1 servidor

% Chegadas com distribuicao ’cheg’

% Atendimento com distribuicao ’serv’

fprintf(’Simulao de Fila com 1 servidor’);

cheg = ’negexp(8,sem)’; % distribuio do intervalo entre chegadas

serv = ’negexp(6,sem)’; % distribuio do tempo de atendimento

tsim = 100; % durao da simulao

sem = 13; % semente

init; chegada=newevent; servico=newevent; linha=newqueue;

caixa=newentt; [time,sem]=eval(cheg); schedule(time,chegada);

while ( clock < tsim )

[event,ents] = getevent;

if ( event = chegada ), fprintf(’\n%5.1f chegada’,simclock);

cliente=newentt;

if ( idle(caixa) ), fprintf(’ > incio de servio’);

[time,sem]=eval(serv);

schedule(time,servico,[caixa,cliente]);

else push(cliente,linha); fprintf(’ > fila’); end;

[time,sem]=eval(cheg);

schedule(time,chegada);

elseif ( event = servico ), fprintf(’\n%5.1f fim de servio’,time);

caixa=ents(1); cliente=ents(2);

old(cliente);

if ( ~empty(linha) ), fprintf(’ > incio de servio’);

cliente=pop(linha);

[time,sem]=eval(serv);

schedule(time,servico,[caixa,cliente]);

end;end;end;

summary;

41

% FONE - Simulao de Linhas de Telefone

n_cabo=3; n_fone=8; t_sim=50; seed=13;

cham = ’negexp(4,seed)’; serv = ’negexp(3,seed)’;

n_blck=0; n_ocup=0; n_ligd=0; time=0;

init;

lines=newset(n_cabo); fones=newset(n_fone); tels=getqueue(fones);

chamada=newevent; servico=newevent;

[time,seed]=eval(cham); schedule(time,chamada);

while ( simclock < t_sim )

[event,ents] = getevent;

if ( event=chamada ),

if empty(fones), disp(’FONE: chamada sem fone?’); return; end;

f1=pull(fones,’random’,seed);

[f2,seed]=random(1,n_fone,seed); f2=tels(f2);

while ( f1=f2 ) [f2,seed]=random(1,n_fone,seed); f2=tels(f2); end;

if ( empty(lines) ), str=’bloqueada’;

push(f1,fones); n_blck=n_blck+1;

elseif ~( idle(f2) ), str=’ocupada’;

push(f1,fones); n_ocup=n_ocup+1;

else n_ligd=n_ligd+1;

linha=pull(lines); f2=pull(fones,’entity’,f2);

[time,seed]=eval(serv); schedule(time,servico,[linha f1 f2]);

str=[’inicio C’ num2str(linha) ’ ’ num2str(f1) ’ ’ num2str(f2)];

end;

[time,seed]=eval(cham); schedule(time,chamada);

elseif ( event=servico ),

linha=ents(1); f1=ents(2); f2=ents(3);

push(linha,lines); push(f1,fones); push(f2,fones);

str=[’fim C’ num2str(linha) ’ ’ num2str(f1) ’ ’ num2str(f2)];

end;

fprintf(’\n%6.2f %s’, simclock, str);

end;

summary;

fprintf(’%d chamadas: %d conectadas %d bloqueadas %d ocupadas\n’, ...

n_ligd+n_blck+n_ocup, n_ligd, n_blck, n_ocup );

42

% PUB - Exemplo de Simulao com Simao

% Entidades do modelo: clientes, garons, copos e pia

% Atividades/Eventos do modelo: Chegar, Servir, Beber, Lavar e Repetir

n_grcm = 3; % (no. of waiters)

n_copo = 3; % (no. of glasses)

Taqm = 10; % (heating time)

Tsim = 20; % (simulation time)

Dst_Arvl=’negexp(2,Sem_Arvl)’; Sem_Arvl=13; % arrival distribution

Dst_Srvc=’erlang(2,2,Sem_Srvc)’; Sem_Srvc=13; % servicing distribution

Dst_Drnk=’uniform(1,3,Sem_Drnk)’; Sem_Drnk=13; % drinking distribution

Dst_Rept=’bernoulli(0.5,Sem_Rept)’; Sem_Rept=13; % repetition distribution

Dst_Wash=’constant(1,Sem_Wash)’; Sem_Wash=13; % washing distribution

Num_Arvl=0; Num_Drnk=0; Num_Wash=0; Tmp_Grcm=0; Tmp_Copo=0; init;

Fla_Lmpo = newset( n_copo ); Fla_Grcm = newset( n_grcm ); Fla_Sujo

= newqueue; Fla_Frgs = newqueue; Pia = newentt; Evt_Arvl=newevent;

Evt_Srvc=newevent; Evt_Drnk=newevent; Evt_Wash=newevent;

Evt_Rini=newevent; stat1 = newstat; tstat=0; stat2 = newstat;

Tcheg = newatrb; [time,Sem_Arvl]=eval(Dst_Arvl);

schedule(time,Evt_Arvl); schedule(Taqm,Evt_Rini); while ( nextclck

<= Taqm+Tsim )

[event,ents] = getevent; % Evento Chegada

if ( event==Evt_Arvl ),

Fregues=newentt;

tstat=logstat(stat1,qsize(Fla_Frgs),tstat,’auto’);

setatrb(Fregues,Tcheg,simclock);

push(Fregues,Fla_Frgs);

[time,Sem_Arvl] = eval(Dst_Arvl);

schedule(time,Evt_Arvl);

Num_Arvl=Num_Arvl+1; % Evento Fim Servir

elseif ( event==Evt_Srvc ),

Fregues=ents(1); Copo=ents(2); Garcom=ents(3);

push ( Garcom, Fla_Grcm );

[time,Sem_Drnk] = eval(Dst_Drnk); ents=[Fregues,Copo];

schedule(time,Evt_Drnk,ents);

Num_Drnk=Num_Drnk+1; Tmp_Copo=Tmp_Copo+time; % Evento Fim Beber

elseif ( event==Evt_Drnk ),

Fregues=ents(1); Copo=ents(2);

[p,Sem_Rept] = eval(Dst_Rept);

43

if ( p ) old(Fregues);

else push( Fregues, Fla_Frgs, ’front’ ); end;

push( Copo, Fla_Sujo ); % Evento Fim Lavar

elseif ( event==Evt_Wash ),

Pia=ents(1); Copo=ents(2); Garcom=ents(3);

push ( Copo, Fla_Lmpo );

if ( empty(Fla_Sujo) ) push(Garcom,Fla_Grcm);

else Copo=pop( Fla_Sujo );

[time,Sem_Wash] = eval(Dst_Wash); Tmp_Grcm=Tmp_Grcm+time;

ents=[Pia, Copo, Garcom];

schedule(time,Evt_Wash,ents);

Num_Wash=Num_Wash+1; Tmp_Grcm=Tmp_Grcm+time; Tmp_Copo=Tmp_Copo+time;

end; % Evento Reinicializar

else Tmp_Grcm=0; Tmp_Copo=0; Num_Arvl=0; Num_Drnk=0; renewstat;

end; % Evento Passivo Inicio de Servir

while ( ~empty(Fla_Frgs) & ~empty(Fla_Lmpo) & ~empty(Fla_Grcm) )

[time,Sem_Srvc]=eval(Dst_Srvc);

tstat=logstat(stat1,qsize(Fla_Frgs),tstat,’auto’);

Fregues = pop( Fla_Frgs );

Copo = pop( Fla_Lmpo );

Garcom = pop( Fla_Grcm );

time=simclock-getatrb(Fregues,Tcheg);

logstat(stat2,time);

ents=[Fregues, Copo, Garcom];

schedule( time, Evt_Srvc, ents);

Tmp_Grcm=Tmp_Grcm+time; Tmp_Copo=Tmp_Copo+time;

end; % Evento Passivo Inicio de Lavar

if ( idle(Pia) & ~empty(Fla_Sujo ) & ~empty(Fla_Grcm) )

[time,Sem_Wash] = eval(Dst_Wash); Tmp_Grcm=Tmp_Grcm+time;

Copo = pop( Fla_Sujo );

Garcom = pop( Fla_Grcm );

ents=[Pia, Copo, Garcom];

schedule( time, Evt_Wash, ents );

Num_Wash=Num_Wash+1; Tmp_Grcm=Tmp_Grcm+time; Tmp_Copo=Tmp_Copo+time;

end;end;

summary;

fprintf(’Aquecimento: %6.2f Simulacao %6.2f\n’, Taqm, Tsim );

44

fprintf(’Entidades: %d Garcons, %d Copos, %d Pia, %d Clientes\n’,

n_grcm,n_copo,1,Num_Arvl );

fprintf(’Atividades: %d Chegadas, %d Servidas/Bebidas, %d Lavadas\n’,

Num_Arvl,Num_Drnk,Num_Wash );

fprintf(’Prop. Util. Copos %6.2f\n’, Tmp_Copo/Tsim/n_copo*100 );

fprintf(’Prop. Util. Garcons %6.2f\n’, Tmp_Grcm/Tsim/n_grcm*100 );

s=getstat(stat1);

fprintf(’Tamanho da Fila: %d (mximo) - %6.2f (mdia) - %6.2f (varincia)\n’,

s(5),s(2),s(3) );

s=getstat(stat2);

fprintf(

’Tempo de Fila (%d clientes): %6.2f (mnimo) - %6.2f (mximo) - %6.2f (mdia) - %6.2f (varincia)\n’,

s(1),s(4),s(5),s(2),s(3) );

45