الگوریتم حریصانه
|
|
پیشنهاد شدهاست که این مقاله یا بخش با حریصانه ادغام گردد. |
روش حریصانه
نام این روش از شخصیت معروف اسکروج گرفته شده است.اسکروج به جای آن که به گذشته و آینده فکر کند،تنها انگیزه هر روز او به دست آوردن طلای بیشتر بود.الگوریتم حریصانه(Greedy) نیز مانند شیوه اسکروج می باشد.
الگوریتم حریصانه یا آزمند شبیه روش های پویا اغلب برای حل مسائل بهینه سازی استفاده می شوند. در شیوه حریصانه در هر مرحله عنصری که بر مبنای معیاری معین ((بهترین))به نظر می رسد، بدون توجه به انتخاب هایی که قبلا انجام شده یا در آینده انجام خواهد شد،انتخاب می شود. الگوریتم های حریصانه اغلب راه حل های ساده ای هستند.در روش حریصانه برخلاف روش پویا ، مسأله به نمونه های کوچک تر تقسیم نمی شود.
الگوریتم حریصانه کمترین تعداد سکه هایی که باعث شود مسئله تغییر نماید را تعیین می نماید .اینها مراحل یک انسان هستند که سکه با مقدار ۳۶ را با استفاده از سکههای با مقادیر ۱و۵و۱۰و۲۰ تعیین می کند. سکه با بزرگترین مقدار و کوچکتر از تغییرات باقی مانده بعنوان بهینه محلی انتخواب می گردد(توجه کنید که در حالت معمول مسئله پیدا کردن تغییرات بااستفاده از برنامهریزی پویا یا Linear programming Integer unknowns جواب بهینه را پیدا می کند).پول آمریکا و دیگر کشورهانمونههای خاصی هستند که با استفاده از الگوریتم حریصانه می توان جواب بهینه آنهارا پیدا کرد).]] در بسیاری از موارد مسئله از ما میخواهد که یک متغیر را کمینه یا بیشینه کنیم و یا اینکه صورت مسئله مستقیما از ما نمیخواهد که چیزی را کمینه یا بیشینه کنیم اما میتوان این مسئله را تبدیل به یک چنین مسئلهای کرد. در اکثر مسائل از این دست ما باید تعدادی انتخاب انجام دهیم و مسئله در تعدادی مرحله حل شود. بازهٔ وسیعی از این مسائل توسط الگوریتمهای حریصانه قابل حلاند. الگوریتمهای حریصانه در هر مرحله در نظر میگیرند که کدام انتخاب در حال حاضر بهترین وضعیت را برای ما رقم میزند و آن را انجام میدهند بدون در نظر گرفتن این که انجام این حرکت در آینده ممکن است به ضرر ما تمام شود. بنابراین الگوریتمهای حریصانه همیشه جواب درست را به ما نمیدهند اما خیلی وقتها هم اینطور نیست این دسته از الگوریتمها در علوم رایانه کاربرد وسیعی دارند.
حال مثالی برای اینگونه الگوریتمها میاوریم:
فرض کنید میخواهیم n تومان را با سکه های۲۵ تومانی۱۰ تومانی۵ تومانی۱ تومانی پرداخت کنیم به طوری که کمترین تعداد سکه را بپردازیم. ما میتوانیم یک الگوریتم حریصانه برای حل این مسئله ارائه دهیم که تعداد سکه بهینه را در هر مرحله بدست آورد برای این کار ما در هر مرحله بزرگترین سکهای را که از پول باقیمانده تجاوز نکند انتخاب میکنیم در این صورت تعداد سکهها بهینه خواهدبود.
prededure change(
for i:=۱ to r
while n≤
begin
add a coin with value
to change
n:=n-
end
مثال دیگری که میتوان عنوان کرد مسأ لهٔ زمان بندی چندین فعالیت در حال رقابت است که نیاز به استقادهٔ منحصر به فرد از یک منبع مشترک با هدف انتخاب مجموعهای با ماکزیمم اندازه از فعالیت هایی که متقابلا با یکدیگر سازگارند، دارند.
فرض کنید یک مجموعهٔ s={a۱،a۲،….an} از n فعالیت پیشنهادی داریم که می خواهند از یک منبع استفاده نمایند، مانند یک تالار سخنرانی که در یک زمان میتواند تنها مورد استفادهٔ یک فعالیت قرار گیرد. هر فعالیت ai دارای زمان شروع si و زمان خاتمهٔ fi است به طوری که ۰≤si<fi<∞ .اگر فعالیت ai انتخاب شود، میتواند در طول بازهٔ [si،fi) رخ دهد.
تعریف: فعالیتهای ai و aj سازگار هستند، اگر بازههای [si،fi)و [sj،fj) همپوشانی نداشته باشند.
مسأله انتخاب فعالیت عبارت است از انتخاب یک زیرمجموعه با ماکزیمم اندازه از فعالیتهای متقابلا سازگار. برای مثال مجموعهٔ s زیر از فعالیتها را در نظر بگیرید که آنها را به ترتیب صعودی یکنواخت از زمانهای خاتمه مرتب کردهایم:
i -> ۱ ۲ ۳ ۴ ۵ ۶ ۷ ۸ ۹ ۱۰ ۱۱
si -> 1 3 0 5 3 5 6 8 8 2 12
fi -> 4 5 6 7 8 9 10 11 12 13 14
برای این مثال زیر مجموعهٔ {a۳،a۹،a۱۱} شامل فعالیتهای متقابلا سازگار است.
اگرچه این زیرمجموعه ماکزیمم نیست، چون زیرمجموعهٔ {a۱،a۴،a۹،a۱۱} بزرگتر از آن است. در حقیقت {a۱،a۴،a۹،a۱۱} بزرگترین زیرمجموعه از فعالیتهای متقابلاً سازگار است. حال یک الگوریتم حریصانه بازگشتی برای حل مسئلهٔ زمانبندی فعالیتها ارائه خواهیم نمود.
با تعریف مجموعهٔ sij={ak € s: fi≤sk<fk≤sj} شروع میکنیم، به طوری که sij زیر مجموعهای از فعالیتها در S است که میتوانند بعد از خاتمه فعالیت ai شروع شده و قبل از شروع فعالیت aj خاتمه یابند. در حقیقت sij شامل همه فعالیتهایی است که با ai و aj و همچنین با همه فعالیتهایی که بعد از خاتمه ai خاتمه نیافته و همه فعالیتهایی که قبل از شروع aj شروع نمیشوند، سازگارند. به منظور بیان کل مسئله، فعالیتهای ساختگی a۰ و an+۱ را اضافه کرده و توافق می کنیم که f0=0 و sn+۱=∞ پس S=S۰،n+۱ و محدودهٔ تغییر iو j به صورت ۰≤I،j≤n+۱ خواهد بود. دامنهٔ تغییر I و j را به صورت زیر میتوانیم بیشتر محدود کنیم. فرض می کنیم که فعالیتها در یک ترتیب یکنواخت صعودی از زمانهای خاتمه مرتب شدهاند:
F۰≤f۱≤f۲≤…≤fn≤fn+۱ ادعا می کنیم که sij=ᴓ هرگاه i≥j باشد. فرض کنید یک فعالیت ak€sij برای i≥j وجود دارد به طوری که ai بعد از aj در ترتیب مرتب قرار دارد. پس خواهیم داشت fi≤sk<fk≤sj<fj. بنابراین fi<fj که با این فرض که ai بعد از aj در ترتیب مرتب قرار دارد در تناقض است. میتوانیم نتیجه بگیریم با این فرض که فعالیتها رادر یک ترتیب صعودی یکنواخت از زمانهای خاتمه مرتب کرده ایم، فضای زیر مسائل انتخاب زیر مجموعه با ماکزیمم اندازه شامل فعالیتهای متقابلا سازگاراز sij است، که ۰≤i<j≤n+۱ با آگاهی از این مطلب که تمام sijهای دیگر تهی هستند.
برای مشاهده زیر ساختار مسئله انتخاب فعالیت، تعدادی زیرمسئله غیر تهی sij را در نظر بگیرید. و فرض کنید که یک جواب برای sij شامل تعدادی فعالیت ak است. بطوریکه fi ≤ sk < fk ≤ sj. استفاده از فعالیت ak سبب ایجاد دو زیر مسئله میشود، sik(فعالیتهای که پس از خاتمه فعالیت aiشروع شده و قبل از شروع فعالیت akخاتمه مییابند)وskj(فعالیتهای که پس از خاتمه akشروع شده و قبل از شروع فعالیت ajخاتمه مییابند)، که هرکدام از یک زیر مجموعه شامل فعالیتهای داخل sij تشکیل شده اند. جواب sij اجتماع جوابهای مربوط به sik و skj است، همراه با فعالیت ak. بنابراین تعداد فعالیتها در جواب sij برابر اندازه جواب skj به علاوه یک (برای ak) میباشد.
اکنون فرض کنید جواب Aij برای sij شامل فعالیت ak میباشد.پس جوابهای Aik برای sik و Akjبرای skj که در این جواب بهینه برای sij استفاده میشوند نیز باید بهینه باشند. بحث برش – و – الصاق معمول در این مورد بکار میرود. اگر یک جواب Áik برای sik میداشتیم که شامل فعالیتهای بیشتری از Aik میبود، میتوانستیم Aik را از داخل Aij برش داده و به داخل Áik الصاق نماییم، بنابراین یک جواب دیگر برای Sij با تعداد فعالیتهای بیشتری از Aij تولید میشود. از آنجا که فرض کردیم Aij یک جواب بهینه است، به یک تناقض رسیده ایم. به طور مشابه اگر جواب Ákj برای skj را با فعالیتهای بیشتر از Akj میداشتیم، میتوانستیم Akj را با Ákj جایگزین کنیم تا یک جواب با فعالیتهای بیشتری از Aij تولید نماییم.
اکنون از زیر ساختار بههینه خود استفاده کرده تا نشان دهیم که میتوانیم یک جواب بهینه برای مسئله از روی جوابهای بهینه زیر مسائل بسازیم. مشاهده کردم که هر جواب برای یک زیر مسئله غیر تهی sij شامل فعالیت ak است و آنکه هر جواب بهنه در درون خود شامل جوابهای بهینه نمونه زیر مسئلههای sik و skj میباشد. بنابراین، میتوانیم یک زیر مجموعه با ماکزیمم اندازه از فعالیتهای متقابلاً سازگار درSijبسازیم. با تقسیم مسئله به دو زیرمسئله (یافتن زیر مجموعههای با ماکزیمم اندازه از فعالیتهای متقابلا سازگار در sikو skj) و پیداکردن زیرمجموعههای با ماکزیمم اندازه Aik و Akjاز فعالیتهای متقابلا سازگار برای این زیر مسائل وسپس تشکیل زیر مجموعه Aij با ماکزیمم اندازه شامل فعالیتهای متقابلا سازگار بصورت Aik υ {ak } υ Akj=Aij یک جواب بهینه برای کل مسئله یک جواب برای S۰،n+۱ است.
محتویات |
[ویرایش] مثال هایی جهت تفهیم بهتر الگوریتم حریصانه
[ویرایش] الگوریتم حریص برای حل مسئله پول خرد
مسئله:پس دادن بقیه پول مشتری با استفاده از سکه های موجود.
ورودی:انواع سکه های موجود(1 سنتی, 5سنتی ,10سنتی,20سنتی,25سنتی و نیم دلاری).
خروجی:پس دادن بقیه پول با حداقل تعداد سکه ها.
(set Greedy-Applying(c
}
{1,5,10,20,25,50}=C
;[0]=S
∅=!While(!solution(s)&&c(
}
;(X=SELECT(C
{C=C-{x
((IF(FEASIBLE(S,X
{S=S+{X
{
((if(solution(s
;return S
else
(∅)return
{
[ویرایش] مثال1
در روش حریصانه، رسیدن به هدف در هر گام مستقل از گام قبلی و بعدی است. یعنی در هر مرحله برای رسیدن به هدف نهایی، مستقل از این که در مراحل قبلی چه انتخابهایی صورت گرفته، و انتخاب فعلی ممکن است چه انتخابهایی در پی داشته باشد، انتخابی که در ظاهر بهترین انتخاب ممکن است صورت میپذیرد. به همین دلیل است که به این روش، روش حریصانه گفته میشود. زمانی که یک دزد عجول و حریص وارد خانهای میشود، در مسیر حرکت خود هر وسیله و کالای با ارزشی را داخل کیسه میاندازد. وی در این حالت چندان توجهی نمیکند که چه اشیائی را قبلا برداشته، و ممکن است در آینده چه اشیاء گرانبهاتری به دست آورد. او در هر گام تنها از بین اشیاء دم دست خود با ارزشترین آن را انتخاب کرده و به وسایل قبلی اضافه میکند.
این روش کاربردهای عمومی دیگری نیز دارد. زمانی که در مقابل خرید از یک فروشگاه یک اسکناس تحویل فروشنده داده میشود، وی با یک حساب سرانگشتی سعی میکند با حداقل اسکناسها و سکههای ممکن باقیمانده پول را تولید کرده و به خریدار تحویل دهد. این حساب سرانگشتی ممکن است روش حریصانه باشد.
خریداری از یک فروشگاه یک جنس 64تومانی می خرد و 100 تومان به فروشنده می دهد و فروشنده باید 36 تومان به او برگرداند.اگر فروشنده سکه های 50،25،10،5،1تومانی (از هرکدام حداقل یک نمونه)داشته باشد چگونه می تواند بقیه پول خریدار را برگرداند به نحوی که تعداد سکه ها(در کل) کمترین مقدار ممکن باشد؟
یک راه حل حریصانه به این صورت است:
در ابتدا هیچ سکه در مجموعه جواب نداریم. از بین سکه های موجود بزرگ ترین ممکن یعنی 25 تومانی را انتخاب می کنیم.این مرحله از الگوریتم حریصانه راروال انتخاب(select procedure) گویند. اگر یک سکه 25 تومانی دیگر را انتخاب کنیم حاصل از 36 تومان بیشتر شده، لذا آن را کنار گذاشته به سراغ سکه 10 تومانی می رویم. حال بررسی می کنیم اگر این سکه 10 تومانی را به مجموعه انتخابی قبلی اضافه کنیم حاصل از 36 تومان بیشتر می شود یا خیر.این مرحله را تحقیق عملی بودن(feasibililty check) می نامند. حال اگر این 10 تومان را به25 تومان جمع مجموعه انتخاب شده 35 می شود که هنوز به 36 نرسیده است. این مرحله را تحقیق حل شدن(Solution check) می گوییم. در ادامه سکه های دیگر را به ترتیب مقایسه می کنیم و در نهایت با انتخاب سکه یک تومانی در کل با 3 سکه (25 تومانی و 10 تومانی و یک تومانی) 36 تومان به دست می آید و این حداقل تعداد سکه ممکن است.
توجه کنید در انتخاب فوق ملاک انتخاب ،برای انتخاب بهترین سکه در هر مرحله(بهینه محلی) سکه است و در انتخاب سکه در هر مرحله به انتخاب های قبلی و بعدی کاری نداریم. در این شیوه اجازه فکر کردن درباره یک انتخاب انجام شده را نداریم یعنی هنگامی که سکه ای پذیرفته شد به طور دائم جزو حل به حساب می آید و هنگامی هم که سکه ای رد می شود به طور دائم از حل کنار گذاشته می شود.
همان طور که مشاهده کردید این روش بسیار ساده است،ولی اصلی ترین نکنه این است که آیا این روش الزاما به یک حل بهینه می رسد؟ در رابطه با مسأله خاص فوق می توان اثبات کرد که جواب بهینه است ولی با مثال زیر نشان می دهیم که ممکن است این گونه نباشد.
[ویرایش] مثال2
فرض کنید قرار است به فردی 16 تومان پس بدهیم. سکه های موجود 1،5،10،12،25تومانی است( با این که ما در ایران سکه 12 تومانی نداریم ولی این فرض را بکنید که داریم).
با الگوریتم حریصانه فوق به این نتیجه می رسیم که باید به این فرد یک سکه 12 تومانی و 4 سکه 1 تومانی بدهیم یعنی جمعا 5 سکه. در حالی که حل بهینه مسأله فوق یک سکه 10 تومانی، یک سکه 5 تومانی و یک سکه یک تومانی است یعنی در کل 3 سکه.
از مثال فوق نتیجه می گیریم که هر الگوریتم حریصانه الزاما حل بهینه را نمی دهد و برای هر مسأله خاص باید اثبات کنیم که آیا الگوریتم حریصانه برای آن، جواب بهینه می دهدیا خیر و این موضوع اغلب سخت ترین مرحله کار است .
با توجه به مثال های فوق می توان مراحل روش حریصانه را به این صورت بیان کرد:
کار با یک مجموعه تهی شروع شده و به ترتیبی خاص عناصری به مجموعه اضافه می شوند.هر دور تکرار الگوریتم شامل مراحل زیر است:
روال انتخاب: این روال عنصر بعدی را طبق یک معیار حریصانه انتخاب می کند. این انتخاب یک شرط بهینه را در همان برهه بر آورده می سازد.
تحقیق عملی بودن: در این مرحله مشخص می شود که آیا مجموعه جدید به دست آمده، برای رسیدن به حل عملی است یا خیر.
تحقیق حل: مشخص می سازد که آیا مجموعه جدید، نمونه مورد نظر را حل کرده است یا خیر.
[ویرایش] منابع
- ↑ درس و کنکور طراحی الگوریتم،مؤلف: حمیدرضا مقسمی،انتشارات گسترش علوم پایه
- مقدمهای بر الگوریتمها - پدیدآورنده: تامس کورمن، چارلز لیزرسان، رونالد دیوست، کلیفورد اشتاین -(clrs)
- درس و کنکور طراحی الگوریتم،مؤلف: حمیدرضا مقسمی،انتشارات گسترش علوم پایه
- Discrete Mathematics and its Applications,Kenneth H.Rosen ,fifth edition
for i:=۱ to r
while n≤
begin
add a coin with value