شجرة فان إمده بواس

شجرة فان إمده بواس ( بالهولندية: [ vɑn ˈɛmdə ˈboːɑs ] )، والمعروفة أيضًا باسم شجرة vEB أو قائمة انتظار فان إمده بواس ذات الأولوية ، هي بنية بيانات شجرية تُنفذ مصفوفة ترابطية بمفاتيح عددية صحيحة مكونة من m بت. اخترعها فريق بقيادة عالم الحاسوب الهولندي بيتر فان إمده بواس عام 1975. [ 1 ] تُنفذ جميع العمليات في زمن O (log m ) (بافتراض أن م{\displaystyle m}يمكن تنفيذ عملية البت في وقت ثابت)، أو ما يعادلها فييا(سجلسجلم){\displaystyle O(\log \log M)}الوقت، أينم=2م{\displaystyle M=2^{m}}هو أكبر عنصر يمكن تخزينه في الشجرة. المعاملم{\displaystyle M}لا ينبغي الخلط بينه وبين العدد الفعلي للعناصر المخزنة في الشجرة، والذي غالباً ما يتم من خلاله قياس أداء هياكل بيانات الشجرة الأخرى.

تتميز شجرة vEB القياسية بكفاءة مساحة غير مثالية تبلغيا(م){\displaystyle O(M)}على سبيل المثال، لتخزين الأعداد الصحيحة ذات 32 بت (أي عندمام=32{\displaystyle m=32}يتطلب ذلكم=232{\displaystyle M=2^{32}}وحدات تخزين. ولحل هذه المشكلة، يمكن تعديل أشجار vEB لتحقيقيا(نسجلم){\displaystyle O(n\log M)}مساحة، أو هياكل بيانات مماثلة ذات كفاءة زمنية ومكانية مكافئة.يا(ن){\displaystyle O(n)}(أينن{\displaystyle n}يمكن استخدام (عدد العناصر المخزنة).

العمليات المدعومة

تدعم شجرة vEB عمليات المصفوفة الترابطية المرتبة ، والتي تتضمن عمليات المصفوفة الترابطية المعتادة بالإضافة إلى عمليتين إضافيتين للترتيب ، وهما FindNext و FindPrevious : [ 2 ]

  • إدراج : إدراج زوج مفتاح/قيمة بمفتاح مكون من m بت
  • حذف : إزالة زوج المفتاح/القيمة باستخدام مفتاح معين
  • البحث : إيجاد القيمة المرتبطة بمفتاح معين
  • FindNext : ابحث عن زوج المفتاح/القيمة الذي يحتوي على أصغر مفتاح أكبر من قيمة k معينة
  • FindPrevious : ابحث عن زوج المفتاح/القيمة الذي يحتوي على أكبر مفتاح أصغر من قيمة k معينة.

تدعم شجرة vEB أيضًا العمليتين Minimum و Maximum ، اللتين تُرجعان أصغر وأكبر عنصر مُخزّن في الشجرة على التوالي. [ 3 ] تعمل كلتا العمليتين فييا(1){\displaystyle O(1)}الوقت، حيث يتم تخزين العنصر الأدنى والأقصى كسمات في كل شجرة.

وظيفة

مثال على شجرة فان إمده بواس
مثال على شجرة فان إمده بواس ذات البعد 5 وبنية الجذر المساعدة بعد إدخال 1 و2 و3 و5 و8 و10.

يتركسجل2م=ك{\displaystyle \log _{2}m=k}لبعض الأعداد الصحيحةك{\displaystyle k}. يُعرِّفم=2م{\displaystyle M=2^{m}}شجرة vEB T فوق الكون{0،...،م-1}{\displaystyle \{0,\ldots ,M-1\}}يحتوي على عقدة جذرية تخزن مصفوفة T.children بطولم{\displaystyle {\sqrt {M}}}.T.children [i] هو مؤشر إلى شجرة vEB المسؤولة عن القيم{أنام،...،(أنا+1)م-1}{\displaystyle \{i{\sqrt {M}},\ldots ,(i+1){\sqrt {M}}-1\}}بالإضافة إلى ذلك، يخزن T قيمتين T.min و T.max بالإضافة إلى شجرة vEB مساعدة T.aux .

تُخزَّن البيانات في شجرة vEB كما يلي: تُخزَّن أصغر قيمة موجودة حاليًا في الشجرة في T.min ، وتُخزَّن أكبر قيمة في T.max . لاحظ أن T.min لا تُخزَّن في أي مكان آخر في شجرة vEB، بينما تُخزَّن T.max . إذا كانت T فارغة، فإننا نستخدم الاصطلاح التالي: T.max = -1 و T.min = M. أي قيمة أخرىx{\displaystyle x}يتم تخزينها في الشجرة الفرعية T.children[i] حيثأنا=x/م{\displaystyle i=\lfloor x/{\sqrt {M}}\rfloor }تحتفظ الشجرة المساعدة T.aux بسجل للأبناء غير الفارغة، لذا تحتوي T.aux على القيمةج{\displaystyle j}إذا وفقط إذا كانت T.children[j] غير فارغة.

فايند نكست

تُجري العملية FindNext(T, x) التي تبحث عن العنصر التالي للعنصر x في شجرة vEB ما يلي: إذا كان x < T.min ، فإن البحث يكون قد اكتمل، والنتيجة هي T.min . إذا كان x ≥ T.max ، فإن العنصر التالي غير موجود، وتُرجع الدالة M. وإلا، تُترك قيمة فارغة.أنا=x/م{\displaystyle i=\lfloor x/{\sqrt {M}}\rfloor }إذا كانت قيمة x أقل من الحد الأقصى للقيمة في T.children[i] ، فإن القيمة المطلوبة موجودة في T.children[i] ، وبالتالي يستمر البحث بشكل متكرر في T.children[i] . وإلا، نبحث عن العنصر التالي للقيمة i في T.aux . وهذا يعطينا فهرس j لأول شجرة فرعية تحتوي على عنصر أكبر من x . ثم تُرجع الخوارزمية الحد الأدنى للقيمة في T.children[j] . يجب دمج العنصر الموجود في مستوى الأبناء مع البتات العليا لتكوين عنصر تالٍ كامل.

دالة FindNext(T, x) إذا كان x < T.min، فأرجع T.min إذا كان x ≥ T.max ، فلا يوجد عنصر تالٍ، فأرجع M i = الجزء الصحيح من (x/م{\displaystyle {\sqrt {M}}}) lo = x modم{\displaystyle {\sqrt {M}}}إذا كان lo < T.children[i].max ، فقم بإرجاع (م{\displaystyle {\sqrt {M}}}i) + FindNext(T.children[i], lo) j = FindNext(T.aux, i) يعود (م{\displaystyle {\sqrt {M}}}j) + T.children[j].min end

لاحظ أنه في أي حال، فإن الخوارزمية تؤدييا(1){\displaystyle O(1)}ثم ربما يتكرر على شجرة فرعية على نطاق واسع بحجمم1/2{\displaystyle M^{1/2}}(أن)م/2{\displaystyle m/2}(عالم البتات). وهذا يعطي تكرارًا لوقت التشغيل لـتي(م)=تي(م/2)+يا(1){\displaystyle T(m)=T(m/2)+O(1)}، والذي يُحل إلىيا(سجلم)=يا(سجلسجلم){\displaystyle O(\log m)=O(\log \log M)}.

أدخل

يتم استدعاء الدالة insert(T, x) التي تُدرج القيمة x في شجرة vEB T على النحو التالي:

  1. إذا كانت T فارغة، فإننا نضبط T.min = T.max = x وبذلك نكون قد انتهينا.
  2. وإلا، إذا كان x < T.min، فإننا نُدرج T.min في الشجرة الفرعية i المسؤولة عن T.min ، ثم نُعيّن T.min = x . إذا كانت T.children[i] فارغة سابقًا، فإننا نُدرج i أيضًا في T.aux.
  3. وإلا، إذا كان x > T.max، فإننا نُدرج x في الشجرة الفرعية i المسؤولة عن x ، ثم نُعيّن T.max = x . وإذا كانت T.children[i] فارغة سابقًا، فإننا نُدرج i أيضًا في T.aux.
  4. وإلا، فإن T.min < x < T.max ، لذا نُدرج x في الشجرة الفرعية i المسؤولة عن x . إذا كانت T.children[i] فارغة سابقًا، فإننا نُدرج i أيضًا في T.aux .

في الكود:

دالة Insert(T, x) إذا كان T.min == x أو T.max == x، فهذا يعني أن x قد تم إدخاله بالفعل، وإلا فإن الدالة تُنهي عملها. إذا كان T.min > T.max، فهذا يعني أن T فارغ. T.min = T.max = x; أعد إذا كانت قيمة x أقل من T.min. تبديل(س، الحد الأدنى لـ ت) إذا كانت x > T.max T.max = x i = الجزء الصحيح من (x /م{\displaystyle {\sqrt {M}}}) lo = x modم{\displaystyle {\sqrt {M}}} أدخل (T.children[i]، lo) إذا كان الحد الأدنى لـ T.children[i] يساوي الحد الأقصى لـ T.children[i] ، أدخل (T.aux، i) نهاية

يكمن سر كفاءة هذه العملية في أن إدخال عنصر في شجرة vEB فارغة يستغرق وقتًا ثابتًا O (1) . لذا، على الرغم من أن الخوارزمية قد تُجري استدعاءين متكررين في بعض الأحيان، إلا أن هذا يحدث فقط عندما يكون الاستدعاء المتكرر الأول في شجرة فرعية فارغة. وهذا يُعطي نفس زمن التشغيل التكراري لـ تي(م)=تي(م/2)+يا(1){\displaystyle T(m)=T(m/2)+O(1)}كما كان من قبل.

يمسح

يُعدّ حذف البيانات من أشجار vEB من أصعب العمليات. يتم استدعاء الدالة Delete(T, x) لحذف القيمة x من شجرة vEB T على النحو التالي:

  1. إذا كان T.min = T.max = x فإن x هو العنصر الوحيد المخزن في الشجرة ونقوم بتعيين T.min = M و T.max = −1 للإشارة إلى أن الشجرة فارغة.
  2. وإلا، إذا كانت x تساوي T.min، فسنحتاج إلى إيجاد ثاني أصغر قيمة y في شجرة vEB، وحذفها من موقعها الحالي، وتعيين T.min=y . ثاني أصغر قيمة y هي T.children[T.aux.min].min ، لذا يمكن إيجادها في زمن O (1) . نحذف y من الشجرة الفرعية التي تحتويها.
  3. إذا كان x≠T.min و x≠T.max ، فإننا نحذف x من الشجرة الفرعية T.children[i] التي تحتوي على x .
  4. إذا كانت x تساوي T.max، فسنحتاج إلى إيجاد ثاني أكبر قيمة y في شجرة vEB وتعيين T.max=y . نبدأ بحذف x كما في الحالة السابقة. عندئذٍ تكون القيمة y إما T.min أو T.children[T.aux.max].max ، لذا يمكن إيجادها في زمن ثابت O (1) .
  5. في أي من الحالات المذكورة أعلاه، إذا قمنا بحذف العنصر الأخير x أو y من أي شجرة فرعية T.children[i]، فإننا نحذف أيضًا i من T.aux .

في الكود:

دالة الحذف (T، x) إذا كان T.min == T.max == x ثم T.min = M T.max = −1 إذا كانت x تساوي T.min، فإن hi = T.aux.min *م{\displaystyle {\sqrt {M}}} j = T.aux.min T.min = x = hi + T.children[j].min i = الجزء الصحيح من (x /م{\displaystyle {\sqrt {M}}}) lo = x modم{\displaystyle {\sqrt {M}}} حذف(T.children[i], lo) إذا كانت T.children[i] فارغة ، حذف (T.aux، i) إذا كانت x تساوي T.max، وإذا كانت T.aux فارغة ، T.max = T.min وإلا فإن hi = T.aux.max *م{\displaystyle {\sqrt {M}}} j = T.aux.max T.max = hi + T.children[j].max نهاية

مرة أخرى، تعتمد كفاءة هذه العملية على حقيقة أن حذف عنصر من شجرة vEB تحتوي على عنصر واحد فقط يستغرق وقتًا ثابتًا. وبالتحديد، لا يتم تنفيذ استدعاء الحذف الثاني إلا إذا كان x هو العنصر الوحيد في T.children[i] قبل الحذف.

عملياً

إن افتراض أن لوغاريتم m عدد صحيح غير ضروري. العملياتxم{\displaystyle x{\sqrt {M}}}وxتعديلم{\displaystyle x{\bmod {\sqrt {M}}}}يمكن استبدال ذلك بأخذ البتات ذات الرتبة الأعلى m /2⌉ والبتات ذات الرتبة الأدنى m /2⌋ من x ، على التوالي. على أي جهاز موجود، يكون هذا أكثر كفاءة من عمليات القسمة أو حساب الباقي.

في التطبيقات العملية، وخاصةً على الأجهزة التي تستخدم تعليمات الإزاحة بمقدار k والبحث عن أول صفر ، يمكن تحسين الأداء بشكل أكبر عن طريق التحويل إلى مصفوفة بتات بمجرد الوصول إلى قيمة m مساوية لحجم الكلمة (أو مضاعف صغير لها). ولأن جميع العمليات على كلمة واحدة تتم في وقت ثابت، فإن هذا لا يؤثر على الأداء الكلي، ولكنه يتجنب معظم عمليات تخزين المؤشرات والعديد من عمليات فك مرجعية المؤشرات، مما يحقق توفيرًا عمليًا كبيرًا في الوقت والمساحة.

تتمثل إحدى طرق تحسين أشجار vEB في حذف الأشجار الفرعية الفارغة. هذا يجعل أشجار vEB مضغوطة للغاية عند احتوائها على عناصر كثيرة، لأنه لا يتم إنشاء أشجار فرعية إلا عند الحاجة إلى إضافة عنصر إليها. في البداية، يُنشئ كل عنصر مُضاف حوالي log( m ) من الأشجار الجديدة التي تحتوي على حوالي m /2 من المؤشرات إجمالاً. ومع نمو الشجرة، يُعاد استخدام المزيد من الأشجار الفرعية، وخاصةً الأكبر حجمًا.

يستخدم التنفيذ الموصوف أعلاه المؤشرات ويشغل مساحة إجمالية قدرها O ( M ) = O (2m ) ، وهي مساحة تتناسب مع حجم مجموعة المفاتيح. ويمكن توضيح ذلك كما يلي. العلاقة التكرارية هيS(م)=يا(م)+(م+1)S(م){\displaystyle S(M)=O({\sqrt {M}})+({\sqrt {M}}+1)\cdot S({\sqrt {M}})}يمكن إثبات أن S ( M ) = O ( M ) بالاستقراء. [ 4 ]

هياكل مماثلة

يُعدّ استخدام مساحة O ( M ) لأشجار vEB عبئًا كبيرًا ما لم يتم تخزين جزء كبير من مجموعة المفاتيح. وهذا أحد أسباب عدم شيوع استخدام أشجار vEB عمليًا. يمكن معالجة هذا القيد بتغيير المصفوفة المستخدمة لتخزين الأبناء إلى بنية بيانات أخرى. أحد الاحتمالات هو استخدام عدد ثابت من البتات لكل مستوى، مما ينتج عنه شجرة بحث ثلاثية (Trie) . بدلاً من ذلك، يمكن استبدال كل مصفوفة بجدول تجزئة ، مما يقلل المساحة إلى O ( n log log M ) (حيث n هو عدد العناصر المخزنة في بنية البيانات) على حساب جعل بنية البيانات عشوائية.

تتميز محاولات x-fast ومحاولات y-fast الأكثر تعقيدًا بأوقات تحديث واستعلام مماثلة لأشجار vEB، وتستخدم جداول تجزئة عشوائية لتقليل المساحة المستخدمة. تستخدم محاولات x-fast مساحة O ( n log M بينما تستخدم محاولات y-fast مساحة O ( n ) .

أشجار الاندماج هي نوع آخر من هياكل بيانات الأشجار، تُنفذ مصفوفة ترابطية على أعداد صحيحة مكونة من w بت في فضاء محدود. تستخدم هذه الأشجار التوازي على مستوى الكلمات وتقنيات معالجة البتات لتحقيق زمن O (log w n ) للاستعلامات والتحديثات الخاصة بالسلف/الخلف ، حيث w هو حجم الكلمة. [ 5 ] تستخدم أشجار الاندماج مساحة O ( n ) ويمكن جعلها ديناميكية باستخدام التجزئة أو الأشجار الأسية.

يقدم لينوف وسميد [ 6 ] صيغةً معدلةً لشجرة vEB تستخدم مساحةً قدرها O ( n ) وتستغرق وقتًا متوسطًا قدره O (1) لإدراج عنصر، مع مراعاة أن عمليات الإدراج تتم بترتيب تصاعدي؛ أي أن العنصر المُدرج هو دائمًا العنصر الأقصى الجديد. تستخدم هذه البنية التجزئة المثالية الديناميكية لتنفيذ الشجرة في مساحة صغيرة، كما أنها تُقلل حجم الشجرة بمعامل log log M عن طريق الحفاظ على حجم مجموعات الأوراق عند log log M.

قدم ديتز ورامان [ 7 ] نسخة فعالة من حيث المساحة ومستمرة جزئيًا من أشجار vEB . تستخدم هذه النسخة مساحة O ( n )، وتدعم إدراج عنصر في النسخة الحالية في وقت O (log log M ) مستهلك ومتوقع، بينما يظل الاستعلام عن أي نسخة O (log log M ) .

التطبيقات

يوجد تطبيق مُوثَّق في إيزابيل (مساعد البرهان) . [ 8 ] وقد تم إثبات كل من صحة الوظائف وحدود الوقت. ويمكن توليد كود Standard ML إجرائي فعال.

انظر أيضاً

مراجع

  1. بيتر فان إمدي بواس : الحفاظ على النظام في غابة في وقت أقل من الوقت اللوغاريتمي ( وقائع الندوة السنوية السادسة عشرة حول أسس علوم الحاسوب 10: 75-84، 1975)
  2. ^ جودموند سكوفبيرج فراندسن : الخوارزميات الديناميكية: ملاحظات الدورة على أشجار فان إمدي بواس (PDF) أرشفة 2015-09-23 في آلة Wayback. ( جامعة آرهوس ، قسم علوم الكمبيوتر)
  3. ^ توماس هـ. كورمين ، تشارلز إي. ليسرسون ، رونالد ل. ريفست ، وكليفورد ستاين . مقدمة للخوارزميات ، الطبعة الثالثة. مطبعة معهد ماساتشوستس للتكنولوجيا ، 2009. ISBN 978-0-262-53305-8الفصل 20: شجرة فان إمده بواس، الصفحات  531-560.
  4. ريكس، أ. "تحديد التعقيد المكاني لأشجار فان إمدي بواس" . تم الاسترجاع في 27 مايو 2011 .
  5. "شجرة الاندماج" . OpenGenus IQ: خبرة الحوسبة والإرث . 4 أبريل 2019. تم الاطلاع عليه في 30 أغسطس 2023 .
  6. لينهوف، هانز-بيتر؛ سميد، ميشيل (1994). "استخدام هياكل البيانات المستمرة لإضافة قيود النطاق إلى مشاكل البحث". RAIRO- المعلوماتية النظرية والتطبيقات . 28 (1): 25-49 . doi : 10.1051/ita/1994280100251 .
  7. ديتز، بول ف.؛ رامان، راجيف (1991). الاستمرارية، والاستهلاك، والعشوائية (تقرير فني). جامعة روتشستر. TR 353.
  8. ^ عامر، توماس. لاميش، بيتر (23 نوفمبر 2021). "أشجار فان إيمدي بواس" . أرشيف الأدلة الرسمية . تم الاسترجاع في 26 نوفمبر 2021 .

للمزيد من القراءة