مسئله کوله‌پشتی

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

George Dantzig الگوریتمی تقریبی از نوع حریصانه برای حل مسئله کوله پشتی بیکران ارائه داد.
به این ترتیب که اشیا را به ترتیب نزولی بر حسب ارزش به واحد وزن مرتب می‌کند () سپس از شی شماره ۱ شروع می‌کند. بیشترین تعداد ممکن از آن را در کوله پشتی قرار می‌دهد، تا زمانی که دیگر جای خالی ای برای آن نوع باقی نماند. آنگاه سراغ شی بعدی می‌رود. (دقت کنید که در این نسخه از سؤال، محدودیتی برای تعداد اشیا نداریم) اگر  بیشینه ارزش اشیایی باشد که در کوله پشتی جا می‌شوند، این الگوریتم حداقل به مقدار  دست می‌یابد. اما اگر تعداد مجاز از هر شی محدود باشد، ممکن است خروجی این الگوریتم از پاسخ بهینه بسیار دور باشد.

روابط پوشانندگی در مسئلهٔ کوله پشتی بیکران

در حل مسئلهٔ کوله پشتی بیکران، با کنار گذاشتن اشیایی که هیچوقت مورد استفاده قرار نمی‌گیرند، می‌توان مسئله را ساده‌تر کرد. برای مثال، فرض کنید برای شی ای مانند i، می‌توان زیر مجموعه از اشیا به نام J یافت طوری‌که ارزش مجموع آن‌ها بزرگتر از ارزش i و وزن مجموع آن‌ها کمتر از وزن i باشد؛ بنابراین، i نمی‌تواند در جواب بهینه بیاید. در این هنگام مجموعهٔ J را پوشاننده ی i می‌گوییم. (توجه کنید این استدلال برای مسئلهٔ کوله پشتی کراندار نمی‌تواند مورد استفاده قرار گیرد. زیرا ممکن است قبلاً از اشیا سازندهٔ مجموعهٔ J استفاده کرده باشیم و تمام شده باشند)
پیدا کردن روابط پوشانندگی، به ما کمک می‌کند تا تا حجم فضای جستجو را در حد قابل توجهی کاهش دهیم. انواع مختلفی از روابط پوشانندگی وجود دارند،
که همگی در نامساوی زیر صدق می‌کنند:
، and  for some 
که:
 و . و  تعداد انتخاب‌های شی نوع j را نشان می‌دهد. (دقت کنید این jها، اعضای مجموعهٔ J هستند)

پوشانندگی انتخابی

شی  ام، به‌طور انتخابی توسط  پوشانده شده، اگر جمع وزن تعدادی از اعضای مجموعهٔ ، کمتر از  باشد و جمع ارزش آن‌ها بیشتر از .
به بیان ریاضی:
 و  درصورتی که  که .
بررسی این نوع پوشانندگی، از لحاظ پیچیدگی محاسباتی چندان ساده نیست، بنابراین از بهترین روش‌ها، راه حل پویاست. در واقع این مسئله، یک مسئله کوله پشتی، اما با پارامترهای کوچکتر، مطابق زیر است:

،

و اشیا محدود به مجموعهٔ  هستند.
نماد ریاضی پوشانندگی انتخابی به صورت  است.

پوشانندگی حدی

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

پوشانندگی چندگانه

شی ، به‌طور چندگانه توسط شی  پوشانده شده، اگر  توسط تعدادی از شی نوع  پوشانده شود. (یعنی شی ، فقط توسط تعدادی شی از نوع  پوشانده شود و نیازی به استفاده از اشیا دیگر نباشد). به بیان ریاضی:
 و  برای 
که .
این پوشانندگی می‌تواند برای بهینه کردن پروسهٔ حل مورد استفاده قرار گیرد، زیرا تشخیص روابط پوشانندگی از این نوع، به محاسبات زیادی نیاز ندارد و نسبتاً ساده است.
نماد ریاضی پوشانندگی انتخابی به صورت  است.

پوشانندگی ماژولار

فرض کنیم  بهترین شی باشد، یعنی برای تمام ها، .  شی ای با بیشترین چگالی است.
شی  ام، به‌طور ماژولار توسط شی  پوشانده شده، اگر توسط  و تعدادی شی از نوع  پوشانده شود. (یعنی شی ، فقط توسط  و تعدادی شی از نوع  پوشانده شود و نیازی به استفاده از اشیا دیگر نباشد) به بیان ریاضی:
 و 
که .
نماد ریاضی پوشانندگی ماژولار به صورت  است.

الگوریتم کوله پشتی با استفاده از روش حریصانه

void Greedy Knapsack(w,n)
{
//W is the knapsack and the n objects
sort (p,w)//Pi/Wi>=Pi+1/Wi+1
for(i=0;i<n;i++)
    x[i]=۰
    U=W
    for(i=0;i<n;i++)
 if(W[i]>u);
break ;
[
x[i]=1;
u=u-[wi]
}
if(i<n)
    x[i]=u/w
}

شبه کد عقبگرد برای مسئله کوله پشتی ۰و۱

از انجاییکه این مسئله بهینه‌سازی است، ما رد بهترین مجموعه کنونی کالاها و مجموع ارزش آن‌ها را نگه می‌داریم که اینکار توسط ارائه bestset و و یک متغیر maxprofit انجام می‌شود. این مسئله را برای یافتن اولین جواب بهینه مطرح می‌کنیم
مسئله:n کالا داریم که هر کدام از آن‌ها دارای ارزشی و وزنی دارند. ارزش‌ها و وزن‌ها، اعدادی صحیح و مثبت هستند. مجموعه‌ای از کالاها با حداکثر مجموع ارزش را طوری تعیین کنید که مجموع اوزان آن‌ها بیش از عدد صحیح مثبت w نشود
ورودی:اعداد صحیح مثبت nوw,ارایه‌های wوpکه از ۱ تاn شاخص دهی شده و هر یک شامل اعداد صحیح و مثبتی هستند که به ترتیب غیر نزولی بر اساس مقادیر [p[i]/w[i مرتب شده‌اند
خروجی:مقدار صحیح maxprofit که ماکزیمم ارزش است، ارائه bestset که از ۱ تا n شاخص دهی شده و در مقادیر bestsetو "yes"است اگر کالای iام در مجموعه بهینه قرار داشته باشد در غیر اینصورت مقدار ان "no" می‌باشد
* void knapsack (index I ,
*            int profit , int weight)
* {
*   if (weight<=W && profit>maxprofit){
*     maxprofit=profit;
*     numbest=i;
*     bestset=include;
*   }
*  if(promising(i)){
*  include[i+1]=”yes”;
* knapsack(i+1,profit+p[i+1],weight+w[i+1]);
* include[i+1]=”no”
* knapsack(i+1,profit,weight);
* }
* }
* bool promising(index i)
* {
* index j,k;
* int totweight;
* float bound;
* if(weight>=W)
* return false;
* else {
* j=i+1;
* bound=profit;
* totweight=weight;
* while(j<=n && totweight + w[j]<=W){
* totweight=totweight+w[j];
* bound=bound+p[j];
* j++;
* }
* k=j;
* if(k<=n)
* bound=bound+(W-totweight)*p[k]/w[k];
* return bound>maxprofit;
* }
* }
طبق قرار دادn,w,p,W ,numbest , bestset , include , maxprofit ورودی‌های روتین نیستند. اگر این متغیرهای را به صورت سراسری تعریف می‌کردیم، شبه کد زیر ماکزیمم ارزش و مجموعه دارای این ارزش را تولید می‌کرد:
* numbest=0;
* maxprofit = 0 ;
* knapsack(0,0,0);
* cout <<maxprofit;      // نوشتن ماکزیمم ارزش
* for (j=i ; j<=numbest ; j++)     //نمایش مجموعه بهینه کالاها
* cout<<bestset[i];

کاربردها

مسئلهٔ کوله پشتی می‌تواند در تصمیم‌گیری‌هایی که در دنیای واقعی با آن‌ها روبرو هستیم، مورد استفاده قرار گیرد. مانند بریدن کالا به‌طوری‌که کمترین مقدار به هدر رود، انتخاب سرمایه‌گذاری‌ها و سبد سهام، انتخاب دارایی‌ها برای مسئلهٔ امنیت دارایی‌های قبلی و ساختن کلیدها برای سیستم رمزنگاری کوله پشتیِ مرکل-هلمن.
== یکی از کاربردهای اولیهٔ مسئلهٔ کوله پشتی، طراحی و بارم بندی آزمون است به نحوی که آزمون دهنده در پاسخگویی به سؤالات حق انتخاب داشته باشد. چنانچه بارم بندی سؤالات همگن باشد، مسئله بسیار ساده خواهد شد. برای مثال، اگر آزمون دارای 12 سؤال، هر سؤال به ارزش 10 نمره باشد، آزمون دهنده باید فقط 10 سؤال را پاسخ دهد تا به بیشینه نمره ممکنِ 100 برسد. اما برای آزمون‌هایی با بارم بندی نایکسان، مسئله کمی سخت‌تر می‌شود. Feuerman و Weiss سیستمی ارائه دادند که در آن دانش آموزان با آزمونی با بارم بندی ناهمگن، با جمع بارم 125 روبرو هستند. از دانش آموزان خواسته می‌شود با توجه به توانایی‌های خود به سؤالات پاسخ دهند. در اینجا با مسئلهٔ کوله پشتی روبرو هستیم. چه زیر مجموعه‌هایی، جمع نمره‌ای برابر با 100 خواهند داشت؟ برای هر دانش آموز، پاسخ گویی به کدام زیر مجموعه از سؤالات، نمرهٔ بیشتری را به ارمغان می‌آورد؟

یک مثال از مسئله کوله پشتی

صورت مسئله: دزدی قصد سرقت از مغازه‌ای را دارد و حداکثر وزن w از اجناس را که می‌تواند بدزد در این مغازه n نوع جنس وجود دارد. اگر وزن جنس iام wi و قیمت آن vi باشد بیشینه سودی که بدست می‌آورد چقدر است؟
این مسئله به دو صورت تعریف می‌شود:
1- صفر و یک
در حالت صفر و یک مسئله به این صورت تعریف می‌شود که دزد یا یک جنس را برمی‌دارد یا برنمی‌دارد و حق برداشتن تکه‌ای از یک جنس را ندارد. برای این مسئله راه حل حریصانه‌ای وجود ندارد و به ارائه یک راه حل پویا خواهیم پرداخت.
ایده حل این مسئله در حالت پویا یه ابن صورت هست که دزد یا جنس iام را برمی‌دارد یا برنمی‌دارد و براساس این دو حالت سود زیرمسئله ایجاد شده محاسبه می‌شود و از مسیری که جواب بیشینه را داده پیش خواهیم رفت. به عبارتی:
کد
c[i,w] = c[i-1, w]
 if wi ≥ 0
 max [vi + c[i-1, w-wi], c[i-1, w]}
 if i>0 and w ≥ wi
شبه کد
Dynamic-0-1-knapsack (v, w, n, W)
 for w = 0 to W
 do c[0, w] = 0
 for i = 1 to n
 do c[i, 0] = 0
 for w = 1 to W
 do if wi ≤ w
 then if vi + c[i-1, w-wi]
 then c[i, w] = vi + c[i-1, w-wi]
 else c[i, w] = c[i-1, w]
 else
 c[i, w] = c[i-1, w]
۲-کسری
در این حالت از مسئه دزد می‌تواند قسمتی از یک جنس را بردارد و مثل حالت قبل ۰ و ۱ی نمی‌باشد.
برای این مسئله راه حال حریصانه وجود داره و به این شکل هست که دزد تا می‌تواند جنس پرارزش تر را برداشته و درصورتی که نتوانست بیشترین کسر ممکن آن را برمی‌دارد.

تاریخچه

مسئلهٔ کوله پشتی بیش از یک قرن مورد مطالعه قرار گرفته و اولین بررسی در سال ۱۸۹۷ انجام گرفته‌است. هر چند اولین داده‌های ثبت شده در این مورد، به کارهای ریاضیدانی به نام (1884–1956) Tobias Dantzig برمی گردد، چیزی با عنوان مسئلهٔ کوله پشتی قبلاً در میان عامهٔ مردم وجود داشته‌است.
مسئلهٔ کوله پشتی درجه دوم، اولین بار توسط Hammer, Gallo و Simeone در سال ۱۹۶۰ مطرح شد.
در سال ۱۹۸۸، تحقیقی از دانشگاه استونی بروک بر روی مجموعه‌ای از الگوریتم‌ها، نشان داد که از میان ۷۵ مسئلهٔ الگوریتمی، مسئلهٔ کوله پشتی، ۱۸ امین مسئلهٔ معروف و ۴ امین مسئلهٔ پرکاربرد بعد از درخت کی دی، درخت پیشوندی و bin packing problem است.