الگوریتم حریصانه

از ویکی‌پدیا، دانشنامهٔ آزاد
پرش به: ناوبری، جستجو

روش حریصانه[ویرایش]

نام این روش از شخصیت معروف اسکروج گرفته شده است.اسکروج به جای آن که به گذشته و آینده فکر کند،تنها انگیزه هر روز او به دست آوردن طلای بیشتر بود.الگوریتم حریصانه(Greedy) نیز مانند شیوه اسکروج می باشد.

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

الگوریتم حریصانه کمترین تعداد سکه هایی که باعث شود مسئله تغییر نماید را تعیین می نماید .اینها مراحل یک انسان هستند که سکه با مقدار ۳۶ را با استفاده از سکه‌های با مقادیر ۱و۵و۱۰و۲۰ تعیین می کند. سکه با بزرگترین مقدار و کوچکتر از تغییرات باقی‌مانده بعنوان بهینه محلی انتخاب می گردد(توجه کنید که در حالت معمول مسئله پیدا کردن تغییرات بااستفاده از برنامه‌ریزی پویا یا Linear programming Integer unknowns جواب بهینه را پیدا می کند).پول آمریکا و دیگر کشورهانمونه‌های خاصی هستند که با استفاده از الگوریتم حریصانه می توان جواب بهینه آنهارا پیدا کرد).]] در بسیاری از موارد مسئله از ما می‌خواهد که یک متغیر را کمینه یا بیشینه کنیم و یا اینکه صورت مسئله مستقیماً از ما نمی‌خواهد که چیزی را کمینه یا بیشینه کنیم اما می‌توان این مسئله را تبدیل به یک چنین مسئله‌ای کرد. در اکثر مسائل از این دست ما باید تعدادی انتخاب انجام دهیم و مسئله در تعدادی مرحله حل شود. بازهٔ وسیعی از این مسائل توسط الگوریتم‌های حریصانه قابل حل‌اند. الگوریتم‌های حریصانه در هر مرحله در نظر می‌گیرند که کدام انتخاب در حال حاضر بهترین وضعیت را برای ما رقم می‌زند و آن را انجام می‌دهند بدون در نظر گرفتن این که انجام این حرکت در آینده ممکن است به ضرر ما تمام شود. بنابراین الگوریتم‌های حریصانه همیشه جواب درست را به ما نمی‌دهند اما خیلی وقت‌ها هم اینطور نیست این دسته از الگوریتم‌ها در علوم رایانه کاربرد وسیعی دارند.

حال مثالی برای اینگونه الگوریتم‌ها می‌اوریم:

فرض کنید می‌خواهیم n تومان را با سکه های۲۵ تومانی۱۰ تومانی۵ تومانی۱ تومانی پرداخت کنیم به طوری که کمترین تعداد سکه را بپردازیم. ما می‌توانیم یک الگوریتم حریصانه برای حل این مسئله ارائه دهیم که تعداد سکه بهینه را در هر مرحله بدست آورد برای این کار ما در هر مرحله بزرگترین سکه‌ای را که از پول باقی‌مانده تجاوز نکند انتخاب می‌کنیم در این صورت تعداد سکه‌ها بهینه خواهدبود.

        prededure change({c_1},{c_2},{...},{c_r}:value of denominations of coin,wherer {c_1}>{c_2}>{...}>{c_r};n:a positive integer
                                                                    for i:=۱ to r    
                                                                        while n≤{c_i}
                                                                            begin 
                                       add a coin with value {c_i} to change
                                                                  n:=n-{c_i}
                                                                              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 سکه.

از مثال فوق نتیجه می گیریم که هر الگوریتم حریصانه الزاماً حل بهینه را نمی‌دهد و برای هر مسأله خاص باید اثبات کنیم که آیا الگوریتم حریصانه برای آن، جواب بهینه می دهدیا خیر و این موضوع اغلب سخت ترین مرحله کار است .

با توجه به مثال های فوق می توان مراحل روش حریصانه را به این صورت بیان کرد:

کار با یک مجموعه تهی شروع شده و به ترتیبی خاص عناصری به مجموعه اضافه می شوند.هر دور تکرار الگوریتم شامل مراحل زیر است:

روال انتخاب: این روال عنصر بعدی را طبق یک معیار حریصانه انتخاب می کند. این انتخاب یک شرط بهینه را در همان برهه بر آورده می سازد.

تحقیق عملی بودن: در این مرحله مشخص می شود که آیا مجموعه جدید به دست آمده، برای رسیدن به حل عملی است یا خیر.

تحقیق حل: مشخص می سازد که آیا مجموعه جدید، نمونه مورد نظر را حل کرده است یا خیر

مثال

روش حریصانه در حل مسئله کوله پشتی صفر ویک :مثالی از این مساله مربوط به دزدی میشود که با کوله پشتی وارد یک جواهر فروشی میشود اگر وزن قطعات از یک حد بیشینه Wفراتر رود کوله پشتی پاره خواهد شد .هر قطعه دارای ارزش و وزن معینی خواهد بود .مسئله ای که دزد با آن مواجه است ،تعیین حداکثر ارزش قطعات است در حالی که وزن کل آن ها از حد معین Wفراتر نرود .این مسئله را کوله پشتی صفر ویک میگویند .میتوان مسئله را بصورت زیر بیان کرد. فرض کنید nقطعه وجود داشته باشد ،به طوری که:

s=[item1,item2,item3,...,itemn]

Wi=item1وزن Pi=itemiارزش W=حداکثر وزنی که کوله پشتی قادر به تحمل آن است. وwi,pi,wهمگی اعداد صحیحی هستند . راه حل جستجوی جامع این است که همه ی زیر مجموعه های این nقطعه را در نظر بگیریم ،زیرمجموعه هایی را که وزن کل آنها از wفراتر نرود ،کنار میگذاریم واز میان آن هایی که باقی می ماند،آن را که بیشترین ارزش را دارد،انتخاب میکنیم

[۱]

منابع[ویرایش]

  1. درس و کنکور طراحی الگوریتم،مؤلف: حمیدرضا مقسمی،انتشارات گسترش علوم پایه
  • Discrete Mathematics and its Applications,Kenneth H.Rosen ,fifth edition