As tentativas permitem o armazenamento eficiente de listas de elementos. Os prefixos são compartilhados e, portanto, economizam espaço.
Estou procurando uma maneira semelhante de armazenar árvores com eficiência. Eu gostaria de poder verificar a associação e adicionar elementos, sabendo se uma determinada árvore é uma subárvore de algumas árvores armazenadas ou se existe uma árvore armazenada sendo uma subárvore da árvore especificada também é desejável.
Normalmente, eu armazenava cerca de 500 árvores binárias desequilibradas de altura menor que 50.
EDITAR
Meu aplicativo é algum tipo de verificador de modelo usando algum tipo de memorização. Imagine que eu tenha um estado e as seguintes fórmulas: e com ser uma subfórmula complexo, e imaginar Primeiro eu quero saber se tem em . Verifico se mantém e, após um longo processo, obtenho que é esse o caso. Agora, quero saber se contém . Gostaria de lembrar o fato de que detém e de notar que para que eu possa derivar in quase instantaneamente.f = φ g = ( φ ∨ ip ) φ f s φ g s f g ⇒ f g s
Por outro lado, se eu provei que não se sustenta , então quero dizer que não se sustenta quase que instantaneamente.t f t
Podemos construir uma ordem parcial em fórmulas e ter iff . Para cada estado , armazenamos dois conjuntos de fórmulas; armazena as fórmulas máximas que retêm e armazena as fórmulas mínimas que não retêm. Agora, dado um estado e uma fórmula , posso ver se , ou se , caso em que estou feito e sei diretamente se contém .g ⇒ f s L ( s ) l ( s ) s g ∃ f ∈ L ( s ) , f ⇒ g ∃ f ∈ l ( s ) , g ⇒ f g s
Atualmente, e são implementados como listas e isso claramente não é o ideal, pois preciso percorrer todas as fórmulas armazenadas individualmente. Se minhas fórmulas fossem sequências e se a ordem parcial fosse "é um prefixo de", um teste poderia ser muito mais rápido. Infelizmente, minhas fórmulas têm uma estrutura de árvore com base em , um operador modal e proposições atômicas.l ¬ , ∧
Como @Raphael e @Jack apontam, eu poderia sequenciar as árvores, mas temo que isso não resolva o problema porque a ordem parcial em que estou interessado não corresponderia a "é um prefixo de".
fonte
Respostas:
Você pode querer conferir g-try . Essa é essencialmente a estrutura de dados que você está procurando, mas projetada para uso com gráficos gerais em vez de apenas árvores. Como tal, não tenho certeza de que as tentativas g tenham boas garantias teóricas - acho que elas usam um algoritmo de canonização de grafos como uma sub-rotina - mas na prática elas parecem funcionar bem.
(Não tenha medo de que o artigo vinculado seja sobre "motivos de rede em redes biológicas": o g-trie é uma estrutura de dados abstrata perfeitamente boa para gráficos.)
fonte
Uma forma especial disso é a persistência : consulte os documentos Tornando as estruturas de dados persistentes por Driscoll, Sarnak, Sleator e Tarjan e Localização de ponto planar usando árvores de pesquisa persistente por Sarnak & Tarjan, que armazenam famílias de árvores relacionadas.
fonte
Isso soa um pouco como uma floresta (florestas desarticuladas ) ...
Ele amortiza o custo de inserção por meio de uma técnica chamada união por classificação e a operação de pesquisa usando a compactação de caminho . Sei que há também uma versão persistente dessa estrutura desenvolvida por Sylvain Conchon e Jean-Christophe Filliâtre, mas não tenho idéia se é a mesma que Jack menciona ...
fonte
E quanto aos autômatos mínimos de árvore ?
fonte
Em "Estruturas de dados puramente funcionais" (1998), Chris Okasaki propõe tentativas de árvores binárias usando agregação de tipos (10.3.2).
Não sei se isso ajuda imediatamente; a solução fornecida pode não ser implementável diretamente.
fonte
No jargão do programador: Se você criar as árvores a partir de subexpressões / árvores / DAGs comuns, você teria um bom modelo compacto. Gráficos acíclicos direcionados. Então um conjunto de árvores seria suficiente.
classe pública Tree {String operation; Árvore [] subárvores;
...}
Mapa commonSubExpressions = new HashMap ();
Tree get (String expressionSyntax) {Árvore t = nova Árvore (); t.operação = ...; t.subtrees = ... chamada recursiva para obter subexpressões; Árvore t2 = commonSubExpressions.get (t); if (t2 == nulo) {t2 = t; commonSubExpressions.put (t2, t2); } retornar t2; }}
fonte