Tema
Médias e probabilidades
Uma métrica é uma pergunta que você faz ao modelo. E{ } e P{ } são as duas formas de perguntar.
E{ } é "a média de"
E{#Fila} significa "quantas fichas ficam na Fila, em média".
O modelo não fica parado: fichas entram e saem, e a quantidade em cada lugar muda o tempo todo. E{ } resume essa variação em um número só — a média ao longo de toda a simulação.
E{#Fila} quantas fichas há na Fila, em média
E{#Servidor} quantos servidores estão ocupados, em média
E{#Fila} + E{#Servidor} quantas fichas há no sistema todo, em médiaP{ } é "que fração do tempo"
P{#Fila > 5} significa "durante quanto tempo a Fila teve mais de 5 fichas", como fração entre 0 e 1.
P{#Fila > 5} fração do tempo com fila acima de 5
P{#Servidor = 0} fração do tempo com o servidor parado
P{#Fila > 5} * 100 a mesma coisa, em porcentagemDentro das chaves você escreve uma condição: comparações (>, >=, <, <=, =, !=), combinadas com AND, OR e NOT.
Um exemplo para ver os dois
Uma máquina que opera por 3 minutos em média e então para 1 minuto para manutenção.
json
{
"modelName": "Máquina com manutenção",
"definitions": [],
"places": [
{ "name": "Operando", "initialMarking": 1, "stringMarking": "1", "initialStringMarking": "1" },
{ "name": "EmManutencao", "initialMarking": 0, "stringMarking": "0", "initialStringMarking": "0" }
],
"rewardMeasures": [
{ "name": "disponibilidade", "expression": "E{#Operando}" },
{ "name": "parada_media", "expression": "E{#EmManutencao}" },
{ "name": "tempo_em_manutencao", "expression": "P{#EmManutencao > 0}" },
{ "name": "divide_as_medias", "expression": "E{#Operando} / (E{#EmManutencao} + 1)" },
{ "name": "media_das_divisoes", "expression": "E{#Operando / (#EmManutencao + 1)}" }
],
"transitions": [
{ "name": "Falha", "type": "TIMED", "firingPolicy": "SINGLE_SERVER",
"raceType": "RACE_WITH_ENABLING_MEMORY", "priority": 1,
"distribution": { "type": "exponential", "parameters": { "Mean delay": "3" } },
"inputArcs": [{ "type": "INPUT", "place": "Operando", "multiplicity": 1 }],
"outputArcs": [{ "type": "OUTPUT", "place": "EmManutencao", "multiplicity": 1 }],
"inhibitorArcs": [] },
{ "name": "Reparo", "type": "TIMED", "firingPolicy": "SINGLE_SERVER",
"raceType": "RACE_WITH_ENABLING_MEMORY", "priority": 1,
"distribution": { "type": "exponential", "parameters": { "Mean delay": "1" } },
"inputArcs": [{ "type": "INPUT", "place": "EmManutencao", "multiplicity": 1 }],
"outputArcs": [{ "type": "OUTPUT", "place": "Operando", "multiplicity": 1 }],
"inhibitorArcs": [] }
]
}De cada 4 minutos, a máquina passa 3 operando. Então dá para prever no papel:
| Métrica | Pergunta | Previsto | Medido |
|---|---|---|---|
E{#Operando} | disponibilidade média | 0,75 | 0,7499 |
E{#EmManutencao} | quanto fica parada, em média | 0,25 | 0,2501 |
P{#EmManutencao > 0} | fração do tempo em manutenção | 0,25 | 0,2501 |
Como só existe uma máquina, E{#Operando} cai entre 0 e 1 e coincide com a fração de tempo — é a disponibilidade de 75%.
Onde você põe as chaves muda a pergunta
Esta é a parte que mais causa engano, e vale entender antes de escrever a primeira métrica composta.
A regra
As chaves marcam o que entra na média. Se você escreve várias E{ } numa expressão, cada uma é resumida separadamente e só depois as contas entre elas acontecem.
Na prática isso é o que você quer quase sempre. Por exemplo, tempo médio de resposta é "quantidade média no sistema, dividida pela vazão média":
(E{#Fila} + E{#Servidor}) / VAZAOCada E{ } vira uma média, e a divisão acontece entre as duas médias. É a conta certa.
Se você envolvesse a expressão inteira em chaves — E{(#Fila + #Servidor) / VAZAO} — estaria pedindo outra coisa: a média da divisão instante a instante. As duas dão números diferentes.
Vendo a diferença no mesmo modelo da máquina:
| Como você escreve | O que está pedindo | Resultado |
|---|---|---|
E{#Operando} / (E{#EmManutencao} + 1) | divide as médias | 0,60 |
E{#Operando / (#EmManutencao + 1)} | média das divisões | 0,75 |
Nenhuma está errada — elas respondem a perguntas diferentes. O erro é escrever uma achando que pediu a outra.
Sem chaves também vira média
Se você escrever #Fila sem chaves, ele é tratado como se estivesse dentro do seu próprio E{ }. Estas duas linhas são idênticas:
#Operando / (#EmManutencao + 1)
E{#Operando} / (E{#EmManutencao} + 1)Ou seja: o comportamento padrão é dividir as médias. Para pedir a média das divisões, você precisa envolver tudo em E{ } de propósito.
Uma ressalva sobre o regime transiente
Tudo acima descreve a análise estacionária, que é a mais usada e onde a média é tirada ao longo de uma execução longa.
Na análise transiente, cada ponto do gráfico é uma média entre várias repetições da simulação, num instante específico. Isso muda um risco: um lugar por onde as fichas passam muito rápido está vazio na maioria das repetições naquele instante, então sua média fica minúscula e instável.
O sintoma
Uma métrica que divide por um lugar assim devolve zero no transiente, mesmo estando correta no estacionário. Se um gráfico transiente mostrar zeros ou saltos sem explicação, é o primeiro lugar para olhar. A página Medir tempo de resposta mostra uma forma alternativa que funciona nos dois regimes.
Erros comuns
| O que você vê | Causa provável |
|---|---|
A métrica dá exatamente 0 no gráfico transiente | Divisão por um lugar de passagem rápida |
| A execução para com erro de valor inválido | Divisão por uma quantidade que chega a zero, sem proteção IF |
| O número parece plausível mas está deslocado | Chaves no lugar errado: dividiu médias quando queria média das divisões, ou o contrário |