Study of Branch & Bound
A New Approach to 0/1 Knapsack Problem with Greedy and Heuristic Searches in Integer Programming
Tam Sayı Programlamada Açgözlü ve Sezgisel Aramalar ile 0/1 Sırt Çantası Problemine Yeni Bir Bakış
The web link of the article is here
Download the article in PDF format.
Abstract:
Integer programming is a type of optimized Linear Programming method. The goal is to get rid of unrealistic results that might occur in the linear programming process. Integer Programming is applied to many engineering fields. In this study, a new heuristic and greedy approach to the conventional Integer Programming method is proposed to the well-known knapsack problem, which is accepted as the source of many engineering problems. Heap data structure, additionally, is used in order to decrease both space complexity and implementation time. In the experimental applications, it is observed that the proposed method yields less computational time than the recursive, pruned, and optimized methods.
A-Star Heuristic Approach ile Branch&Bound Algorithm can be applied to the KnapSack problem. The problem and the implemented C/C++ codes can be as follows:
Branch & Bound
Yangından Mal Kaçırma
Aynı okulda öğrenci olan Mustafa ile Mehmet, Yunus ve İshak ikilisinden pek hoşlanmadıkları için yurtta sürekli bir yerleri yakmaktadırlar. Yunus ve İshak ikilisi bilgisayar olimpiyatçısı olduğu için yurt müdürü Bahadır bey, bu ikiliyi yurdun itfaiye birliğine seçmiştir. Bahadır Bey’in isteği yurttaki demirbaşların en önemlilerin kurtarılmasıdır. Bunun için Bahadır Bey Yunus ve İshak’a demirbaş listesini vermiştir. Yunus bu sorunu Knapsack algoritmasını kullanarak çözerken İshak başka bir algoritma kullanmak istemiştir. Aklına ilk olarak Branch & Bound algoritması gelmiştir. Sizden istenen bu sorunu tıpkı İshak gibi Branch & Bound algoritmasıyla çözmenizdir.
Girdi :
girdi.in dosyasının ilk satırda demirbaş sayısı N, çantanın kapasite değeri K verilmektedir.
Sonraki N satırda ise her demirbaşın ağırlığı ve pahası verilmektedir.
Çıktı :
cikti.out dosyasında kurtarılan demirbaşların değerleri toplamı.
Örnek Girdi ve Çıktı :
girdi.in
4 16
4 12
7 63
8 56
10 100
cikti.out
119
Kısıtlar :
N < 30
K < 100.000
Ağırlık ve Paha < 10.000
Hesaplama Süresi < 1sn
C/C++ Çözüm Kodları şu şekilde:
#include<stdio.h>
FILE *oku,*yaz;
int dizi[3000][3];
int parca_sayisi,kapasite;
int upperbound;
int alt_sinir=0;
int cmp(int *a,int *b)
{
return *(a+2)<*(b+2);
}
void Oku()
{
int i;
oku=fopen("girdi.in","r");
fscanf(oku,"%d %d ",&parca_sayisi,&kapasite);
for(i=0;i<parca_sayisi;i++)
{
fscanf(oku,"%d %d ",&dizi[i][0],&dizi[i][1]);
dizi[i][2]=dizi[i][1]/dizi[i][0];//dizi[i][2]=birim agirligi
}
qsort(dizi,parca_sayisi,sizeof(int)*3,cmp);//birim degerine gore buyukten kucuge siraladik
upperbound=dizi[0][2]*kapasite;//ustsinir'i buluyoruz //en buyuk birim degerlinin birim degeriyle kapasiteyi carptik
}
void Rec(int kullanilan_kapasite,int esya,int deger)
{
if(esya==parca_sayisi)//butun esyalari denemissek
{
if(deger>alt_sinir)//daha buyuk sonuc bulmussak
alt_sinir=deger;
return;
}
if(deger+dizi[esya][2]*(kapasite-kullanilan_kapasite)<alt_sinir)//alt sinirdan kucukse return et
return;
if(kullanilan_kapasite+dizi[esya][0]<=kapasite && deger+dizi[esya][1]<upperbound)//esyayi larak gitme
Rec(kullanilan_kapasite+dizi[esya][0],esya+1,deger+dizi[esya][1]);
Rec(kullanilan_kapasite,esya+1,deger);//esyayi almadan gitme
}
void Yaz()
{
yaz=fopen("cikti.out","w");
fprintf(yaz,"%d\n",alt_sinir); //Alt sinir yani cantayi kapasiteyi asmadan doldurabilecegimiz en degerli durum
fclose(yaz);
}
int main()
{
Oku(); //Okuma islemlerini yapiyoruz
Rec(0,0,0); //upperboundu gecmeyen ve sonuc olarak buldugumuz en buyuk degerden kucuk olmayan tum durumlari deneyecek Recursive fonksiyon
Yaz(); // Ve son olarak yazma islemi
return 0;
}
C/C++ kodları için test girdi ve çıktıları için burayı tıklayın.
Referans vermek için (for citations):
Faruk BULUT, İ. Furkan INCE, "Tam Sayı Programlamada Açgözlü ve Sezgisel Aramalar ile 0/1 Sırt Çantası Problemine Yeni Bir Bakış", 2018