מסנן בלום

מסנן בלום (Bloom filter) הוא מבנה נתונים חסכוני במקום בזיכרון מחשב המאפשר לדעת, בהסתברות גבוהה, האם איבר נמצא בקבוצת איברים מסוימת. הוא הומצא בשנת 1970 על ידי בורטון ה. בלום.

בדרך כלל משמש המסנן ככלי עזר לגישה למבנה נתונים אחר, ומאפשר לדעת באופן מהיר האם יש טעם לחפש את האיברים באותו מבנה נתונים או באחר.

ייתכן מצב שבו המסנן יכזיב, ויצביע על איבר שאינו נמצא כאילו הוא נמצא, אך ההפך לא ייתכן. תשובה שלילית לגבי הימצאותו של איבר היא נכונה בוודאות.

==תיאור האלגוריתם==
k}} = 3.

ישנו מערך של m ביטים, שכל אחד מהם שווה ל-0 או ל-1. ערכם ההתחלתי הוא 0.

ישנן k פונקציות ערבול (hash functions) שונות. טווח הפונקציות הוא m-1..0.

כל אימת שמכניסים איבר, מזינים את פונקציות הערבול בערכו (המכונה בדרך כלל:המפתח שלו). מקבלים כתוצאה k אינדקסים של ביטים במערך, אינדקס כתוצאה של כל פונקציה, ואותם "מדליקים" (כלומר משנים את ערכם ל-1).

אחר כך כאשר בודקים האם איבר נמצא, מפעילים את פונקציות הערבול על המפתח של האיבר. אם כל הביטים המתקבלים מהפונקציות דלוקים, יש סבירות גבוהה שהאיבר נמצא (אם כי ייתכן שהביטים הודלקו בשל קיומם של איברים אחרים). אם לא כל הביטים דולקים, ניתן לומר בוודאות גמורה כי האיבר אינו נמצא (אחרת בהכנסתו היו מודלקים הביטים המתקבלים עבורו בערבול).

==ניתוח הסתברותי של השגיאה==

נניח שפונקציות הערבול הן בעלות התפלגות אחידה. ההסתברות שביט מסוים לא יודלק בידי פונקציית ערבול היא <math> 1- \frac{1}{m} </math>.

ההסתברות שביט מסוים לא יודלק בידי אף אחת מפונקציות הערבול היא:

<math>\left(1-\frac{1}{m}\right)^k</math>.

ההסתברות שביט יישאר בערך אפס אחרי הכנסת n איברים היא:

<math>\left(1-\frac{1}{m}\right)^{kn}</math>;

ועל כן ההסתברות שערכו של ביט מסוים יהיה 1 לאחר הכנסת n איברים היא:

<math>1-\left(1-\frac{1}{m}\right)^{kn}</math>.

מה ההסתברות שתתקבל תשובה חיובית עבור איבר שאינו שייך לקבוצת האיברים? <BR> דבר זה יקרה אם כל k הביטים שפונקציות הערבול נותנות עבורו הודלקו.

<math>\left(1-\left(1-\frac{1}{m}\right)^{kn}\right)^k \approx \left(1-e^{-kn/m}\right)^k</math>.

ברור שככל שמספר הביטים במערך גדל, כך קטן הסיכוי לתשובות חיוביות שגויות. ברור גם שהגדלת מספר האיברים המוכנסים מגדילה את הסיכוי לשגיאות.

למספר פונקציות הערבול יש שתי השפעות סותרות: מצד אחד, מפעילים יותר פונקציות ולכן צריך שיודלקו יותר ביטים כדי להשיב שאיבר שייך לקבוצת האיברים. מנגד, בכל פעם שמכניסים איבר, יותר ביטים מודלקים, וממילא גדל הסיכוי שתיווצר בעתיד "התנגשות" שתגרום לתשובה חיובית עבור איברים שאינם נמצאים.

ניתן לחשב שהמספר האופטימלי של פונקציות ערבול עבור m (מספר ביטים) ו-n (מספר איברים) הוא

<math>\frac{m}{n}\ln 2</math>,

וההסתברות לטעות בשאילתה תהיה:

<math>\left(\frac{1}{2^{\ln 2}}\right)^{m/n}</math>.

אם נניח שמקצים 32 ביטים לכל איבר (m=32*n) ומשתמשים ב-13 פונקציות ערבול, הסיכוי לתשובה חיובית בשאילתה עבור איבר שאינו בקבוצה קטן ממיליונית.

== יתרונות וחסרונות ==
מסנן בלום מאפשר לענות על השאילתה האם איבר מסוים שייך לקבוצת איברים מסוימת ללא צורך לשמור את כל איברי הקבוצה באופן מלא ומפורש. על כן גודל הזיכרון שדורש מסנן בלום תלוי במספר האיברים בקבוצה אך לא בזיכרון שתופס כל איבר בקבוצה. יש לכך יתרון כאשר כל איבר בקבוצה תופס זיכרון רב.
טבלת גיבוב רגילה תמיד תענה נכונה על שאילתת השייכות וגם תאפשר גישה לאיבר עצמו אם הוא נמצא בטבלה. ולכן אם נדרשת גישה לאיבר או אם לא ניתן לסבול שגיאה בשאילתת השייכות, טבלת גיבוב רגילה עדיפה. חיסרון נוסף של מסנן בלום הוא שאינו תומך בהוצאת איבר מקבוצה שהרי לא ניתן לכבות את הביטים שהוא הדליק כי אולי גם איברים אחרים הדליקו אותם.

=== ניתוח יעילות ===
באופן נאיבי, אם אורך הקלט הוא l ויש להפעיל עליו k פעמים את אלגוריתם הערבול (שבדרך כלל ליניארי באורך הקלט) הרי שעלות חיפוש איבר בקבוצה וההכנסה של איבר לקבוצה היא kl. עלות זו גבוהה מזו הדרושה למציאת איבר בעזרת חיפוש בטבלת גיבוב רגילה.
ניתן להציע פונקציות ערבול שבהן ניתן להשתמש בתוצאת חישוב ערבול אחד כדי למצוא את תוצאת הערבולים האחרים, לדוגמה SHA-1 MD5 ודומיהן. בעזרת שיטות אלו ניתן להגיע לסיבוכיות k+l.

==מחיקה==

אין אפשרות למחיקת איבר שהוכנס למסנן בלום, והפתרון עלול להיות בנייה מחדש של כל המסנן.

"כיבוי" פשוט של הביטים שפונקציות הערבול כורכות יחד עם האיבר היא בלתי אפשרית, שכן ביטים אלו עלולים להצביע גם על איברים אחרים, שכיבוי הביטים ישלול מהמשתמש את המידע על קיומם.

עם זאת, הועלו רעיונות חדשים ולפיהם ייעשה שימוש במונה, שיימנה כמה פעמים הודלק כל ביט. אז ניתן יהיה להפחית את המונה של כל הביטים הקשורים באיבר מסוים במקרה של מחיקת האיבר. ברור שלשם כך יש להקצות מקום נוסף בזיכרון.

==קישורים חיצוניים==

קטגוריה:מבני נתונים