複習分數揹包問題

揹包問題,我就知道有零一揹包和分數揹包。零一揹包看了就忘,想起來再看,再看再忘。ios

分數揹包沒怎麼看過,也沒怎麼記住。今天心血來潮,在網上找到了一段代碼(本段代碼來自百度的一個叫「冰藍沸點」的空間,地址:http://hi.baidu.com/nikopolidis/item/d31f4316997bb6ce38cb3064。我作了一下格式化),以下:this

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

class bag{
	private:
		int id;
		int weight;
		int profit;
 
	public:
		bag(){};
		bag(int i, int w, int p):id(i), weight(w), profit(p){}
		int getID(){return id;}
		int getWeight(){return weight;}
		int getProfit(){return profit;}
		double getValue(){return ((double) profit/(double) weight);}
		bag& operator=(bag &a);
};

bag& bag::operator=(bag &a)
{
	id = a.id;
	weight = a.weight;
	profit = a.profit;
	return *this;
}

bool operator<(bag &a, bag &b)
{
	double aValue, bValue;
	aValue = a.getValue();
	bValue = b.getValue();
	return (aValue<bValue ? true : false);
}

void arrayPrint(bag *a, int n)
{
	for(int i = 0; i < n; i++)
	  cout << a[i].getID() << " ";
	cout << endl;
}

void selectionSort(bag *a, int n)
{
	 for(int i = 0; i < n; i++){
	   int min = i;
	   for(int j = i + 1; j < n; j++){
		if(a[j] < a[min])
			min = j;
	   }
	   swap(a[i], a[min]);
	 }
}


void knapsack(bag *a, int n, double limitWeight)
{
	 selectionSort(a, n);
	 double curWeight = 0.0;
	 double curProfit = 0.0;
	 for(int i = n - 1; i >= 0; i--){
		   if(curWeight + a[i].getWeight() <= limitWeight){
				cout << a[i].getID() << "(1)" << " ";
				curWeight += a[i].getWeight();
				curProfit += a[i].getProfit();
				if(curWeight == limitWeight){
					 cout << endl;
					 break ;
				}
		   }else{
				double propotion = (limitWeight - curWeight) / a[i].getWeight();
				curWeight += (a[i].getWeight() * propotion);
				curProfit += (a[i].getProfit() * propotion);
				cout << a[i].getID() << "(" << propotion << ")" << endl;
				break ;
		    }
	 }
	 cout << "Total profit: " << curProfit << ".\n";
}

int main()
{
	int weight1 = 2, weight2 = 4, weight3 = 1000,
	profit1 = 1000, profit2 = 20, profit3 = 20;
	bag a(2, weight1, profit1);
	bag b(1, weight2, profit2);
	bag c(0, weight3, profit3);
	bag *bagArray = new bag[3];
	bagArray[0] = a, bagArray[1] = b, bagArray[2] = c;
	knapsack(bagArray, 3, 5.0);
	return 0;
}

       看完代碼,明白了。spa

       分數揹包要解決的問題是這樣的:有個揹包和一堆細軟。要把細軟裝到包裏。若是細軟太大(或者過重)裝不進去的話,能夠剁碎了變成小細軟。如今讓你把包裝滿,而且達到包裏的細軟總價值最大的效果。至於爲何是揹包,而不是挎包,行李箱之類的東西,這我就不知道了。可能就是個抽象含義吧,就是指一個容器了。code

       解決的思路大概就是這麼個意思:先把細軟按照單位重量(或者體積)的價值進行排序,而後先可最貴的往包裏裝,裝不下就切成小塊裝,最貴的裝完,裝第二貴的,以此類推。直到裝滿,就算是完事兒了。連個遞歸的過程都用不上。排序

看來,彷佛分數揹包比零一揹包問題還簡單一些啊。遞歸

       我知道的揹包問題,無論是分數揹包或者零一揹包,都是隻限制一個條件:重量或者是體積。其實這倆限制本質上是同樣的啦。而後我如今就有個問題:若是揹包既限制重量,又限制體積呢?那麼該怎麼算?get

        唉,本人比較懶,先把這個問題冷處理吧。冷處理,是高中時候一個同桌自創的處理問題方法,就是把眼下想不出來的問題冷凍起來。等哪天忽然靈光一現的時候,再拿出來研究。說白了就是拖延啦。it

       也歡迎各位大神能指點一二。不勝感謝。io

相關文章
相關標籤/搜索