Skip to content

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édia

P{ } é "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 porcentagem

Dentro 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étricaPerguntaPrevistoMedido
E{#Operando}disponibilidade média0,750,7499
E{#EmManutencao}quanto fica parada, em média0,250,2501
P{#EmManutencao > 0}fração do tempo em manutenção0,250,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}) / VAZAO

Cada 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ê escreveO que está pedindoResultado
E{#Operando} / (E{#EmManutencao} + 1)divide as médias0,60
E{#Operando / (#EmManutencao + 1)}média das divisões0,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 transienteDivisão por um lugar de passagem rápida
A execução para com erro de valor inválidoDivisão por uma quantidade que chega a zero, sem proteção IF
O número parece plausível mas está deslocadoChaves no lugar errado: dividiu médias quando queria média das divisões, ou o contrário