Suponha que eu tenha um alfabeto de n símbolos. Eu posso codificá-los eficientemente com-bits strings. Por exemplo, se n = 8:
A: 0 0 0
B: 0 0 1
C: 0 1 0
D: 0 1 1
E: 1 0 0
F: 1 0 1
G: 1 1 0
H: 1 1 1
Agora eu tenho a restrição adicional de que cada coluna deve conter no máximo p bits definidos como 1. Por exemplo, para p = 2 (en = 8), uma solução possível é:
A: 0 0 0 0 0
B: 0 0 0 0 1
C: 0 0 1 0 0
D: 0 0 1 1 0
E: 0 1 0 0 0
F: 0 1 0 1 0
G: 1 0 0 0 0
H: 1 0 0 0 1
Dados nep, existe um algoritmo para encontrar uma codificação ideal (menor comprimento)? (e pode-se provar que calcula uma solução ideal?)
EDITAR
Até agora, foram propostas duas abordagens para estimar um limite mais baixo do número de bits . O objetivo desta seção é fornecer uma análise e uma comparação das duas respostas, a fim de explicar a escolha da melhor resposta .
A abordagem de Yuval é baseada em entropia e fornece um limite inferior muito bom: Onde .
A abordagem de Alex é baseada em combinatória. Se desenvolvermos um pouco mais o raciocínio dele, também é possível calcular um limite inferior muito bom:
Dado o número de bits , existe um único de tal modo que
Agora, dado e , tente estimar . Nós sabemos isso então se , então . Isso fornece o limite inferior para. Primeiro calcule o então encontre o maior de tal modo que
É isso que obtemos se traçarmos, por , os dois limites inferiores juntos, o limite inferior com base na entropia em verde, o baseado no raciocínio combinatório acima em azul, obtemos:
Ambos parecem muito semelhantes. No entanto, se traçarmos a diferença entre os dois limites inferiores, ficará claro que o limite inferior baseado no raciocínio combinatório é melhor no geral, especialmente para valores pequenos de.
Eu acredito que o problema vem do fato de que a desigualdade é mais fraco quando fica menor, porque as coordenadas individuais se correlacionam com pequenas . No entanto, este ainda é um limite inferior muito bom quando.
Aqui está o script (python3) que foi usado para calcular os limites inferiores:
from scipy.misc import comb
from math import log, ceil, floor
from matplotlib.pyplot import plot, show, legend, xlabel, ylabel
# compute p_m
def lowerp(n, m):
acc = 1
k = 0
while acc + comb(m, k+1) < n:
acc+=comb(m, k+1)
k+=1
pm = 0
for i in range(k):
pm += comb(m-1, i)
return pm + ceil((n-acc)*(k+1)/m)
if __name__ == '__main__':
n = 100
# compute lower bound based on combinatorics
pm = [lowerp(n, m) for m in range(ceil(log(n)/log(2)), n)]
mp = []
p = 1
i = len(pm) - 1
while i>= 0:
while i>=0 and pm[i] <= p: i-=1
mp.append(i+ceil(log(n)/log(2)))
p+=1
plot(range(1, p), mp)
# compute lower bound based on entropy
lb = [ceil(log(n)/(p/n*log(n/p)+(n-p)/n*log(n/(n-p)))) for p in range(1,p)]
plot(range(1, p), lb)
xlabel('p')
ylabel('m')
show()
# plot diff
plot(range(1, p), [a-b for a, b in zip(mp, lb)])
xlabel('p')
ylabel('m')
show()