D* (تلفظ "دی استار") هر یک از سه الگوریتم جستجوی افزایشی زیر است:
هر سهٔ این الگوریتمهای جستجو مسائل برنامهریزی مسیر مبتنی بر فرض را حل میکنند، از جمله برنامهریزی با فرض فضای آزاد،[۷] که در آن یک ربات باید در یک زمین ناشناخته به مختصات هدف داده شده برود. که در مورد قسمت ناشناخته زمین فرضیاتی ارائه میشود (به عنوان مثال: هیچ مانعی در زمین وجود ندارد) و ربات کوتاهترین مسیر را از مختصات فعلی خود به مختصات هدف تحت این مفروضات مییابد. سپس ربات مسیر را دنبال میکند. هنگامی که اطلاعات نقشه جدید (مانند موانع ناشناخته قبلی) را مشاهده میکند، اطلاعات را به نقشه خود اضافه میکند و در صورت لزوم کوتاهترین مسیر جدید را از مختصات فعلی خود به مختصات هدف داده شده دوباره برنامهریزی میکند. این فرایند را تکرار میکند تا زمانی که به مختصات هدف برسد یا تعیین کند که نمیتوان به مختصات هدف رسید. هنگام عبور از زمین ناشناخته، موانع جدید ممکن است بهطور مکرر کشف شوند، بنابراین این برنامهریزی باید سریع باشد. الگوریتمهای جستجوی افزایشی (آگاهانه) سرعت جستجو را برای دنبالههایی از مشکلات جستجو مشابه با استفاده از تجربه مشکلات قبلی برای تسریع در جستجوی مورد فعلی افزایش میدهند. با فرض تغییر نکردن مختصات هدف، هر سه الگوریتم جستجو از جستجوی *A مکرر کارآمدتر هستند.
D* و انواع آن بهطور گستردهای برای رباتهای سیار و ناوبری وسیله نقلیه خودمختار استفاده میشوند. سیستمهای فعلی معمولاً بیشتر از D* Lite یا D* Focused مبتنی بر D* Lite هستند. در حقیقت، حتی آزمایشگاه استنتز در برخی از پیادهسازیها از D* Lite به جای *D استفاده میکند.[۸] چنین سیستمهای ناوبری شامل یک سیستم نمونه آزمایشی که در مریخ نوردهای Opportunity و Spirit و سیستم ناوبری برنده در DARPA Urban Challenge تست شدهاند که هر دو در دانشگاه کارنگی ملون توسعه یافتهاند.
D* اصلی توسط آنتونی استنتز در سال ۱۹۹۴ معرفی شد. نام *D از اصطلاح "*Dynamic A" آمدهاست،[۲] زیرا الگوریتم مانند *A رفتار میکند با این تفاوت که هنگام اجرای الگوریتم هزینههای قوس میتوانند تغییر کند.
عملکرد اساسی *D در زیر بیان شدهاست.
مانند الگوریتم Dijkstra و *A، الگوریتم *D لیستی از گرههای مورد ارزیابی را نگهداری میکند، معروف به "لیست OPEN". گرهها به عنوان یکی از چندین حالت زیر مشخص شدهاند:
این الگوریتم با تکرار عملیات انتخاب یک گره از لیست OPEN و ارزیابی آن کار میکند. سپس تغییرات گره را در همه گرههای همسایه منتشر کرده و در لیست OPEN قرار میدهد. این فرایند انتشار "گسترش" نامیده میشود. برخلاف *A متعارف، که مسیر را از ابتدا تا انتها دنبال میکند، *D با جستجوی عقبگرد از گره هدف شروع میشود. هر گره توسعه یافته دارای یک "backpointer" است که به گره بعدی منتهی به هدف اشاره دارد و هر گره هزینه دقیق رسیدن به هدف را میداند. وقتی گره شروع گره ای است که در مرحله بعدی گسترش مییابد، الگوریتم به پایان میرسد و میتوان با دنبال کردن نشانگرهای عقب("backpointers")، مسیر رسیدن به هدف را پیدا کرد.
وقتی مانع در مسیر مورد نظر شناسایی شد، تمام نقاطی که تحت تأثیر قرار میگیرند با برچسب RAISE مشخص شده و دوباره در لیست OPEN قرار میگیرند. قبل از اینکه گره RAISED هزینه اش افزایش یابد، الگوریتم همسایگان خود را بررسی میکند و بررسی میکند که آیا میتواند هزینه گره را کاهش دهد. در غیر اینصورت، حالت RAISE به تمام فرزندان گرهها، یعنی گرههایی که دارای نشانههای برگشتی هستند، انتشار مییابد. سپس این گرهها ارزیابی شده و حالت RAISE منتقل شده و موجی را تشکیل میدهند. هنگامی که یک گره RAISED میتواند کاهش یابد، قسمت داخلی آن به روز میشود و وضعیت LOWER را به همسایگان خود منتقل میکند. این امواج RAISE و LOWER قلب *D هستند.
بوسیله این نکته، از «لمس شدن» یک سری از نقاط توسط امواج جلوگیری میشود؛ بنابراین الگوریتم فقط در نقاطی که در تغییر هزینه تأثیر دارند کار کردهاست.
این بار نمیتوان از بنبست به راحتی عبور کرد. هیچیک از نقاط نمیتوانند مسیر جدیدی را از طریق همسایه به مقصد پیدا کنند؛ بنابراین، آنها به انتشار افزایش هزینههای خود ادامه میدهند. فقط نقاط خارج از کانال را میتوان یافت، که میتواند از طریق یک مسیر مناسب به مقصد منجر شود. به این ترتیب دو موج پایین توسعه مییابند که به صورت نقاطی که با اطلاعات مسیر جدید بعنوان غیرقابل دستیابی مشخص شدهاند، گسترش مییابد.
while (!openList.isEmpty()) {
point = openList.getFirst();
expand(point);
}
void expand(currentPoint) {
boolean isRaise = isRaise(currentPoint);
double cost;
for each (neighbor in currentPoint.getNeighbors()) {
if (isRaise) {
if (neighbor.nextPoint == currentPoint) {
neighbor.setNextPointAndUpdateCost(currentPoint);
openList.add(neighbor);
} else {
cost = neighbor.calculateCostVia(currentPoint);
if (cost <neighbor.getCost()) {
currentPoint.setMinimumCostToCurrentCost();
openList.add(currentPoint);
}
}
} else {
cost = neighbor.calculateCostVia(currentPoint);
if (cost <neighbor.getCost()) {
neighbor.setNextPointAndUpdateCost(currentPoint);
openList.add(neighbor);
}
}
}
}
boolean isRaise(point) {
double cost;
if (point.getCurrentCost()> point.getMinimumCost()) {
for each(neighbor in point.getNeighbors()) {
cost = point.calculateCostVia(neighbor);
if (cost <point.getCurrentCost()) {
point.setNextPointAndUpdateCost(neighbor);
}
}
}
return point.getCurrentCost()> point.getMinimumCost();
}
همانطور که از نام آن مشخص است، *D متمرکز یک الگوریتم گسترش یافته از *D است که از یک روش ابتکاری برای تمرکز انتشار RAISE و LOWER به سمت ربات استفاده میکند. به این ترتیب، فقط حالتهایی که مهم هستند به روز میشوند، به همان روشی که *A فقط هزینه برخی از گرهها را محاسبه میکند.
D* Lite براساس *D اصلی یا *D متمرکز نیست، اما همان عمل را انجام میدهد. فهم آن سادهتر است و میتواند در تعداد کمتری خط کدش پیادهسازی و اجرا شود، از این رو نام آن "D* Lite" است. از نظر عملکرد، بهتر یا برابر با *D متمرکز است. D * Lite مبتنی بر برنامهریزی مادام العمر *A است که چند سال قبل توسط کونیگ و لیخاچف معرفی شد. D * آرشیو
برای *D، تمایز بین حداقل هزینه و هزینههای فعلی مهم است. مورد اول فقط در زمان جمعآوری مهم است ولی مورد دوم بسیار حیاتی است زیرا OpenList را مرتب میکند. تابعی که حداقل هزینه را برمیگرداند همیشه کمترین هزینه به نقطه فعلی را برمیگرداند زیرا اولین ورودی OpenList است.
{{cite thesis}}
: Missing or empty |title=
(help)