Qual é a melhor maneira de acompanhar a mediana?


8

Li uma pergunta e estou procurando informações sobre como resolvê-la:

Os números são gerados aleatoriamente e armazenados em uma matriz (em expansão). Como você acompanharia a mediana?

Existem duas estruturas de dados que podem resolver o problema. Uma é a árvore binária balanceada, a outra são duas pilhas que rastreiam a metade maior e a menor metade dos elementos. Acho que essas duas soluções têm o mesmo tempo de execução O(n lg n), mas não tenho certeza do meu julgamento.

Qual é a melhor maneira de acompanhar a mediana?

Minha tentativa:

Nesta questão, acho que um monte é a melhor maneira de acompanhar a mediana. Existem dois montões, o grande e o pequeno, que não precisam ser seqüenciais. Primeiro, calculamos o valor médio dos elementos na matriz. Se o elemento for menor que o valor médio, colocaremos o num no pequeno heap. Pelo contrário, colocamos o num no monte grande. Se o número da pilha grande for igual ao número da pilha pequena, o maior na pilha pequena e o menor na pilha grande será a mediana. Se os dois heaps tiverem tamanho diferente, basta colocar o elemento raiz do heap com tamanho maior e empurrá-lo para a raiz do heap de tamanho menor. Para heap grande, o elemento raiz é o menor e, para heap pequeno, o elemento raiz é o maior. Dessa forma, se os dois montões tiverem o mesmo tamanho ou uma diferença digital,

Penso que esta solução tem o tempo de execução como O (m * n), m significa os tempos em que ajustamos os montes de desequilíbrio.

Essa é a melhor maneira de acompanhar a mediana?


Se você só precisar rastrear a mediana, os dois terão essencialmente a mesma complexidade, mas a abordagem baseada em heap usará menos memória (sua estrutura está implícita em vez de exigir ponteiros) e geralmente mais rápido também (porque normalmente é armazenado de forma contígua, o que geralmente melhorará o uso do cache).
Jerry Coffin

2
stackoverflow.com/questions/2579912/… seria uma solução linear se você quisesse.
JB rei

2
Hehe - std::nth_elementalguém?
precisa

5
Isso realmente soa mais como uma pergunta para SO do que aqui.
Mark B

O valor médio pode ser muito enganador a ponto de não ter sentido. Imaginando, você tem muitos números pequenos (digamos 1..999) e 10 ^ 8. O valor médio para esses 1000 números é ~ 10 ^ 5, então você acaba colocando tudo menos 10 ^ 8 na pilha pequena. Portanto, o algoritmo tem um mau comportamento de pior caso.
user281377

Respostas:


1

Provavelmente, existem mais de 2 estruturas de dados que resolvem esse problema. Dê uma olhada nas medianas aproximadas e outros quantiles em um passe e com memória limitada

Eles não usam dois montões. Eu imagino que você possa modificar o algoritmo deles para obter periodicamente um valor aproximado em execução da mediana. O quão boa uma aproximação dependeria, é claro, de muitos fatores, e o menos importante é a quantidade de dados que passaram pelo algoritmo.


0

Uma solução melhor é usar uma lista de pulos. Como a lista na qual você estará inserindo é sempre mantida como uma lista classificada (pelo fato de como você a está construindo), a complexidade da inserção é O (log n). Você aproveitará o fato de que a primeira inserção fornece a mediana a custo zero (o item inserido é a mediana). Após cada inserção adicional, sua lista ainda é classificada e a própria mediana será aumentada ou diminuída por um único índice, e essa comparação é O (1).

Complexidade total = O (log n)


A complexidade total de cada elemento é O(log n)- a inserção de n elementos tem uma complexidade deO(n log n)
Greg Jackson

1
Certamente, mas para uma "mediana corrente", pode-se argumentar que você está inserindo um conjunto ilimitado de elementos, mas faz pouco sentido dizer que a complexidade é O (log infinito n). ;-)
Michael Hays

Eh ... ok, minha resposta pode não ser melhor do que pilhas. A pilha de Fibonacci possui uma inserção de O (1) e uma exclusão de O (lg n). Eu apenas nunca o usei.
Michael Hays

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.