Một cấu trúc dữ liệu cho các bộ cây.


10

Tries cho phép lưu trữ hiệu quả danh sách các yếu tố. Các tiền tố được chia sẻ để nó là không gian hiệu quả.

Tôi đang tìm kiếm một cách tương tự để lưu trữ cây hiệu quả. Tôi muốn có thể kiểm tra tư cách thành viên và thêm các yếu tố, biết nếu một cây nhất định là cây con của một số cây được lưu trữ hoặc nếu có một cây được lưu trữ là cây con của cây đã cho cũng là điều mong muốn.

Tôi thường sẽ lưu trữ khoảng 500 cây nhị phân không cân bằng có chiều cao dưới 50.

BIÊN TẬP

Ứng dụng của tôi là một số loại trình kiểm tra mô hình bằng cách sử dụng một số loại ghi nhớ. Hãy tưởng tượng tôi có một trạng thái và các công thức sau: và với là một subformula phức tạp, và tưởng tượng đầu tiên tôi muốn biết nếu giữ trong . Tôi kiểm tra nếu giữ và sau một quá trình dài tôi nhận được rằng đó là trường hợp. Bây giờ, tôi muốn biết nếu giữ trong . Tôi muốn nhớ thực tế là giữ và để ý rằng để tôi có thể lấy được trong gần như ngay lập tức.f = ϕ g = ( ϕ ψ ) ϕ f s ϕ g s f g f g sSf= =φg= =(φψ)φfSφgSfgfgS
Ngược lại, nếu tôi đã chứng minh rằng không giữ trong , thì tôi muốn nói rằng không giữ trong gần như ngay lập tức.t f tgtft

Chúng ta có thể xây dựng một thứ tự một phần trên các công thức và có iff . Đối với mỗi trạng thái , chúng tôi lưu trữ hai bộ công thức; lưu trữ các công thức tối đa giữ và lưu trữ các công thức tối thiểu không giữ. Ngay bây giờ cho một trạng thái và một công thức , tôi có thể thấy nếu , hoặc nếu trong trường hợp này tôi thực hiện và tôi biết trực tiếp liệu giữ trong .g f s L ( s ) l ( s ) s g f L ( s ) , f g f l ( s ) , g f g sgfgfSL(S)tôi(S)SgfL(S),fgftôi(S),gfgS

Hiện tại, và được triển khai dưới dạng danh sách và điều này rõ ràng là không tối ưu vì tôi cần lặp lại thông qua tất cả các công thức được lưu trữ riêng lẻ. Nếu các công thức của tôi là các chuỗi và nếu thứ tự từng phần là "là tiền tố của" thì một bộ ba có thể chứng minh nhanh hơn nhiều. Thật không may, các công thức của tôi có cấu trúc giống như cây dựa trên , toán tử phương thức và các mệnh đề nguyên tử.Ltôi¬,

Như @Raphael và @Jack chỉ ra, tôi có thể tuần tự hóa các cây, nhưng tôi sợ nó sẽ không giải quyết được vấn đề vì thứ tự một phần tôi quan tâm sẽ không tương ứng với "là tiền tố của".


Chỉ là một ý tưởng nhanh: Bạn đã thử các cây tuần tự (thực hiện một giao dịch theo thứ tự, liệt kê các nút được truy cập phù hợp và thêm các yếu tố đặc biệt để tăng tốc độ di chuyển xuống) và lưu trữ chúng trong một trie chưa? Tất nhiên, điều này sẽ "chỉ" cho phép kiểm tra các cây con bên trái, theo một nghĩa nào đó.
Raphael

2
Điều gì sẽ xảy ra nếu bạn chỉ đơn giản sử dụng một chuỗi của các cây với thuộc tính sau: là một cây con của T khi và chỉ khi S ( T ) là một chuỗi con của S ( T ) ? Xây dựng một S như vậy là đơn giản [nếu bạn lần đầu tiên tìm thấy một hình thức chính tắc của cây của bạn]. Sau đó, câu hỏi của bạn tương đương với kết hợp chuỗi con, đây là một vấn đề được nghiên cứu rộng rãi trong chuỗi. STT'S(T)S(T')S
Jukka Suomela

1
Hãy nhìn vào chỉ mục hạn .
starblue

1
Một ý tưởng nhanh khác là lưu trữ tất cả các cây t1, t2, .. trong một cây lớn T, ghi nhớ cho mỗi cạnh của bộ cây mà nó là một phần của. Sau đó, để xác định xem f có phải là cây con của một trong những cây được lưu trữ hay không, trước tiên bạn xác định xem f có phải là cây con trong T không và nếu có, sau đó cắt tất cả các bộ nhãn cạnh của cây con đó. Câu trả lời là có, nếu giao lộ không trống. (Bạn cũng có thể kết hợp hai bước).
Martin B.

Câu trả lời:


5

Bạn có thể muốn kiểm tra g-thử . Đây thực chất là cấu trúc dữ liệu bạn đang tìm kiếm, nhưng được thiết kế để sử dụng với các biểu đồ chung thay vì chỉ cây. Như vậy, tôi không chắc chắn rằng g-try có các đảm bảo lý thuyết tốt - tôi nghĩ rằng họ sử dụng thuật toán chuẩn hóa đồ thị như một chương trình con - nhưng trong thực tế, chúng có vẻ hoạt động tốt.

(Đừng sợ rằng bài báo được liên kết là về "họa tiết mạng trong mạng sinh học": g-trie là một cấu trúc dữ liệu trừu tượng hoàn toàn tốt cho đồ thị.)


4

Một dạng đặc biệt của điều này là sự kiên trì : Xem các bài viết Tạo cấu trúc dữ liệu liên tục bởi Driscoll, Sarnak, Sleator, & Tarjan và Planar Point Location sử dụng Cây tìm kiếm liên tục của Sarnak & Tarjan, nơi lưu trữ các họ cây liên quan.


1
Cảm ơn bạn đã tham khảo. Hiện tại tôi không thể truy cập vào Cấu trúc dữ liệu liên tục , nhưng tôi có phần quen thuộc với khái niệm về tính bền vững. Tuy nhiên, tôi không thấy làm thế nào tôi có thể sử dụng kiên trì để giải quyết vấn đề của mình. Tôi thực sự muốn sử dụng các từ điển ánh xạ cây thành boolean và cùng một cây có thể là chìa khóa cho các giá trị khác nhau trong các từ điển khác nhau.
Abdallah

1
Vì tôi không chắc ứng dụng của bạn là gì, tôi đã kích hoạt tính năng tương tự của bạn để thử, lưu trữ chuỗi bằng cách chia sẻ tiền tố. Nhận xét của bạn rằng "cùng một cây có thể là chìa khóa cho các giá trị khác nhau trong các từ điển khác nhau", tuy nhiên dường như không phù hợp với các lần thử. Có lẽ bạn chỉ muốn một số bộ sưu tập chữ ký cho một cây (và tất cả các cây con của nó) mà bạn có thể tra cứu? (ví dụ: sử dụng số Catalan cho cây nhị phân hoặc mã Prufer cho cây có nhãn.)
Jack

1

Điều này nghe hơi giống một khu rừng (những khu rừng tách biệt ) ...

Nó khấu hao chi phí chèn thông qua một kỹ thuật gọi là union theo thứ hạng và thao tác tìm kiếm bằng cách sử dụng nén đường dẫn . Tôi biết cũng có một phiên bản bền bỉ của cấu trúc này được phát triển bởi Sylvain Conchon và Jean-Christophe Filliâtre nhưng tôi không biết liệu đây có giống như cái mà Jack đề cập ...



0

Trong "Cấu trúc dữ liệu chức năng thuần túy" (1998), Chris Okasaki đề xuất thử các cây nhị phân bằng cách sử dụng tập hợp kiểu (10.3.2).

Tôi không biết điều này ngay lập tức có ích; giải pháp đưa ra có thể không thể thực hiện trực tiếp.


0

Trong biệt ngữ lập trình viên: Nếu bạn tạo cây từ các biểu thức con / cây / DAG thông thường, bạn sẽ có một mô hình nhỏ gọn đẹp. Vì vậy, đồ thị Acyclic có hướng. Sau đó, một bộ cây sẽ đủ.

lớp công khai Tree {Chuỗi hoạt động; Cây [] cây con;

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

...}

Bản đồ commonSubExpressions = new HashMap ();

Tree get (String biểu thứcSyntax) {Tree t = new Tree (); hợp tác = ...; t.subtrees = ... cuộc gọi đệ quy để có được các biểu hiện con; Cây t2 = commonSubExpressions.get (t); if (t2 == null) {t2 = t; commonSubExpressions.put (t2, t2); } trả về t2; }}

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.