Existe uma estrutura de dados que ofereça suporte eficiente às seguintes operações?
- Adicionar conjunto
- Pergunte se algum subconjunto de um conjunto foi adicionado.
Isso pode ser implementado com sobrecarga linear, testando todos os conjuntos adicionados durante cada consulta. Pode ser implementado com mais eficiência? Pequenas probabilidades de falsos positivos / negativos são aceitáveis (por exemplo, estilo de filtro Bloom).
data-structures
Elliot Gorokhovsky
fonte
fonte
Respostas:
Digamos que todos os seus conjuntos sejam subconjuntos finitos deN . DeixeiS⊆P(N) denotar seu conjunto de conjuntos.
Você quer duas operações:
Aqui estão algumas idéias para acelerar as coisas:
Você vai testar se um conjunto se um subconjunto de outro muito, então você provavelmente deve manter o tamanho|s| de cada conjunto s disponível em O(1) para que quando você precisar testar se s⊆s′ , você começa verificando se |s|≤|s′| e se não, você pode retornar falso imediatamente. E você realmente tem|s|≤|s′| , basta executar o teste lento normal.
Observe que se você tivers1∈S e s2∈S , de modo a s1⊆s2 , então se s2⊆s′ , você também tem s1⊆s′ . Então você não precisa manters2 no S para O2 . Então você pode representarS por um conjunto de conjuntos para que s∈S e s⊊s′ implica s′∉S . Em outras palavras, você só precisa acompanhar os conjuntos emS que são mínimos para inclusão. Isso pode ser implementado com bastante eficiência: Ao adicionar um conjuntos′ , para todos os conjuntos s∈S de modo a |s|≤|s′| (ordenado pelo aumento do cardeal), se s⊆s′ , então não adicione s′ porque não será mínimo (ou já está em S ) Caso contrário, adiciones′ e depois entre conjuntos s∈S de modo a |s′|<|s| , remova-os para que s′⊆s (porque eles não são mais mínimos).
Mantenha um conjuntot isso é igual à união de todos os conjuntos S . Então, ao invés de correrO2(S,s′) , você pode correr O2(S,s′∩t) em vez disso (porque se por algum s∈S , s⊆s′ então desde s⊆t , s⊆s′∩t e se s⊆s′∩t , então s⊆s′∩t⊆s′ )
Com essas idéias em mente, eu representariaS por um dictionnary (implementado como uma lista duplamente ligada de pares (key,value) com as teclas em ordem crescente) d de modo a d(k) é uma lista duplamente vinculada que contém exatamente o mínimo (para inclusão) de conjuntos S do cardeal k .
(Observe que, embora eu não tenha feito isso explicitamente no código de
O1
, você pode fazer uma única travessia da lista duplamente vinculada que representad
)Não acho que isso melhore muito no pior dos casos, mas, em média, deveria.
fonte