الگوریتم *B

درخت بی‌استار، یک نوع خاص از درخت بی‌پلاس است. درخت‌های بی، بی‌استار و بی‌پلاس در پایگاه داده‌ها و سیستم فایلها کاربرد زیادی دارند. الگوریتم بی استار(به انگلیسی: B*) یک الگوریتم جستجوی ابتدا بهترین در گراف است.
در این روش، کم‌هزینه‌ترین مسیر از یک گره به گرهٔ هدف در گراف محاسبه می‌شود(برای جستجو). این الگوریتم اولین بار در سال ۱۹۷۹ توسط هانس برلینر ارائه شد که با الگوریتم الگوریتم جستجوی آ* مرتبط است.

درخت *B

درخت‌های بی، بی استار و بی پلاس در پایگاه داده‌ها و سیستم فایلها کاربرد زیادی دارند و در داده ساختارها و پایگاه‌داده‌ها به منظور شاخص بندی استفاده می‌شوند.
در علوم کامپیوتر، یک درخت بی یا بی‌تری (به انگلیسی:  B-tree) داده‌ساختاری درختی است که داده‌ها را به صورت مرتب‌شده نگه می‌دارد و جستجو، درج و حذف را در زمان لگاریتمی میسر می‌سازد. بر خلاف درخت‌های جستجوی دودویی متوازن (به انگلیسی: Balanced binary search tree)، این داده‌ساختار برای سیستم‌هایی که بلاک‌های عظیم اطلاعات را خوانده و می‌نویسند بهینه‌سازی شده‌است. این داده‌ساختار معمولاً در پایگاه‌داده‌ها و سیستم پرونده استفاده می‌شود.
در درخت بی داده‌ها می‌توانند در برگ‌ها یا گره‌های میانی ذخیره شوند. اما در درخت بی‌پلاس، تمام داده‌ها در برگ‌ها ذخیره می‌شوند و یک گره توانایی نگهداری چند داده به جای یک داده هم دارد.
درخت *B نوع خاصی از درخت +B است که حداقل دو سوم از ظرفیت هر گره تکمیل باشد.

خلاصه

این الگوریتم نشان می‌دهد که شروع از ریشه برای جستجو بهتر است. برای این کار، تلاش می‌کند گرهٔ بهتری را پید کند. در این الگوریتم، ترتیب بسط دادن گره‌ها تعیین می‌شود، و هر گرهٔ بسط داده شده دو مقدار به عنوان باند بالا و باند پایین دارد. اگر در طول الگوریتم این دو مقدار به یک عدد مشخص میل کنند و همگرا شوند، الگوریتم به سوی پایان یافتن است. تا وقتی که باندهای یک گره در درخت قابل بسط دادن توسط قوانین مربوطه هستند، الگوریتم به دنبال بهترین گره می‌گردد.

علت استفاده از الگوریتم *B

در سایر الگوریتم‌های جستجو، برای انجام جستجوهای تکراری، یک راه طبیعی برای پایان جستجو وجود ندارد. همچنین با در نظر گرفتن محدودیت‌های مختلف این نکته که کدام عنصر باید ریشه واقع شود، چیز ثابتی نیست. برای غلبه بر این مشکلات از الگوریتم جستجوی بی استار استفاده می‌کنیم.

انتخاب روش

اجرای روش بدبینانه تا وقتی که باند پایین گرهٔ فرزندی که بالاترین باند بالا را دارد، در میان سایر باندهای پایین، بزرگترین است، بیهوده است.
الگوریتم اصلی کمک بیشتری برای انتخاب روش به ما نمی‌کند.

روش انتخاب برای یک گرهٔ غیر ریشه

وقتی که یک گرهٔ فرزند انتخاب شده باشد، با اجرای یکی از دو روش ذکر شده در بالا، به یک برگ می‌رسیم. وقتی که به برگ رسیدیم، الگوریتم گره‌های ترتیبی بعدی(به انگلیسی: successor nodes) را تولید می‌کند، سپس با استفاده از تابع سنجش، اختلاف فاصلهٔ هر گره به آن اختصاص داده شود. سپس تمامی این اختلافات ذخیره شده به وسیلهٔ یک فرایند پشتیبانی، مدیریت می‌شوند.
وقتی که جابجایی و حرکت روی گره‌ها امکان پذیر است، فرایند پشتیبانی ممکن است نیاز داشته باشد مقدار گره‌هایی که در مسیر انتخابی نیستند تغییر دهد. در این حالت الگوریتم نیاز دارد که از هر فرزند هم به گرهٔ پدر یک اشاره گر وجود داشته باشد تا تغییرات بتواند منتشر شود. باید توجه داشت منتشر شدن وقتی اتفاق می‌افتد که فرایند پشتیبانی مقدار گرهٔ مورد نظر را تغییر نمی‌دهد.

فرایند پشتیبانی

دقت داشته باشیم که در فرایند پشتیبانی باید باند بالای گرهٔ پدر، به عنوان باند بالای همهٔ باندهای بالای گره‌های فرزند در نظر گرفته می‌شود. باند پایین آن هم باید از باند پایین گره‌های فرزند بیشتر در نظر گرفته شود.
فرایند پشتیبانی وقتی رخ می‌دهد که یکی از سه رخداد زیر پیش آید:
۱-مقادیر خوشبینانه و بدبینانه به هم نزدیک شوند طوری‌که با هم برابر شوند.
۲-شاخه‌های مورد نیاز برای بررسی برای روش خوشبینانه بیشتر است.
۳- روش خوشبینانه و بدبینانه تا جایی پیش رفته باشند که وضعیت زیردرختی که به آن رسیدیم، معلوم شود.
در فرایند پشتیبانی، بهترین مقدار خوشبینانه جایگزین مقدار بدبینانهٔ آن می‌شود و بهترین مقدار بدبینانه، مقدار خوشبینانهٔ آن می‌شود. برای حالت بیشینه، مقادیر خوشبینانه از مقادیر بدبینانه بیشترند. در حالی که در حالت کمینه، مقادیر خوشبینانه کمتر از بدبینانه‌اند. فرایند پشتیبانه به‌طور مداوم تا وقتی که مقادیر جدیدی طبق سه قانون بالا باید پشتیبانی شوند وجود دارد، اجرا می‌شود.

پایان یافتن جستجو

وقتی باند پایین یکی از فرزندان مستقیم ریشه، بزرگتر یا مساوی باند بالای سایر فرزندان ریشه باشد، الگوریتم *B باعث ایجاد جداسازی می‌شود. درختی که جداسازی در آن صورت می‌گیرد، نشان می‌دهد که فرزند ریشه حداقل به اندازهٔ سایر گره‌ها مناسب است؛ پس این الگوریتم پایان می‌یابد. البته در عمل، جستجوهای پیچیده، ممکن است در یک مدت زمان معقول تمام نشوند پس الگوریتم با یک پایان مصنوعی مانند تایم لیمیت یا مموری لیمیت تمام می‌شود.

مزایای الگوریتم

دو نکتهٔ زیر می‌تواند الگوریتم *B را به عنوان یک الگوریتم ابندا-بهترین ساده متمایز سازد:
۱-الگوریتم *B، فرایند پشتیبانی را اجرا می‌کند هر گاه به جایی برسد که مقدار آن برای مسئلهٔ ما کافی است. در حالی که سایر الگوریتم‌های ابتدا-بهترین، تا مقدار نهایی را نیابند فرایند پشتیبانی را اجرا نمی‌کنند. یک نکتهٔ ظریف اینجا وجود دارد و آن این است که بی معنی ایت اگر حرکت را از یک گره ادامه بدهیم در حالی که گره موجود حاوی مقداری است که مناسب انتخاب شدن است. در حالی که سایر روش‌های ابتدا-بهترین این را نمی‌فهمند.
۲-الگوریتم می‌تواند یکی از دو روش را فقط وقتی روی ریشه است انتخاب کند. این باعث می‌شود ادامهٔ الگوریتم در مسیری حرکت کند که کم هزینه‌ترین حرکت‌ها مشخص شود.

شبه کد

1) DEPTH <- 0; CURNODE <- 0; BESTALT[-2] <- 0

2) if DEPTH <0 then EXIT.

3)    if    CURNODE   has    not    been   expanded   yet    then   generate,   name,     and    evaluate    
successors,  give  each   pointer  to  parent

4)  BESTNODE  <-  name  of  successor  with  best  OPTIM  value;  

ALTERN  <-  name  of  successor  with  second  best  OPTIM  value;  

MAXOPTIM  <-  0PTIM[BESTN0DE];  

MAXPESS <-  VaJue  of  the  best  PESSIM  value  of  all  successors;  

5)   Back   up  MAXOPTIM   and  MAXPESS   and  far   as  necessary.    If   a  change   is   made   to   
descendants  of  root,  then  (DEPTH  <- 0;  CURNODE  <- 0;  go  to  4);  

6) if MAXOPTIM = MAXPESS then go to 16; 

7) BESTALT[DEPTH] <- BESTALT[DEPTH-2] 

8)  if  DEPTH  =  0  then  decide  STRATEGY,  

if  STRATEGY  =   DISPROVEREST  then  

(ASPIR  <-  MAXPESS ;  BESTALT[0]  <-  MAXPESS ; BESTALT[-1]  <- OPTIMf ALTERN]); 

if  STRATEGY  =   PROVEBEST  then  

(ASPIR   <-  OPTIM[ALTERN]j  BESTALT[-1]<-  MAXPESS; BESTALT[0]  <-  0PTIM[ALTER

9) if MAXPESS> BESTALT[DEPTH-1 ] then goto 16;  

10)  if  STRATEGY  =  PROVEBEST  then  

if  MAXPESS>  ASPIR  then  goto  16;        

11)  if  MAXOPTIM  <BESTALT[DEPTH]  then  goto  16;        

12)  if  STRATEGY  =   DISPROVEREST  then  

if  MAXOPTIM  <ASPIR  then  goto  16;            

13)  if  DEPTH !=  0  then  

if  0PTIM[ALTERN]>  BESTALT[DEPTHJ  then  BESTALT[DEPTH]  <-  0PTIM[ALTERN];  

14)  if  (DEPTH  =  0)  and  (STRATEGY  =  DISPROVEREST)   then  CURNODE  <-    ALTERN    

else  CURNODE  <-  BESTNODE;  

15)  DEPTH <-DEPTH+1;

go  to  3.  

16)  DEPTH  <-DEPTH-1;

if  DEPTH  <0  then  ANSWER  <-  BESTNODE 

else  (CURNODE      PARENT[CURNODE];  go  to  2);

کاربرد الگوریتم

اندرو پالای(به انگلیسی: Andrew Palay) توانست از این الگوریتم در شطرنج استفاده کند. نقطهٔ پایان ارزیابی، به وسیلهٔ جستجوهای پوچ شناخته می‌شود. گزارشی در دست نیست که این الگوریتم چگونه در برابر هرس آلفا بتا که روی سخت افزارهای مشابه کار می‌کند، عملکرد بهتری دارد.
همچنین الگوریتم *B استفاده می‌شود تا روش بهینه در بازی جمع (به انگلیسی: sum game) از یک مجموعه بازی‌های ترکیبی را محاسبه کند.