overbooking / accc.py
FelipeRocha13's picture
Upload accc.py
e5bda07 verified
raw
history blame
4.02 kB
import math
from math import comb
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import streamlit as st
# ----------------- Funções auxiliares -----------------
def prob_binom(n, k, p):
if k < 0 or k > n:
return 0.0
return comb(n, k) * (p**k) * ((1-p)**(n-k))
def prob_overbooking(n, c, p):
k_vals = np.arange(c+1, n+1)
if len(k_vals) == 0:
return 0.0
probs = [prob_binom(n, int(k), p) for k in k_vals]
return float(np.sum(probs))
def expected_bumped(n, c, p):
ks = np.arange(c+1, n+1)
if len(ks) == 0:
return 0.0
vals = [(k - c) * prob_binom(n, int(k), p) for k in ks]
return float(np.sum(vals))
def expected_profit(n, c, p, R, C_marg, C_over):
EX = n * p
E_bumped = expected_bumped(n, c, p)
return n*R - EX*C_marg - E_bumped*C_over
# ----------------- Interface Streamlit -----------------
st.title("Análise de Overbooking - Aérea Confiável ✈️")
# Parâmetros de entrada
st.sidebar.header("Parâmetros")
capacidade = st.sidebar.number_input("Capacidade do avião", min_value=50, max_value=300, value=120)
vendidas_alvo = st.sidebar.number_input("Passagens vendidas", min_value=capacidade, max_value=capacidade+50, value=130)
p_comparecer = st.sidebar.slider("Probabilidade de comparecimento (%)", 0.5, 1.0, 0.88, 0.01)
R = st.sidebar.number_input("Receita média por bilhete (R$)", min_value=100.0, value=800.0, step=50.0)
C_marg = st.sidebar.number_input("Custo marginal por passageiro presente (R$)", min_value=50.0, value=150.0, step=10.0)
C_over = st.sidebar.number_input("Custo médio por passageiro preterido (R$)", min_value=500.0, value=1500.0, step=50.0)
# ----------------- Cálculos -----------------
# Probabilidade para cenário alvo
prob_over_130 = prob_overbooking(vendidas_alvo, capacidade, p_comparecer)
st.subheader("1️⃣ Probabilidade de Overbooking")
st.write(f"Com **{vendidas_alvo} passagens vendidas**, capacidade de **{capacidade}**, e p={p_comparecer:.2f}, a probabilidade de overbooking é:")
st.metric("Risco de Overbooking", f"{prob_over_130*100:.2f}%")
# ----------------- Variação do risco -----------------
n_min = capacidade
n_max = capacidade + 30
Ns = list(range(n_min, n_max + 1))
probs = [prob_overbooking(n, capacidade, p_comparecer) for n in Ns]
df_risco = pd.DataFrame({
"Passagens Vendidas": Ns,
"Probabilidade Overbooking (%)": [p*100 for p in probs]
})
limite = 0.07
viaveis = df_risco[df_risco["Probabilidade Overbooking (%)"] <= limite*100]
st.subheader("2️⃣ Variação do risco por número de passagens vendidas")
st.dataframe(df_risco)
# Gráfico
fig, ax = plt.subplots()
ax.plot(df_risco["Passagens Vendidas"], df_risco["Probabilidade Overbooking (%)"])
ax.axhline(limite*100, linestyle="--", label="Limite 7%")
ax.set_title("Risco de Overbooking x Passagens Vendidas")
ax.set_xlabel("Passagens Vendidas")
ax.set_ylabel("Probabilidade (%)")
ax.grid(True)
ax.legend()
st.pyplot(fig)
# ----------------- Análise Financeira -----------------
st.subheader("3️⃣ Análise Financeira")
cenarios = [capacidade + d for d in [0, 5, 10, 15]]
resultados = []
for n in cenarios:
lucro = expected_profit(n, capacidade, p_comparecer, R, C_marg, C_over)
risco = prob_overbooking(n, capacidade, p_comparecer)
bumped_esp = expected_bumped(n, capacidade, p_comparecer)
resultados.append({
"Passagens Vendidas": n,
"Probabilidade Overbooking (%)": round(risco*100, 3),
"Passageiros Preteridos (Esperado)": round(bumped_esp, 2),
"Lucro Esperado (R$)": round(lucro, 2)
})
df_fin = pd.DataFrame(resultados)
st.dataframe(df_fin)
st.write("""
- O risco aumenta conforme mais passagens são vendidas.
- O lucro pode crescer até certo ponto, mas o custo de overbooking pode inviabilizar a estratégia.
- O objetivo é equilibrar **risco aceitável (<=7%)** e **maximização do lucro**.
""")