Teoria de Estoques e Simulação de Processos de Chegada com Distribuição de Poisson

1. Introdução

A gestão eficiente de estoques é um pilar fundamental para o sucesso de qualquer organização que lida com produtos físicos, seja na manufatura, varejo ou serviços. Em um ambiente de negócios cada vez mais dinâmico e incerto, a capacidade de otimizar os níveis de estoque impacta diretamente a lucratividade, a satisfação do cliente e a competitividade. A Teoria de Estoques fornece as ferramentas e modelos matemáticos necessários para tomar decisões informadas sobre quando e quanto pedir, minimizando custos e garantindo a disponibilidade de produtos [1].

No entanto, muitos dos desafios reais na gestão de estoques envolvem a variabilidade e a incerteza, características inerentes a processos estocásticos como a demanda de clientes e o tempo de reposição de produtos. Nesses cenários, a simulação computacional emerge como uma metodologia poderosa para analisar o comportamento de sistemas complexos, testar diferentes políticas de estoque e prever seu desempenho sob diversas condições, sem a necessidade de intervir no sistema real [2]. Este artigo acadêmico explora a intersecção entre a Teoria de Estoques e a simulação de processos de chegada, com foco na Distribuição de Poisson, fornecendo uma fundamentação teórica robusta e diretrizes para a modelagem em simulações.

2. Fundamentação Teórica

2.1. Teoria de Estoques

A Teoria de Estoques busca equilibrar os custos associados à manutenção de estoques com os custos de não ter estoque suficiente para atender à demanda. Os modelos clássicos de estoque são a base para a compreensão e otimização dessa balança [3].

2.1.1. Modelos Clássicos

O Modelo de Lote Econômico de Compra (EOQ - Economic Order Quantity) é um dos modelos mais fundamentais, que determina a quantidade ótima de pedido que minimiza a soma dos custos de pedido e de manutenção. A fórmula do EOQ é dada por:

\[ EOQ = \sqrt{\frac{2DS}{H}} \]

Onde: * \(D\) = Demanda anual * \(S\) = Custo por pedido * \(H\) = Custo de manutenção por unidade por ano

Outros modelos importantes incluem os modelos com ponto de ressuprimento (ROP - Reorder Point), que disparam um novo pedido quando o nível de estoque atinge um ponto pré-determinado, e os sistemas de revisão contínua (Q-system) e revisão periódica (P-system). No sistema Q, o estoque é monitorado continuamente e um pedido de tamanho fixo é feito quando o ROP é atingido. No sistema P, o estoque é revisado em intervalos fixos e um pedido de tamanho variável é feito para elevar o estoque a um nível alvo [4].

2.1.2. Custos Envolvidos

Os principais custos na gestão de estoques são:

  • Custo de Pedido (Ordering Cost): Associado à emissão e processamento de um pedido, incluindo custos administrativos, de transporte e de recebimento.
  • Custo de Manutenção (Holding Cost): Relacionado à posse do estoque, incluindo capital empatado, armazenagem, obsolescência, seguro e perdas.
  • Custo de Falta (Shortage Cost): Decorrente da incapacidade de atender à demanda, podendo ser perda de vendas, insatisfação do cliente ou custos de produção acelerada [3].

2.1.3. Tipos de Demanda e Lead Time

A demanda pode ser determinística, quando é conhecida e constante, ou probabilística (estocástica), quando varia aleatoriamente. A maioria dos cenários reais envolve demanda probabilística, o que exige o uso de estoque de segurança para mitigar riscos de falta. O lead time (tempo de reposição) é o tempo entre a emissão de um pedido e o recebimento do produto. A variabilidade no lead time também é um fator crítico que influencia a necessidade de estoque de segurança [5].

2.2. Processos de Chegada com Distribuição de Poisson

Um Processo de Poisson é um modelo estocástico que descreve o número de eventos que ocorrem em um intervalo de tempo fixo ou em uma região específica, dado que esses eventos ocorrem com uma taxa média constante e independentemente uns dos outros. É amplamente utilizado para modelar chegadas de clientes em sistemas de fila, ocorrências de falhas em equipamentos, e, crucialmente, a demanda em sistemas de estoque [6].

2.2.1. Propriedades do Processo de Poisson

As principais propriedades de um processo de Poisson com taxa \(\lambda\) são:

  • Estacionariedade: A probabilidade de um evento ocorrer em um intervalo de tempo depende apenas do comprimento do intervalo, não de sua localização no tempo.

  • Independência de Incrementos: O número de eventos em intervalos de tempo disjuntos são variáveis aleatórias independentes.

  • Distribuição Exponencial dos Tempos Entre Chegadas: Se o número de chegadas segue uma distribuição de Poisson, então o tempo entre chegadas consecutivas segue uma distribuição exponencial com média \(1/\lambda\). A função de densidade de probabilidade (PDF) para o tempo entre chegadas \(T\) é:

    \[ f(t) = \lambda e^{-\lambda t} \quad \text{para } t \ge 0 \]

  • Distribuição de Poisson para o Número de Chegadas: O número de chegadas \(N(t)\) em um intervalo de tempo de duração \(t\) segue uma distribuição de Poisson com parâmetro \(\lambda t\). A função de massa de probabilidade (PMF) é:

    \[ P(N(t) = k) = \frac{e^{-\lambda t} (\lambda t)^k}{k!} \quad \text{para } k = 0, 1, 2, \dots \]

2.2.2. Aplicações e Relação com Processos de Markov

Processos de Poisson são fundamentais em Teoria das Filas, onde modelam a chegada de clientes a um sistema. Em estoques, são usados para representar a demanda por itens em períodos de tempo. A simplicidade e as propriedades matemáticas dos processos de Poisson os tornam ideais para simulações de eventos discretos. Além disso, há uma forte relação entre processos de Poisson e Processos de Markov, especialmente em cadeias de Markov de tempo contínuo, onde as transições entre estados ocorrem de acordo com taxas exponenciais, análogas aos tempos entre chegadas de Poisson [7].

3. Metodologia de Simulação

A simulação de sistemas de estoque com demanda e lead time estocásticos, modelados por processos de Poisson, é uma ferramenta essencial para a análise de desempenho e a tomada de decisões. A linguagem R, com seus pacotes estatísticos e de simulação, é particularmente adequada para essa finalidade.

3.1. Modelagem da Chegada de Clientes/Demanda

Para simular a demanda de clientes ou a chegada de pedidos usando um processo de Poisson, o primeiro passo é definir a taxa média de chegada (\(\lambda\)). Por exemplo, se a demanda média diária é de 10 unidades, então \(\lambda = 10\) unidades/dia. A geração de eventos de demanda pode ser feita de duas maneiras principais:

  1. Geração do Número de Eventos em um Intervalo: Para simular a demanda em um dia, pode-se gerar um número aleatório a partir de uma distribuição de Poisson com parâmetro \(\lambda \times 1\) (se \(\lambda\) for a taxa diária). Em R, isso pode ser feito com rpois(n=1, lambda = lambda_diaria).
  2. Geração dos Tempos Entre Eventos: Alternativamente, pode-se gerar os tempos entre chegadas consecutivas usando uma distribuição exponencial com taxa \(\lambda\). Em R, rexp(n=1, rate = lambda) geraria o tempo até a próxima chegada. A soma desses tempos determinaria quando o próximo evento de demanda ocorreria.

3.2. Integração com Modelos de Estoque

A integração da demanda simulada com os modelos de estoque permite avaliar o impacto da variabilidade. Por exemplo, em um sistema de revisão contínua (Q-system), a simulação pode rastrear o nível de estoque ao longo do tempo, registrando quando o ROP é atingido e quando os pedidos são feitos e recebidos. A variabilidade na demanda (modelada por Poisson) e no lead time (que também pode ser modelado por uma distribuição, como a uniforme ou normal, ou até mesmo exponencial) afetará a frequência de pedidos, os níveis de estoque de segurança necessários e a ocorrência de faltas.

Ao simular, é possível coletar métricas de desempenho como:

  • Nível médio de estoque
  • Número de faltas e seu custo associado
  • Número de pedidos e seu custo associado
  • Custo total do sistema de estoque

Essas métricas permitem comparar diferentes políticas de estoque (e.g., diferentes ROPs ou tamanhos de pedido) e identificar a que melhor se adapta às condições de demanda e lead time estocásticas. A simulação oferece um ambiente controlado para experimentação, onde os parâmetros do sistema podem ser ajustados e seus efeitos observados sem risco real.

3.3 Método de Monte Carlo

O Método de Monte Carlo é uma técnica estocástica utilizada para resolver problemas complexos por meio de simulações baseadas em amostragem aleatória. Trata-se de um método amplamente empregado em diversas áreas da ciência e, particularmente, na simulação computacional de sistemas logísticos e de produção, devido à sua capacidade de modelar incertezas e comportamentos aleatórios de variáveis. Em contextos como o gerenciamento de estoques, o Método de Monte Carlo permite simular diferentes cenários de demanda, lead time e falhas no abastecimento, fornecendo uma visão mais robusta sobre o desempenho de políticas de estoque sob incertezas.

A base do método consiste em repetir um experimento computacional diversas vezes, utilizando números pseudoaleatórios para representar os eventos incertos. Com isso, é possível estimar distribuições, médias, variâncias, probabilidades e outros parâmetros de interesse a partir da análise estatística dos resultados simulados.

Por exemplo, ao se considerar a chegada de pedidos de clientes como um processo de Poisson e o tempo de reposição de estoque como uma variável aleatória (como distribuição exponencial ou uniforme), pode-se utilizar Monte Carlo para avaliar a probabilidade de ruptura de estoque, o nível médio de inventário e o custo total esperado, com base em 1.000 ou mais simulações do ciclo de operação.

4 Simulação

4.1 Modelo de Simulação de Estoque: O Caso da Distribuidora de Bicicletas

Esta simulação computacional representa o comportamento de um sistema de controle de estoque para um único produto, neste caso, bicicletas em uma distribuidora atacadista. A simulação não busca apenas oferecer uma abordagem conceitual, mas sim aplicar a teoria em um cenário prático, onde variáveis como demanda mensal incerta e custos operacionais são incorporadas na modelagem. Os parâmetros utilizados, como custos e a descrição do problema, foram adaptados do “Exemplo 2: Distribuição Atacadista de Bicycles”, apresentado no capítulo de referência sobre Teoria dos Estoques, conferindo ao modelo uma base mais realista e fundamentada.

Este relatório detalha a estrutura e a lógica de um script em R desenvolvido para simular e avaliar uma política de controle de estoque do tipo (s, Q) (ponto de ressuprimento, quantidade de pedido). O modelo utiliza o método de Monte Carlo, executando 1000 réplicas de uma simulação de 36 meses para analisar o comportamento estocástico do sistema. A demanda mensal é modelada como um processo de Poisson para refletir sua natureza aleatória. O objetivo do script é fornecer métricas de desempenho físicas (nível de estoque) e financeiras (custos de pedido, manutenção e falta, giro de estoque e nível de serviço) para apoiar a tomada de decisão gerencial.

Essa simulação ilustra a potência do uso de técnicas de simulação estocástica mesmo em contextos iniciais, e destaca como a estatística computacional pode contribuir para a compreensão e análise de fenômenos operacionais em ambientes de incerteza.

# Carregar a biblioteca para gráficos
library(ggplot2)
library(scales) # Adicionado para formatação de percentual

# Usar set.seed garante que os resultados "aleatórios" sejam os mesmos toda vez
set.seed(666)

# 1. PARÂMETROS

# Parâmetros da simulação para o ATACADISTA DE BICICLETAS
meses_simulados <- 36
simulacoes <- 1000
lambda_demanda <- 250
lead_time <- 0.5
ponto_ressuprimento <- 150
quantidade_pedido <- 300
estoque_inicial <- 300

# Parâmetros de Custo (baseados no livro)
custo_pedido <- 200.00
custo_holding_unit <- 1.00
custo_falta_unit <- 15.00
custo_unitario_produto <- 35.00

# 2. DEFINIÇÃO DA FUNÇÃO DE SIMULAÇÃO

simular_estoque_df <- function(meses, lambda, lead, reord_point, qtd_pedido, estoque_ini,
                               cost_order, cost_hold, cost_short) {
  
  demanda <- rpois(meses, lambda)
  pedidos_em_andamento <- rep(0, meses + ceiling(lead) + 1)
  estoque_atual <- estoque_ini
  
  estoque <- numeric(meses)
  pedido_chega <- numeric(meses)
  unidades_faltantes <- numeric(meses)
  pedido_ativo <- FALSE
  dia_chegada_prevista <- Inf
  
  custo_pedido_dia <- numeric(meses)
  custo_holding_dia <- numeric(meses)
  custo_falta_dia <- numeric(meses)

  for (mes in 1:meses) {
    
    if (mes >= dia_chegada_prevista) {
      estoque_atual <- estoque_atual + quantidade_pedido
      pedido_chega[mes] <- quantidade_pedido
      pedido_ativo <- FALSE
      dia_chegada_prevista <- Inf
    }
    
    if (estoque_atual < demanda[mes]) {
      unidades_faltantes[mes] <- demanda[mes] - estoque_atual
      custo_falta_dia[mes] <- unidades_faltantes[mes] * cost_short
    }
    
    estoque_atual <- estoque_atual - demanda[mes]
    if (estoque_atual < 0) estoque_atual <- 0
    
    estoque[mes] <- estoque_atual
    custo_holding_dia[mes] <- estoque[mes] * cost_hold
    
    if (estoque_atual <= reord_point && !pedido_ativo) {
      pedido_ativo <- TRUE
      dia_chegada_prevista <- mes + lead_time
      custo_pedido_dia[mes] <- cost_order
    }
  }
  
  df <- data.frame(
    Mes = 1:meses, Demanda = demanda, Estoque = estoque,
    PedidoChega = pedido_chega, UnidadesFaltantes = unidades_faltantes,
    CustoPedidoDia = custo_pedido_dia, CustoHoldingDia = custo_holding_dia,
    CustoFaltaDia = custo_falta_dia
  )
  return(df)
}


# 3. ANÁLISE DE UMA ÚNICA SIMULAÇÃO

# 3.1. Executando a simulação uma única vez
df_simulacao_unica <- simular_estoque_df(
  meses = meses_simulados, lambda = lambda_demanda, lead = lead_time,
  reord_point = ponto_ressuprimento, qtd_pedido = quantidade_pedido,
  estoque_ini = estoque_inicial, cost_order = custo_pedido,
  cost_hold = custo_holding_unit, cost_short = custo_falta_unit
)

# 3.2. Resumo da Simulação Única em Tabela

custo_pedido_unico <- sum(df_simulacao_unica$CustoPedidoDia)
custo_holding_unico <- sum(df_simulacao_unica$CustoHoldingDia)
custo_falta_unico <- sum(df_simulacao_unica$CustoFaltaDia)
custo_total_unico <- custo_pedido_unico + custo_holding_unico + custo_falta_unico
demanda_media <- mean(df_simulacao_unica$Demanda)
estoque_medio <- mean(df_simulacao_unica$Estoque)
total_faltas <- sum(df_simulacao_unica$UnidadesFaltantes)

tabela_resumo_unica <- data.frame(
  Métrica = c(
    "Custo Total de Pedidos",
    "Custo Total de Manutenção",
    "Custo Total de Falta",
    "CUSTO TOTAL DA SIMULAÇÃO",
    "---", # Usamos isso como um separador visual
    "Demanda Média Mensal",
    "Estoque Médio Mensal",
    "Total de Unidades Faltantes"
  ),
  Valor = c(
    custo_pedido_unico,
    custo_holding_unico,
    custo_falta_unico,
    custo_total_unico,
    "", 
    demanda_media,
    estoque_medio,
    total_faltas
  )
)

knitr::kable(
  tabela_resumo_unica,
  caption = "Resumo Completo da Simulação Individual",
  col.names = c("Métrica", "Valor"),
  digits = 2, # Arredonda os números para 2 casas decimais
  format.args = list(decimal.mark = ",", big.mark = ".") # Formato de número para o Brasil
)
Resumo Completo da Simulação Individual
Métrica Valor
Custo Total de Pedidos 5800
Custo Total de Manutenção 3135
Custo Total de Falta 6225
CUSTO TOTAL DA SIMULAÇÃO 15160
Demanda Média Mensal 249.388888888889
Estoque Médio Mensal 87.0833333333333
Total de Unidades Faltantes 415
# --- BLOCO DE CÓDIGO ATUALIZADO PARA O GRÁFICO DA SIMULAÇÃO ÚNICA ---

# 3.4. Gerando o gráfico do estoque da simulação única
grafico_simulacao_unica <- ggplot(df_simulacao_unica, aes(x = Mes, y = Estoque)) +
  
  # A linha principal do estoque
  geom_line(aes(color = "Estoque Mensal"), linewidth = 1) + 
  geom_point(color = "darkblue", alpha = 0.5) +
  
  labs(
    title = "Evolução do Estoque em Uma Simulação Individual",
    subtitle = NULL, 
    y = "Nível de Estoque (Bicicletas)", x = "Mês",
    color = "Legenda"
  ) +
  
  # A escala de cores agora só precisa definir a cor para o "Estoque Mensal"
  scale_color_manual(values = c("Estoque Mensal" = "darkblue")) +
  
  theme_minimal()

print(grafico_simulacao_unica)

# 4. SIMULAÇÃO DE MONTE CARLO (1000 Réplicas)

# Vetores para armazenar resultados
custos_totais_mc <- numeric(simulacoes)
custos_pedido_mc <- numeric(simulacoes)
custos_holding_mc <- numeric(simulacoes)
custos_falta_mc <- numeric(simulacoes)
giro_estoque_mc <- numeric(simulacoes)
fill_rate_mc <- numeric(simulacoes)

for (i in 1:simulacoes) {
  resultado <- simular_estoque_df(
    meses = meses_simulados, lambda = lambda_demanda, lead = lead_time,
    reord_point = ponto_ressuprimento, qtd_pedido = quantidade_pedido,
    estoque_ini = estoque_inicial, cost_order = custo_pedido,
    cost_hold = custo_holding_unit, cost_short = custo_falta_unit
  )
  
  custos_pedido_mc[i] <- sum(resultado$CustoPedidoDia)
  custos_holding_mc[i] <- sum(resultado$CustoHoldingDia)
  custos_falta_mc[i] <- sum(resultado$CustoFaltaDia)
  custos_totais_mc[i] <- custos_pedido_mc[i] + custos_holding_mc[i] + custos_falta_mc[i]
  
  unidades_atendidas <- sum(resultado$Demanda) - sum(resultado$UnidadesFaltantes)
  estoque_medio_unidades <- mean(resultado$Estoque)
  if (estoque_medio_unidades > 0) {
    giro_estoque_mc[i] <- unidades_atendidas / estoque_medio_unidades
  } else {
    giro_estoque_mc[i] <- 0
  }
  
  demanda_total <- sum(resultado$Demanda)
  if (demanda_total > 0) {
      fill_rate_mc[i] <- unidades_atendidas / demanda_total
  } else {
      fill_rate_mc[i] <- 1
  }
}


# 5. ANÁLISE DOS RESULTADOS AGREGADOS

# Resumo Custo Total
print("Resumo do Custo Total por Simulação:")
## [1] "Resumo do Custo Total por Simulação:"
print(summary(custos_totais_mc))
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   12984   16246   17080   17031   17826   20636
# Decomposição do Custo Médio
df_custo_medio <- data.frame(
  Componente = c("Custo de Manutenção", "Custo de Pedido", "Custo de Falta"),
  ValorMedio = c(mean(custos_holding_mc), mean(custos_pedido_mc), mean(custos_falta_mc))
)
grafico_decomp_custo <- ggplot(df_custo_medio, aes(x = reorder(Componente, -ValorMedio), y = ValorMedio, fill = Componente)) +
  geom_bar(stat = "identity", color = "black") +
  geom_text(aes(label = paste0("R$ ", round(ValorMedio, 2))), vjust = -0.5, size = 4) +
  labs(
    title = "Decomposição do Custo Total Médio",
    x = "Componente de Custo", y = "Custo Médio (R$)"
  ) +
  theme_minimal() + theme(legend.position = "none")
print(grafico_decomp_custo)

# 6. ANÁLISE DOS KPIs: GIRO E NÍVEL DE SERVIÇO
print("ANÁLISE DOS KPIs DE DESEMPENHO")
## [1] "ANÁLISE DOS KPIs DE DESEMPENHO"
# Análise do Giro de Estoque
giro_medio_periodo <- mean(giro_estoque_mc)
giro_anualizado <- giro_medio_periodo * (12 / meses_simulados)
cat(paste("\nO giro médio anualizado é de aproximadamente:", round(giro_anualizado, 2), "vezes ao ano.\n"))
## 
## O giro médio anualizado é de aproximadamente: 32.17 vezes ao ano.
# Análise do Nível de Serviço (Fill Rate)
fill_rate_medio <- mean(fill_rate_mc)
cat(paste("O Nível de Serviço médio (Fill Rate) é de:", scales::percent(fill_rate_medio), "\n\n"))
## O Nível de Serviço médio (Fill Rate) é de: 94%
# Gráfico do Nível de Serviço (Fill Rate)
grafico_dist_fill_rate <- ggplot(data.frame(FillRate = fill_rate_mc), aes(x = FillRate)) +
  geom_histogram(bins = 30, fill = "dodgerblue", color = "black", alpha = 0.7) +
  scale_x_continuous(labels = scales::percent) +
  geom_vline(aes(xintercept = mean(FillRate)), color = "red", linetype = "dashed", size = 1) +
  labs(
    title = "Distribuição do Nível de Serviço (Fill Rate)",
    subtitle = paste0("Média (linha vermelha) = ", scales::percent(mean(fill_rate_mc))),
    x = "Fill Rate",
    y = "Frequência (Nº de Simulações)"
  ) +
  theme_minimal()
print(grafico_dist_fill_rate)

4.1.1 Conclusão

A simulação da política de estoque (s=150, Q=300) para o distribuidor de bicicletas revelou um custo total médio de R$ 17.031 por período de 36 meses. A maior parcela deste custo (42%) vem da manutenção do estoque, sugerindo que uma redução nos níveis de estoque poderia ser benéfica. No entanto, o nível de serviço médio de 94% indica que faltas de estoque já ocorrem. Isso aponta para um clássico trade-off: aumentar o estoque de segurança para melhorar o nível de serviço elevaria ainda mais o custo de manutenção, enquanto reduzi-lo para economizar agravaria as faltas. A próxima etapa seria rodar a simulação com diferentes valores de s e Q para encontrar um melhor ponto de equilíbrio.

5. Referências

[1] Hillier, F. S., & Lieberman, G. J. (2015). Introduction to Operations Research. 10th ed.  -Hill Education.

[2] Banks, J., Carson, J. S., Nelson, B. L., & Nicol, D. M. (2010). Discrete-Event System Simulation. 5th ed. Pearson Education.

[3] Nahmias, S. (2009). Production and Operations Analysis. 6th ed. McGraw-Hill/Irwin.

[4] Silver, E. A., Pyke, D. F., & Peterson, R. (1998). Inventory Management and Production Planning and Scheduling. 3rd ed. John Wiley & Sons.

[5] Gross, D., & Harris, C. M. (1998). Fundamentals of Queueing Theory. 3rd ed. John Wiley & Sons.

[6] Ross, S. M. (2013). Simulation. 5th ed. Academic Press.

[7] Ross, S. M. (2014). Introduction to Probability Models. 11th ed. Academic Press.