Após uma contagem de, pelo menos, uma hora em um sistema que apresente fila de espera, preferencialmente com mais de um servidor, o aluno deverá apresentar respostas às perguntas que serão apresentadas a seguir.
In [1]:
from datetime import datetime, timedelta
from IPython.display import display
from math import factorial
from matplotlib import pyplot as plt
import io
import numpy as np
import pandas as pd
Σ = sum
%matplotlib inline
In [2]:
def timetable(a, b):
return b + timedelta(minutes=int(a))
v_timetable = np.vectorize(timetable)
In [3]:
def sampling_generator(
size: int=20, initial_datetime: datetime=None
) -> np.array:
"""
"""
if initial_datetime is None:
initial_datetime = datetime.now()
return v_timetable(
np.random.randint(0, 60, size=size),
datetime.now()
)
In [4]:
def mean_diff_time(se_time: pd.Series) -> float:
"""
"""
n = se_time.shape[0]
l_diff = [0] * (n-1)
for i in range(1, n):
j = i-1
l_diff[j] = (se_time[i] - se_time[j]).seconds/60
return np.mean(l_diff)
In [5]:
initial_datetime = datetime.now()
df_chegada = pd.DataFrame({
'entrada': sampling_generator(
initial_datetime=initial_datetime
)
}).sort_values(by='entrada').reset_index(drop=True)
df_saida = pd.DataFrame({
'saída': sampling_generator(
initial_datetime=initial_datetime
)
}).sort_values(by='saída').reset_index(drop=True)
"""
fig, ax = plt.subplots(1, 2)
df_chegada.hist(ax=ax[0])
df_saida.hist(ax=ax[1])
plt.show()
"""
print('tables head')
display(df_chegada.head())
display(df_saida.head())
a) Descrição do sistema de filas, local, data e horários da coleta de dados:
Fila do tipo: FIFO
Local: loja Plazafone
Início da coleta:
In [6]:
initial_datetime.strftime('%d de %b de %Y - %l:%M%p')
Out[6]:
b) Número de servidores atendendo = S:
In [7]:
S = 3
print('S:', S)
c) O tempo médio entre as chegadas à fila ( um cliente a cada 5 min, por ex.):
In [8]:
μ_chegada = mean_diff_time(df_chegada['entrada'])
# fixando los valores para teste
μ_chegada = 3.05263157895
print('μ_chegada:', μ_chegada, 'mins')
d) A taxa de chegada de usuários no sistema de filas – λ ( clientes por unidade de tempo):
$\lambda = \frac{60 min}{\mu\_chegada} (clientes/hora)$
In [9]:
λ = 60/μ_chegada
print('λ:', λ)
e) O tempo médio de atendimento de cada cliente ( 20 min, por ex.):
In [10]:
μ_atendimento = mean_diff_time(df_saida['saída'])
# fixando valores para teste
μ_atendimento = 2.84210526316
print('μ_atendimento:', μ_atendimento, 'mins')
f) A taxa de atendimento dos usuários – μ ( clientes por unidade de tempo, por servidor:
$\mu = \frac{60 min}{\mu\_atendimento} (clientes/hora)$
Se existir mais que um servidor, a taxa de atendimento do sistema será multiplicada pelo número de servidores:
In [11]:
μ = 60/(μ_atendimento*S)
print('μ:', μ, 'clientes/hora')
g) A ocupação do sistema(em porcentagem);
$\rho = \frac{\lambda}{S*\mu} * 100 (\%)$
In [12]:
ρ = (λ/(S*μ))*100
print('ρ:', ρ, '%')
h) A probabilidade de o sistema estar vazio:
$$ P_0 = [ \sum\limits_{n=0}^{S-1} (\frac{(\lambda / \mu)^n}{n!}) + \frac{(\lambda/\mu)^S}{S!(1-(\lambda/(S.\mu)))} ]^{-1} $$
In [13]:
P_0 = (
Σ([(((λ/μ)**n)/(factorial(n))) for n in range(S)]) +
(((λ/μ)**S)/(factorial(S) * (1-(λ/(S*μ)))))
)**(-1)
print('P_0:', P_0)
i) A probabilidade de todos os servidores estarem ocupados:
$ P_{ocupados} = P(n \leq S) = \frac{(\lambda/\mu)^S}{S!(1-\lambda/(S.\mu))}.P_0 $
In [14]:
P_ocupados = (((λ/μ)**S)/(factorial(S)*(1-(λ/(S*μ))))) * P_0
print('P_ocupados:', P_ocupados)
k) O número esperado de usuários na fila:
$ L_q = \frac{(\lambda/\mu)^S . \lambda . \mu . S}{S!(\mu . S - \lambda)^2} . P_0 $
In [15]:
L_q = ((((λ/μ)**S)*λ*μ*S)/(factorial(S)*((μ*S-λ)**2)))*P_0
print('L_q:', L_q, 'usuários na fila')
j) O número esperado de usuários no sistema:
$ L = L_q + \frac{\lambda}{\mu} $
In [16]:
L = L_q + (λ/μ)
print('L:', L, 'usuários no sistema')
l) O tempo médio dos usuários na fila:
$ W_q = \frac{L_q}{\lambda} $
In [17]:
W_q = L_q/λ
print('W_q:', W_q, 'horas')
m) O tempo provável dos usuários no sistema:
$ W = \frac{L}{\lambda} $
In [18]:
W = L/λ
print('W:', W, 'horas')
n) Se a taxa de chamadas duplicasse, o que aconteceria com o sistema? E quais as providências que deveriam ser tomadas.
In [19]:
p_dobro = ((λ*2)/(S*μ))
print('p_dobro:', p_dobro*100, '%')
if p_dobro < 1:
print('Ok: o sistema atinge a estabilidade')
else:
print('O sistema não atinge a estabilidade')
Antes de pensar em aumentar a quantidade de servidores, deve ser feito um estudo para identificar se é possível otimizar o tempo de atendimento que pode estar sendo prejudicado por algum procedimento ineficiente ou por lentidão dos rescursos computacionais ou de falta de habilidade do servidor. Depois de haver otimização dos recursos, caso não for suficiente, deverá ser avaliada a opção de aumentar o número de servidores nos horários críticos ou apresentar uma proposta para facilitar o atendimento, como pré-atendimento online ou alguma facilidade extra em horários de pouco fluxo de entrada de clientes
In [20]:
# dados de teste providos pelo professor
t_S = 3
t_λ = 19.655 # Clientes/hora
t_μ = 7.037 # Clientes/hora
t_ρ = 0.93 # %
t_P_0 = 0.016570 # 1,657 % - Probabilidade 0 clientes
# Prob S clientes no sistema 0.060176 -> 6,018 %
t_P_ocupados = 0.87251 # 87,251 %
t_L_q = 11.78 # clientes
t_L = 14.57 # clientes - Número médio clientes no sistema
t_W_q = 0.599 # horas - Tempo médio de espera na fila
t_W = 0.741 # horas - Tempo médio de espera sistema
np.testing.assert_approx_equal(S, t_S)
np.testing.assert_approx_equal(λ, t_λ, 3)
np.testing.assert_approx_equal(μ, t_μ, 3)
np.testing.assert_approx_equal(ρ, t_ρ*100, 1)
np.testing.assert_approx_equal(P_0, t_P_0, 3)
np.testing.assert_approx_equal(P_ocupados, t_P_ocupados, 3)
np.testing.assert_approx_equal(L_q, t_L_q, 3)
np.testing.assert_approx_equal(L, t_L, 3)
np.testing.assert_approx_equal(W_q, W_q, 3)
np.testing.assert_approx_equal(W, t_W, 3)