מילון למחרוזות - Trie Lecture of Geiger & Itai s slide brochure www.cs.technion.ac.il/~dang/courseds מבני נתונים למחרוזות Trie מאפשר חיפוש, הכנסה, הוצאה, ומציאת מינימום (לקסיקוגרפי) של מחרוזות. המימוש באמצעות עץ. לכל צומת פנימי יש לכל היותר מספר ילדים כגודל האלף- בית + אחד. כל קשת מסומנת בתו. התו (שאינו שייך ל- ) מסמן סיום מחרוזת. אנו נתייחס למקרים בהם הגודל של קבוע. דוגמא: Trie עבור המחרוזות,,, כאשר תו סיום-המחרוזת הוא הקטן ביותר לקסיקוגרפית. הערה: בכל צומת מוחזק מערך באורך + של מצביעים לבנים. כל מחרוזת במבנה מגדירה מסלול מהשורש אל עלה. כל הפעולות מתבצעות ע"י מעקב לאורך המסלול המתאים. סיבוכיות המימוש: הזמן הנדרש לביצוען נקבע ע"י אורך המחרוזת ( ) (ולא ע"י מספרן של המחרוזות ). המקום: לינארי בסכום אורכי המחרוזות במבנה. cs, Technion 2 חומר קריאה לשיעור זה Algorithms on, Trees, and Sequences, Dan Gustfield Chapter 5, 7., 7., 7.7 cs, Technion מימוש חיפוש, הכנסה והוצאה מבנה צומת בTrie הגדרת צומת: חיפוש( ): נתחיל בשורש. 0. כל עוד : אם התו ה- במחרוזת הוא התו ה- בא"ב, נעקוב אחרי המצביע ה- במערך. אם המצביע הזה,NULL נחזיר "לא נמצא". אחרת, +. אם, > החזר "נמצא". הכנסה( ): בדומה לחיפוש, אבל אם ניתקל במצביע NULL במהלך החיפוש, נקצה צומת חדש ונדאג שהמצביע המתאים בצומת הנוכחי יצביע אליו, ונמשיך בחיפוש בצומת החדש. הוצאה( ): נחפש את המחרוזת ונשמור את הצומת האחרון בעל יותר מבחן אחד לאורך מסלול החיפוש ואת האות הבאה של. נמחק את תת העץ המתאים של. הצומת עבור הסרת המחרוזת #define SIGMA 26; typedef struct node { struct node[ SIGMA + ] *sons ; } NODE ; NODE *root ; cs, Technion cs, Technion
מיון מחרוזות באמצעות Trie מיון מחרוזות נאיבי קלט: מחרוזות,, שאורכן הכולל הוא פלט: הדפסת המחרוזות בסדר לקסיקוגרפי. ניתן להשתמש בעובדה שלמחרוזות יש מבנה - שרשרת תווים מעל אלף-בית מאורך קבוע - כדי למיינן מהר יותר מאשר ע"י השוואות של מחרוזות. נשתמש ב- Trie באופן הבא: = האלגוריתם. הכנס את.Trie ל-,,.2 עבור על ה- trie לפי סדר preorder וכתוב לפלט את המסלול לכל עלה. (המסלול נמצא במחסנית הרקורסיה). דוגמא: נתונות המחרוזות,,, כאשר תו סיום- מחרוזת הוא (הקטן ביותר לקסיקוגרפית). המחרוזות הממוינות הן.,, פתרון באמצעות מיון מבוסס השוואות: נניח לרגע (לשם פשטות) שאורך כל המחרוזות אחיד ושווה ל-./ השוואת שתי מחרוזות תיקח זמן (/).( ( = לפתרון באמצעות השוואות נדרשות.((/) log ) = ( log ) השוואות ולכן סה"כ נדרש זמן Θ( log ) נראה כעת פתרון בזמן.() cs, Technion 6 cs, Technion 5 דחיסת Trie ניתוח זמנים נסלק מהעץ צמתים בעלי בן אחד ע"י החלפת שרשרת שתסומן בתווית המקודדת את המחרוזת המתאימה. קשתות בקשת בודדת זמן הריצה:. הכנסת דורשת זמן לכן זמן הכנסת כל המחרוזות הוא ).() = (Σ סיור ה- preorder ב- Trie דורש זמן כמספר הצמתים ומספר זה הוא.() המחרוזות אורכי כסכום זמן דורשות הסיור במהלך המתבצעות ההדפסות.() = (Σ ) סה"כ זמן ריצת האלגוריתם:.() ייצוג אפשרי: כל צומת יחזיק מערך בגודל + Σ של לבניו ואת המחרוזות המתאימות לקשתות. מצביעים דוגמא: cs, Technion 8 cs, Technion 7
עץ סיומות Tree) (Suffix דחיסת Trie השפעה על מספר הצמתים עץ סיומות של מחרוזת הוא Trie שבו הוכנסו כל הסיומות של המחרוזת עם תו סיום. דוגמא: עץ סיומות עבור : = לעץ סיומות עשרות שימושים במסגרת אלגוריתמים הפועלים על מחרוזות. אנו נבחן שלושה שימושים (שימושים רבים נוספים מתוארים בספר של :(Gusfield מציאת תת מחרוזת בתוך מחרוזת נתונה (או בתוך רשימת מחרוזות נתונה). מציאת תת מחרוזת ארוכה ביותר המשותפת לשתי רשימות נתונות. מימוש אלגוריתם לדחיסת אינפורמציה compression).(ziv-lempel cs, Technion 0 יהא מספר הצמתים בעץ ו- מספר העלים. עקב הדחיסה, לכל אחד מ ( ) הצמתים הפנימיים יש לפחות שני בנים. טענה: לעץ בו לכל צומת פנימי לפחות 2 בנים, מספר הצמתים מקיים 2 הוכחה: שיקולי ספירת קשתות. כיוון שמדובר בעץ, ולפי התכונות הנ"ל, מתקיים: = Σ 2( ) ומכאן מתקיים.2 לכן לאחר דחיסת Trie מספר הצמתים לינארי במספר העלים (מספר המחרוזות) בTrie. החסכון יהיה משמעותי יותר בהמשך כאשר תוויות הקשתות יהיו מקודדות בצורה קומפקטית. cs, Technion 9 חיסכון הכרחי במקום אלגוריתם לבניית עץ סיומות ניזכר בעץ הסיומות עבור : = (, ) חיסכון במקום: Trie דחוס דורש מקום כסכום אורכי המחרוזות על הקשתות. עבור עץ סיומות מדובר ב- ) Θ( מקום. הראינו כיצד להקטין כיוון אך,() ל- הצמתים מספר את הזיכרון סך הקשתות על מחרוזות ששומרים דרישות את לשפר ניתן כיצד נשאר ).Ω( המקום? פתרון: נשמור העתק נפרד של המחרוזת וכל תווית תהיה זוג מצביעים המציינים את מיקום () תדרוש קשת כל. במחרוזת התווית מקום. סך המקום הנדרש הוא.() למעשה כל אלגוריתם ליניארי לבניית עצי סיומות חייב לייצג = את תוויות הקשתות בצורה לא-ישירה כיון שקיימות סדרות של מחרוזות באורך כך שסכום האורכים של תוויות עץ כתיבת זמן ולכן Θ() מ- גדול של הקשתות הסיומות ידרוש יותר מ-( Θ( זמן (תרגיל בית. רמז: הסתכלו והכלילו את המחרוזת ).((000 00 00 0 00 0 0 (, ) cs, Technion 2 נניח לאורך ההרצאה שאורך המחרוזת הוא. אלגוריתם נאיבי לבניית עץ סיומות עבור : הכנס את המחרוזות ] [ ], [2 ],, [ ל- Trie דחוס את ה- Trie שנוצר. ניתוח זמנים: () = + ( ) + + = ( 2 ) קיימים מספר אלגוריתמים מסובכים בהרבה המאפשרים לבנות עץ סיומות בזמן () (כאשר גודל האלף-בית קבוע). אלגוריתם עם זמן ריצה זה מתואר למשל במאמר: Esco Ukkonen. On-line construction of suffix trees. Algorithmica, :29-60, 995 ובספר של.Gusfield אנו נשתמש באלגוריתם זה כ"קופסא שחורה". cs, Technion
מציאת מחרוזות קצרות בטקסט ארוך אינפורמציה נוספת בעץ סיומות הבעיה: נתונה מחרוזת מאורך הנקראת טקסט. לאחר זמן עיבוד ליניארי () של הטקסט, יש להיות מוכנים לקבל מחרוזת לא ידועה באורך ולמצוא מופע של בטקסט (המופע הראשון) או לקבוע שהמחרוזת אינה נמצאת בטקסט. שימו לב שכל פתרון העובר על הטקסט בזמן קבלת המחרוזת ללא עיבוד מוקדם של יאלץ לבצע לפחות Θ() פעולות. דוגמאות לשימושים:. הטקסט הוא האנציקלופדיה בריטניקה והמחרוזת היא מילה. 2. הטקסט הוא הגנום של אורגניזם כלשהו, כלומר מחרוזת ארוכה של האותיות {,},,, והמחרוזת היא סדרה של אותיות כאלה המקודדת גן אותו יש למצוא בגנום הנתון. הערה: כמובן שקיימות וריאציות לבעיה זו כגון מציאת כל המופעים של בטקסט הנתון, התאמה חלקית של לטקסט, או חיפוש בתוך אוסף טקסטים. הנחה: << כלומר המחרוזת המבוקשת קצרה יחסית לאורך הטקסט. cs, Technion נבחן שוב את עץ הסיומות עבור : = ע"י סיור postorder בעץ נוכל בזמן ליניארי () לחשב לכל צומת את המיקום הראשון של תת המחרוזת המיוצגת ע"י המסלול מהשורש ועד. נסמן מיקום ראשוני זה ע"י. 6 2 5 2 למשל: המחרוזת המיוצגת ע"י המסלול (,) מתחילה במקום השני ב- והמחרוזת המיוצגת ע"י המסלול (,) מתחילה במקום החמישי ב-. באופן כללי, עבור עלים מספרים אלה מתקבלים ע"י חיסור מספר התווים המופיעים על המסלול לצומת מהאורך הכללי ועוד אחד (6 = בדוגמא זו). בצמתים פנימיים יירשם המינימום של ערכי הילדים. למשל 2 בצומת, כלומר = 2. אמנם המיקום השמאלי ביותר של המחרוזת ב- הוא 2. cs, Technion דחיסת אינפורמציה אלגוריתם למציאת מחרוזות בטקסט הבעיה: טקסט מילולי (ואחר) המקודד בצורה מפורשת הוא לעיתים ארוך מהנחוץ שכן מילים וחלקי מילים חוזרים על עצמם לאורך הטקסט. המטרה: בהינתן מחרוזת, לייצר מחרוזת התופסת פחות מקום מ- והמכילה את אותה האינפורמציה. השימוש: העברה יעילה של קבצי אינפורמציה במדיום אלקטרוני כגון בדיסקטים, ברשתות תקשורת, וכדומה. למשל פקודות הדחיסה המקובלות winzip ו- compress במערכת Windows ובמערכת. Unix הרעיון: נעבור על המחרוזת הנתונה s משמאל לימין, בכל פעם שעוברים על תת מחרוזת z שכבר ראינו נחליף את z עם האינדקס והאורך של המופע השמאלי ביותר של z במחרוזת s. האלגוריתם המתבסס על רעיון זה נקרא Ziv-Lempel compression והוא מתואר במאמרים: Ziv, Lempel, IEEE Trans on Information Theory, 2:7-, 977. Ziv, Lempel, IEEE Trans on Information Theory, 2:50-68, 978. כמו כן מוכח במאמרים אלה שאסימפטוטית, זהו אלגוריתם דחיסה אופטימלי. cs, Technion 6 בנה בזמן () עץ סיומות עבור הטקסט. הוסף לכל צומת בעץ הסיומות את המספר. בהינתן מחרוזת, עקוב על המסלול מהשורש של עץ הסיומות לפי התווים שבמחרוזת. אם נמצאה המחרוזת, אזי מקום המחרוזת הוא כאשר הוא הצומת האחרון במסלול החיפוש של. הסיומות עץ את שוב ניבחן דוגמא: המחרוזת. = עבור (והרביעי) הראשון במקום נמצאת השני במקום נמצאת והמחרוזת (והחמישי). 6 2 5 2 הערה: למציאת כל המופעים של בטקסט, האלגוריתם מוצא את לכל עלה בתת העץ ששורשו. זמן החיפוש הוא () כאשר הוא מספר המופעים של בטקסט. החסם נובע מכך שכפי שראינו, מספר הצמתים בתת עץ עם עלים קטן מ- 2. בדוגמא, עבור הצומת מתקבל =,. cs, Technion 5
הגדרות וסימונים דוגמאות לדחיסה הגדרה: לכל אינדקס במחרוזת [.],. נגדיר את תת המחרוזת להיות הרישא (Prefix) הארוכה ביותר של [ [.. ואשר מופיעה כתת מחרוזת בתוך )] (.[.. 7 = 2 5 6 8 9 = המחרוזת הנתונה: דוגמא: = = (2,) (2,) (,) דוגמא I: המחרוזת הדחוסה: במקרה זה אין דחיסה כלל. זו תופעה נפוצה עבור מחרוזות קצרות. דוגמא :II המחרוזת הנתונה: המחרוזת הדחוסה: נסמן ב- את אורך המחרוזת. כאשר היא מחרוזת ריקה אז = 0. נסמן ב- את מיקום המחרוזת כאשר > 0. = = (,2) (,) (,8) (,6) 7 = = 7 = 2 בדוגמא : עבור חזרות של נקבל מחרוזת דחוסה באורך (.Θ(log cs, Technion 8 cs, Technion 7 מימוש יעיל של Ziv-Lempel האלגוריתם וניתוחו בנה עץ סיומות עבור המחרוזת בזמן.() חשב את לכל צמתי בזמן.() בכל איטרציה, כאשר האלגוריתם נדרש לחשב את ) ),, צעד על המסלול מהשורש של לפי התווים במחרוזת ] [.. כל עוד, + < כאשר אורך המסלול עד כה. כאשר החיפוש נעצר, לאחר תווים, המקום שווה ל- כאשר הוא הצומת האחרון על מסלול הצעידה...2. for (i=; i <= m; ) { Compute(s i,l i ) ; if L i > 0 {output(s i, L i ); i = i + L i }; else {output(s[i]) ; i = i + } } נתונה המחרוזת ].[.. 6 2 5 2 דוגמא: דחיסת = = (,2) פענוח מחרוזת דחוסה: עבור על המחרוזת משמאל לימין. במקרה של תו, העתק אותו ל-, ובמקרה של זוג ) ),, שכפל את התווים המתחילים במקום. cs, Technion 20 נקודת המפתח במימוש האלגוריתם הוא חישוב ) ), בכל איטרציה. נניח שניתן לממש פעולה זו בזמן ) ( (כפי שנראה), מה יהיה זמן הריצה של האלגוריתם? האלגוריתם קורא את המחרוזת משמאל לימין. האלגוריתם לא מחשב את ) ), עבור אינדקס שכבר נמצא באזור הדחוס. בכל איטרציה האלגוריתם דוחס תווים וקופץ קדימה תווים במחרוזת. לפיכך סכום האורכים שחושבו ע"י האלגוריתם קטן מ- (אין חפיפות), וזמן הריצה.() = = 0 0 2 8 6 דוגמא: האורכים שחושבו : cs, Technion 9
עץ סיומות מוכלל מציאת תת מחרוזת ארוכה משותפת הבעיה: מצא תת מחרוזת ארוכה ביותר המשותפת לשתי מחרוזות נתונות, 2 בזמן ).( + עץ סיומות מוכלל הוא Trie שבו הוכנסו כל הסיומות. לכל מחרוזת עם תו סיום שונה {,.., } קבוצת של מחרוזות 6 5 5 52 2 דוגמא: = superiocalifornialives 2 = sealiver פתרון לדוגמא: תת המחרוזת הארוכה ביותר המשותפת לשתי הנתונות היא.alive תרגיל: מצאו אלגוריתם יעיל ככל שתוכלו ללא שימוש בעצי סיומות. המחרוזות דוגמא: עץ סיומות מוכלל עבור.{ =, 2 = 2 } אלגוריתם נאיבי לבניה: נכניס את כל הסיומות אחת אחת ל- Trie בודד. זמן הריצה כאורך סכום כל הסיומות של כל המחרוזות (במקרה הגרוע בהרבה מסכום אורכי המחרוזות). גדול cs, Technion 22 cs, Technion 2 מציאת תת מחרוזת ארוכה משותפת בנית עץ סיומות מוכלל הרעיון: נבנה עץ סיומות מוכלל המכיל את הסיומות של שתי המחרוזות. נסמן עלה בתווית אם העלה מתאים לסיומת של ובתווית 2 אם העלה מתאים לסיומת של. 2 נסמן צומת פנימי ב- אם כל ילדיו מסומנים ב-, נסמנו ב- 2 אם כל ילדיו מסומנים ב- 2, ונסמנו ב- {,2} אם תוויות ילדיו מכילים גם וגם 2. סימון זה לוקח זמן ליניארי בגודל עץ הסיומות. דוגמא: עץ סיומות מוכלל עבור.{ =, 2 = 2 },2 2,2 2,2 52 2 שורת המחץ: תת המחרוזת הארוכה ביותר המשותפת היא זאת המיוצגת ע"י המסלול הארוך ביותר מהשורש אשר סימון כל הצמתים שלו הוא {,2}. לכן, ע"י סיור נוסף ניתן למצוא את המחרוזת המשותפת הארוכה ביותר. בדוגמא, המחרוזת המשותפת היא או. cs, Technion 2 אלגוריתם ליניארי : נבנה עץ סיומות עבור המחרוזת S = 2 2. נבצע סיור ונקצץ את כל תתי העצים מתחת לקשתות שהתווית שלהן 2. מסתיימת ב-.. ) = (Σ סיבוכיות זמן: דוגמא:.{ =, 2 = 2 } עץ סיומות עבור 2 נראה כך : 6 5 2 תתי העצים המצויירים כמשולש מייצגים סיומות המכילות. סיומות אלה אינן שייכות לאף אחת מהמחרוזות המקוריות. לכן ניתן לגזום את המשולשים הנ"ל מהעץ. cs, Technion 2
מציאת תת מחרוזת ארוכה משותפת ל- מחרוזות הבעיה: מצא תת מחרוזת ארוכה ביותר המשותפת.( + + + ) בזמן,,, ל- מחרוזות נתונות הרעיון כמו קודם: נבנה עץ סיומות מוכלל המכיל את הסיומות של המחרוזות. נסמן את הצמתים ונמצא את המסלול הארוך ביותר מהשורש אשר מסומן בכול אורכו ע"י },.{, דוגמא לשימוש: המחרוזות הנתונות הם הגנום של מספר אורגניזמים, והמחרוזת הארוכה ביותר המשותפת להם עוזרת למציאת התאמות בן הגנומים השונים. כמובן שבשימוש זה נצטרך להכניס מגבלות נוספות, כגון מיקום תת המחרוזת בכל גנום, התאמה חלקית לחלק מהגנומים, מחרוזות משותפות נוספות, וכו'. cs, Technion 26 cs, Technion 25