Ağaç setleri için veri yapısı.


10

Denemeler, eleman listelerinin verimli bir şekilde saklanmasını sağlar. Ön ekler paylaşılır, böylece alan etkili olur.

Ağaçları verimli bir şekilde depolamak için benzer bir yol arıyorum. Üyelik olup olmadığını kontrol etmek ve eleman eklemek, belirli bir ağacın saklanan bazı ağaçların bir alt ağacı olup olmadığını veya verilen ağacın bir alt ağacı olan depolanmış bir ağaç olup olmadığını bilmek de istenir.

Tipik olarak, 50'den az yükseklikte yaklaşık 500 dengesiz ikili ağacı depolarım.

DÜZENLE

Benim uygulama bir tür memoization kullanarak model denetleyicisi bir türüdür. Bir devlet var düşünün ve aşağıdaki formüller: ve ile olmanın karmaşık altformülü, ve ben ilk olmadığını bilmek istiyorum hayal içinde tutan . Olmadığını kontrol tutan ve uzun bir süreçten sonra ben böyle olduğunu elde ederiz. Şimdi, bilmek istiyorum içinde tutan . Ben gerçeği hatırlamak istiyoruz tutan ve bildirime o yüzden türetebilirsiniz o içinde neredeyse anında.f = ϕ g = ( ϕ ψ ) ϕ f s ϕ g s f g f g s g t f tsf=ϕg=(ϕψ)ϕfsϕgsfgfgs
Bunu kanıtladık Tersine, içinde tutmaz , o zaman ben şunu söylemek istiyorum içinde tutmaz neredeyse anında.gtft

Bu formüller üzerinde kısmi bir düzen oluşturmak ve sahip olabilir IFF . Her devlet için , biz formüller iki set saklamak; , tutan maksimum formülleri ve tutmayan en düşük formülleri saklar. Şimdi durum verilen ve bir formül , ben görebilir durumunda, ya da durumda ben yapılır ve doğrudan tutup tutmadığını biliyorum .g f s L ( s ) l ( s ) s g f L ( s ) , f g f l ( s ) , g f g sgfgfsL(s)l(s)sgfL(s),fgfl(s),gfgs

Şu anda, ve liste olarak uygulanmaktadır ve bu açıkça optimal değildir, çünkü saklanan tüm formülleri tek tek yinelemem gerekir. Formüllerim sekanslarsa ve kısmi sıra "öneki ise" bir üçlü daha hızlı olabilirdi. Ne yazık ki formüllerim , modal operatör ve atomik önermelere dayanan bir ağaç yapısına sahip .l ¬ , Ll¬,

@Raphael ve @Jack'in işaret ettiği gibi, ağaçları sıralı hale getirebilirim, ancak korkarım bunun sorunu çözmeyeceğinden korkuyorum çünkü ilgilendiğim kısmi düzen "önekidir".


Sadece hızlı bir fikir: Ağaçları sıraya dizmeyi denediniz mi (sıralı bir geçiş gerçekleştirin, ziyaret edilen düğümleri buna göre listeleyin ve yukarı aşağı hareketler için özel elemanlar ekleyin) ve bunları üç kat halinde sakladınız mı? Tabii ki, bu bir anlamda sol alt ağaçların kontrolüne "sadece" izin verirdi.
Raphael

2
Ne basit bir seri kullanılırsa aşağıdaki özelliği ile ağaçların: T bir alt ağaçtır T ' ancak ve ancak S ( T ) de bir alt S ( T ' ) ? Böyle bir S'yi inşa etmek basittir [eğer ağaçlarınızın kanonik bir formunu ilk bulursanız]. Bundan sonra, sorunuz stringolojide yaygın olarak incelenen bir sorun olan alt dize eşleşmesine eşdeğerdir. STTS(T)S(T)S
Jukka Suomela

1
Bir göz atın vadeli endeksleme .
starblue

1
Başka bir hızlı fikir, tüm ağaçları t1, t2, .. bir büyük ağaç T'de saklamak, her kenar için parçası olduğu ağaç kümesini hatırlamak olacaktır. Daha sonra, f'nin saklanan ağaçlardan birinin bir alt ağacı olup olmadığını belirlemek için önce f'nin T'de bir alt ağaç olup olmadığını ve evet ise, o alt ağacın tüm kenar-etiket kümeleriyle kesişirsiniz. Kavşak boş değilse cevap evettir. (İki adımı da birleştirebilirsiniz).
Martin

Yanıtlar:


5

G-try'lara göz atmak isteyebilirsiniz . Bu aslında aradığınız veri yapısıdır, ancak sadece ağaçlar yerine genel grafiklerle kullanılmak üzere tasarlanmıştır. Bu nedenle, g-denemelerinin iyi teorik garantilere sahip olduğundan emin değilim - bir grafik kanonizasyon algoritmasını altyordam olarak kullandıklarını düşünüyorum - ama pratikte iyi çalışıyor gibi görünüyorlar.

(Bağlantılı makalenin "biyolojik ağlardaki ağ motifleri" ile ilgili olduğundan korkmayın: g-trie grafikler için son derece iyi bir soyut veri yapısıdır.)


4

Bunun özel bir biçimi kalıcılıktır : Driscoll, Sarnak, Sleator & Tarjan ve Sarnak & Tarjan'ın Kalıcı Arama Ağaçlarını Kullanarak Veri Yapılarını Kalıcı Yapma başlıklı makalelere bakınız.


1
Referanslar için teşekkürler. Veri Yapılarını Şu Anda Kalıcı Hale Getirememe erişemiyorum , ancak kalıcılık kavramına biraz aşinayım. Ancak, sorunumu çözmek için kalıcılığı nasıl kullanabileceğimi göremiyorum. Aslında ağaçları boole ile eşleyen sözlükler kullanmak istiyorum ve aynı ağaç farklı sözlüklerdeki farklı değerlerin anahtarı olabilir.
Abdallah

1
Uygulamanızın ne olduğundan emin olmadığımdan, önekleri paylaşarak dizeleri saklayan denemelere benzetmenizi tetikledim. Bununla birlikte, "aynı ağaç farklı sözlüklerdeki farklı değerlerin anahtarı olabilir" yorumunuz da denemelere uymuyor gibi görünüyor. Belki de sadece bir ağacın (ve tüm alt ağaçlarının) arayabileceğiniz bir imza koleksiyonu istersiniz? (örneğin, ikili ağaçlar için Katalanca sayıları veya etiketli ağaçlar için Prufer kodlarını kullanma.)
Jack

1

Bu biraz bir ormana benziyor ( ayrık setli ormanlar ) ...

Bu bir teknik denilen aracılığıyla yerleştirme maliyetini amorti rütbesi ile birlik ve kullanan arama operasyonu yolu sıkıştırma . Sylvain Conchon ve Jean-Christophe Filliâtre tarafından geliştirilen bu yapının kalıcı bir versiyonu olduğunu biliyorum , ancak Jack'in bahsettiği ile aynı olup olmadığı hakkında hiçbir fikrim yok ...



0

"Tamamen Fonksiyonel Veri Yapıları" nda (1998), Chris Okasaki tip toplama (10.3.2) kullanarak ikili ağaçların denemesini önermektedir.

Bunun derhal işe yarayıp yaramadığını bilmiyorum; orada verilen çözüm doğrudan uygulanamayabilir.


0

Programcı dilinde: Ağaçları ortak alt ifadelerden / ağaçlar / DAG'lardan oluşturursanız, güzel bir kompakt modeliniz olur. Böylece Yönlendirilmiş Asiklik Grafikler. Sonra bir dizi ağaç yeterli olurdu.

public class Tree {Dize işlemi; Ağaç [] alt ağaçları;

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;
}

...}

Ortak haritaSubExpressions = yeni HashMap ();

Tree get (Dize expressionSyntax) {Ağaç t = yeni Ağaç (); t.çalışma = ...; t.subtrees = ... alt ifadeleri almak için özyinelemeli çağrı; Ağaç t2 = commonSubExpressions.get (t); eğer (t2 == null) {t2 = t; commonSubExpressions.put (t2, t2); } dönüş t2; }}

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.