Una struttura di dati per gruppi di alberi.


10

I tentativi consentono una memorizzazione efficiente degli elenchi di elementi. I prefissi sono condivisi, quindi è efficiente nello spazio.

Sto cercando un modo simile per conservare gli alberi in modo efficiente. Vorrei poter verificare l'appartenenza e aggiungere elementi, sapendo se un determinato albero è una sottostruttura di alcuni alberi memorizzati o se esiste un albero memorizzato che è una sottostruttura dell'albero specificato è anche desiderabile.

Solitamente conserverei circa 500 alberi binari non bilanciati di altezza inferiore a 50.

MODIFICARE

La mia applicazione è una sorta di modello di controllo che utilizza una sorta di memoization. Immagina di avere uno stato e le seguenti formule: f = ϕ e g = ( ϕ ψ ) con ϕ essendo un subformula complesso, e immagina di voler prima sapere se f vale in s . Controllo se ϕ è valido e dopo un lungo processo ottengo che sia così. Ora voglio sapere se g vale in s . Vorrei ricordare il fatto che f vale e notare che g fsf=ϕg=(ϕψ)ϕfsϕgsfgfin modo che io possa derivare in s quasi all'istante. Al contrario, se ho dimostrato che g non tiene in t , allora voglio dire che f non tiene in t quasi all'istante.gs
gtft

Possiamo costruire un ordine parziale sulle formule e avere iff g f . Per ogni stato s , memorizziamo due serie di formule; L ( s ) memorizza le formule massime che detengono e l ( s ) memorizza le formule minime che non detengono. Ora dato uno stato s e una formula g , posso vedere se f L ( s ) , f g , o se f l ( s )gfgfsL(s)l(s)sgfL(s),fg nel qual caso ho finito e so direttamente se g vale in s .fl(s),gfgs

Attualmente, e L sono implementate come liste e questo non è chiaramente ottimale perché ho bisogno per scorrere tutte le formule memorizzate singolarmente. Se le mie formule fossero sequenze, e se l'ordine parziale fosse "è un prefisso di", un trie potrebbe rivelarsi molto più veloce. Sfortunatamente le mie formule hanno una struttura ad albero basata su ¬ , , un operatore modale e proposizioni atomiche.Ll¬,

Come sottolinea @Raphael e @Jack, potrei sequenziare gli alberi, ma temo che non risolverebbe il problema perché l'ordine parziale a cui sono interessato non corrisponderebbe a "è un prefisso di".


Solo una breve idea: hai provato a sequenzializzare gli alberi (eseguire un attraversamento in ordine, elencare i nodi visitati di conseguenza e aggiungere elementi speciali per i movimenti su e giù) e archiviarli in un trie? Ovviamente, ciò "consentirebbe" solo ai controlli per i sottotitoli di sinistra, in un certo senso.
Raffaello,

2
STTS(T)S(T)S

1
Dai un'occhiata al termine indicizzazione .
Starblue,

1
Un'altra idea veloce sarebbe quella di memorizzare tutti gli alberi t1, t2, .. in un grande albero T, ricordando per ogni bordo l'insieme di alberi di cui fa parte. Quindi, per determinare se f è una sottostruttura di uno degli alberi memorizzati, determinare innanzitutto se f è una sottostruttura in T e se sì, quindi intersecare tutti i set di etichette di bordo di tale sottostruttura. La risposta è sì se l'intersezione non è vuota. (Potresti anche combinare i due passaggi).
Martin B.

Risposte:


5

Potresti voler dare un'occhiata a g-try . Questa è essenzialmente la struttura dei dati che stai cercando, ma progettata per l'uso con grafici generali anziché solo alberi. Pertanto, non sono sicuro che g-try abbia buone garanzie teoriche - penso che utilizzino un algoritmo di canonizzazione dei grafici come subroutine - ma in pratica sembrano funzionare bene.

(Non abbiate paura che il documento collegato riguardi "motivi di rete nelle reti biologiche": il g-trie è una struttura di dati astratti perfettamente valida per i grafici.)


4

Una forma speciale di questo è la persistenza : vedere i documenti Come rendere persistenti le strutture di dati di Driscoll, Sarnak, Sleator e Tarjan e ubicazione dei punti planari usando gli alberi di ricerca persistente di Sarnak e Tarjan, che memorizzano famiglie di alberi correlati.


1
Grazie per i riferimenti. Al momento non riesco ad accedere a Come rendere persistenti le strutture dati , ma ho una certa familiarità con il concetto di persistenza. Tuttavia, non vedo come posso usare la persistenza per risolvere il mio problema. In realtà voglio usare i dizionari che associano gli alberi a valori booleani e lo stesso albero potrebbe essere la chiave per valori diversi in diversi dizionari.
Abdallah,

1
Dato che non ero sicuro di quale fosse la tua applicazione, ho attivato la tua analogia con try, che memorizza le stringhe condividendo i prefissi. Tuttavia, il tuo commento secondo cui "lo stesso albero potrebbe essere la chiave per valori diversi in dizionari diversi" non sembra adattarsi neanche ai tentativi. Forse vuoi solo una raccolta di firme per un albero (e tutti i suoi sottoalberi) che puoi cercare? (ad es. usando numeri catalani per alberi binari o codici Prufer per alberi etichettati.)
Jack

1

Sembra un po 'come una foresta (foreste disgiunte ) ...

Ammortizza il costo dell'inserzione attraverso una tecnica chiamata unione per rango e l'operazione di ricerca usando la compressione del percorso . So che esiste anche una versione persistente di questa struttura sviluppata da Sylvain Conchon e Jean-Christophe Filliâtre, ma non ho idea se questa sia la stessa di quella menzionata da Jack ...



0

In "Purely Functional Data Structures" (1998), Chris Okasaki propone tentativi di alberi binari usando l'aggregazione dei tipi (10.3.2).

Non so se questo aiuti immediatamente; la soluzione fornita potrebbe non essere implementabile direttamente.


0

Nel linguaggio programmatore: se crei gli alberi da sottoespressioni / alberi / DAG comuni, avresti un bel modello compatto. Grafici aciclici così diretti. Quindi sarebbe sufficiente una serie di alberi.

albero di classe pubblica {operazione String; Tree [] subtrees;

public int compareTo(Tree rhs) {
    if (rhs == null) return false;
    int cmp = operation.compareTo(rhs.operation);
    if (cmp == 0) {
        cmp = Arrays.compareTo(subtrees, rhs.subtrees);
    }
    return cmp;
}

...}

Mappa commonSubExpressions = new HashMap ();

Tree get (String expressionSyntax) {Tree t = new Tree (); t.operation = ...; t.subtrees = ... chiamata ricorsiva per ottenere sottoespressioni; Albero t2 = commonSubExpressions.get (t); if (t2 == null) {t2 = t; commonSubExpressions.put (t2, t2); } restituisce t2; }}

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.