Prazo de entrega recomendado:
Você deve implementar uma fila de prioridade para balancear tráfego de um roteador.
Um importante componente de uma rede de computadores são os roteadores. Eles são responsáveis por encaminhar pacotes de dados que chegam até eles. Em cada roteador, existe uma fila de prioridades que controla a ordem em que os pacotes são processados e encaminhados. Essa fila serve para garantir a qualidade da rede nos momentos que ela estiver sobrecarregada. Mesmo que o roteador não consiga encaminhar todos os pacotes que recebeu, entregará pelo menos os mais importantes.
Você precisa implementar o firmware de um roteador para um novo protocolo de rede. Nesse protocolo, os pacotes chegam ao roteador com uma prioridade predefinida além de uma taxa de incremento. O roteador deve guardar os pacotes enquanto a rede estiver congestionada. Sempre que a rede se desobstrui, o roteador emite um tick e os $k$ pacotes com prioridades mais altas são encaminhados.
Logo depois que os pacotes são enviados, a prioridade de cada pacote
remanescente é aumentada de sua taxa de incremento. Por exemplo, se um
pacote remanescente A
tinha prioridade $5$ e incremento $1$ e outro
pacote B
tinha prioridade $2$ e incremento $3$, depois do primeiro
tick, esses pacotes terão prioridades $6$ e $5$, respectivamente. Se
depois do próximo tick esses pacotes ainda não forem encaminhados,
então o pacote A
passará a ter prioridade $7$ e pacote B
passará a
ter prioridade $8$, passando à frente na fila de prioridades.
Como o roteador tem memória limitada, ele só tem capacidade para armazenar até $m$ pacotes na fila. Infelizmente, isso significa que, enquanto a rede está muito congestionada e a fila está cheia, os pacotes que chegam são descartados, independentemente de suas prioridades.
Entrada
A primeira linha contém a configuração do roteador com os números $k$
e $m$. Cada linha seguinte contém três números inteiros e representa
um pacote ou um tick. Um pacote tem a forma <id> <prioridade> <incremento>
, em que <id>
é um inteiro positivo identificando o
pacote. Um tick é representado por uma linha 0 0 0
.
A entrada deve ser lida até o fim do arquivo EOF.
Exemplo de entrada
11 99
1 1 1
2 2 1
3 3 1
4 4 1
5 5 1
6 6 1
7 7 1
8 8 1
0 0 0
9 9 1
10 10 1
11 11 1
12 12 1
13 13 1
14 14 1
15 15 1
0 0 0
Saída
A cada tick, deve ser impressa uma linha com o número do tick e
uma linha com os dados atualizados <id> <prioridade> <incremento>
de
cada pacote enviado. As colunas podem ser separadas por um caractere
de tabulação ou espaço. Veja o exemplo abaixo.
Exemplo de saída
TICK 1
8 8 1
7 7 1
6 6 1
5 5 1
4 4 1
3 3 1
2 2 1
1 1 1
TICK 2
15 15 1
14 14 1
13 13 1
12 12 1
11 11 1
10 10 1
9 9 1
Dicas e sugestões
Para ler uma sequência de linhas até o final de arquivo, você pode
verificar o retorno do scanf
, como no exemplo.
while (scanf(...) != EOF){ ... }
Escreva o algoritmo antes de programar e teste cada parte do programa
com calma: verifique se a leitura está correta, teste
separadamente cada operação da fila de prioridade utilizada, etc.
Sempre é útil criar também uma função para mostrar a estrutura de
dados. Enquanto está testando o algoritmo, chame essa função em cada
iteração do laço principal, ou melhor, aprenda a configurar um
breakpoint no início de cada iteração e chame essa função a partir do
gdb
!
Critérios
Você deve implementar uma fila de prioridades usando um max heap. Sua implementação deve ser eficiente, evitando passar pelos elementos da fila desnecessariamente.
Correção
Esta tarefa será corrigida automaticamente sempre que você realizar um
git push
. Depois de terminada a tarefa, deve-se utilizar o botão na
interface de notas para solicitar a correção de um monitor.
Turma AB: O peso desta tarefa será 4.