پرش به محتویات

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

توضیحات

الگوریتم های حریصانه یا گریدی دسته ای از الگوریتم ها هستند که ما در هر مرحله سعی میکنیم همواره بهترین گزینه را انتخاب کنیم. کاربرد این الگوریتم ها بسیار زیاد و متنوع است. در ادامه چند مسئله که به کمک این الگوریتم ها حل میشوند آمده است.

مسئله کوله پشتی (مایع)

در این مسئله ما \(n\) مایع داریم که از مایع \(i\) ام ‍ \(L_i\) لیتر وجود دارد. قیمت هر لیتر از مایع \(i\) ام \(C_i\) تومان است و وزن هر لیتر از این مایع \(V_i\) گرم است. ما میخواهیم به بازار برویم و مقداری از این \(n\) مایع ها را بفروشیم ولی متاسفانه حداکثر \(W\) گرم می‌توانیم حمل کنیم و می‌خواهیم بدانیم حداکثر فروشی که می‌توانیم در یکبار رفتن به بازار داشته باشیم چقدر است.

راه حل

ابتدا مایع ها را بر حسب \(\frac {C_i} {V_i}\) از زیاد به کم مرتب میکنیم. برای سادگی در ابتدا فرض کنید برای هیچ دوتایی این مقدار برابر نیست. حال به ترتیب شروع میکنیم و از هر مایع هر چقدر که میتوانیم برمیداریم. یعنی اگر تا کنون \(w\) گرم برداشته ایم از مایع کنونی \(min(\frac {W-w} {V_i} , L_i)\) لیتر بر می داریم.

فرض کنید حالتی وجود داشته باشد که فروش بیشتری داشته باشیم. یکی از حالات بهینه را در نظر بگیرید. میدانیم مایع ای وجود دارد که نسبت به حالت اول از آن بیشتر فروخته ایم. این مایع را در نظر بگیرید و فرض کنید از آن \(l\) لیتر بیشتر فروخته ایم . اگر مایع ای نباشد که در ترتیب ما زودتر آمده باشد و الان کمتر فروخته شده باشد پس ما از این مایع بیشینه مقدار ممکن را انتخاب نکرده بودیم که تناقض است. اگر مایع ای وجود داشته باشد که کمتر فروخته باشیم و در ترتیب ما زود تر آمده باشد میتوانیم از آن بیشتر بفروشیم و از این مایع کمتر و سود بیشتری کسب کنیم پس حالتی که در نظر گرفتیم بهینه ترین حالت نبوده است که باز هم در تناقض است با فرض خلف ما.

حال اگر \(i\) و \(j\) وجود داشت که \(\frac {C_i} {V_i} = \frac {C_j} {V_j}\) و همچنین \(R = \frac {V_i} {V_j}\) آنگاه اگر \(l\) لیتر از مایع \(i\) ام بفروشیم مانند این است که \(l \times R\) لیتر از مایع \(j\) بفروشیم پس کافیست به مقدار مایع \(j\) که داریم \(L_i \times R\) واحد اضافه کنیم و خللی در اثبات به وجود نمی آید.

دقت کنید، برای سورت کردن مایع ها بر حسب \(\frac {C_i} {V_i}\) می‌توانید یک آرایه از اندیس ها را به کمک تابع سورت و این تابع cmp سورت کنید.

1
2
3
    bool cmp(int i, int j){
        return C[i] * V[j] < C[j] * V[i]; // (1)!
    }
  1. می‌توان به راحتی ثابت کرد چک کردن این شرط معادل چک کردن \(\frac {C_i} {V_i} < \frac {C_j} {V_j}\) است. با چک کردن این شرط از خطای اعشاری جلوگیری می‌شود.

Matching vs Independent Set

در این مسئله گرافی \(3 \times n\) راسی داریم و میخواهیم یا مجموعه مستقل حداقل \(n\) راسی پیدا کنیم یا تطابقی با حداقل \(n\) یال.

راه حل

همواره تا وقتی که گراف خالی از یال نشده یک یال را انتخاب میکنیم و رئوس دو سرش به همراه تمام یال های متصل به آن ها را حذف میکنیم حال در انتها اگر حداقل \(n\) راس بماند که میدانیم این رئوس یالی بینشان نیست و مجموعه مستقل هستند. در غیر این صورت میدانیم بیش از \(n\) یال انتخاب کرده ایم زیرا هر مرحله ۲ راس حذف میشوند. همچنین رئوس دوسر یال ها دو به دو متفاوت هستند و در نتیجه این یال ها تطابق ما هستند.

نکته

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

سوال ها


سوال سختی تگ ها جاج
Printed PR 1000
Spoiler
SGU
Telecasting station 1200
Spoiler
SGU
Great Sequence 1200
Spoiler
Codeforces
Knapsack 1300
Spoiler
Codeforces
Number Game 1400
Spoiler
Codeforces
Magic Powder 2 1500
Spoiler
Codeforces
Zero Array 1500
Spoiler
Codeforces
Tree Infectoin 1600
Spoiler
Codeforces
Keshi Is Throwing a Party 1600
Spoiler
Codeforces
Equal Frequencies 1600
Spoiler
Codeforces
Basketball 1600
Spoiler
SGU
Two Arrays and Sum of Functions 1600
Spoiler
Codeforces
secrets 1600
Spoiler
Codeforces
Minimizing Difference 2000
Spoiler
Codeforces
Project Planning 2000
Spoiler
Created by potrace 1.16, written by Peter Selinger 2001-2019 Atcoder
Matching vs Independent Set 2100
Spoiler
Codeforces
Minimax 2100
Spoiler
Codeforces
The Human Equation 2100
Spoiler
Codeforces
Pokémon Army (hard version) 2100
Spoiler
Codeforces
GukiZ hates boxes 2200
Spoiler
Codeforces
New Game Plus! 2200
Spoiler
Codeforces
Coins 2400
Spoiler
Codeforces
DeadLee 2400
Spoiler
Codeforces
Taking The Middle 2700
Spoiler
Created by potrace 1.16, written by Peter Selinger 2001-2019 Atcoder
Shop 2800
Spoiler
Codeforces
Candy Shop 2900
Spoiler
Codeforces
Outermost Maximums 3400
Spoiler
Codeforces

نظرات