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.