回溯法解決01揹包問題

#include<stdio.h>


int x[1000]; //數組用來存放每個物品的狀態是0 還是1 


int val[1000] = {-1};//存放每個物品的價值


int weight[1000] = {-1};//存放每個物品的重量


int IsOverLoad(int n, int c)//判斷物品是否超重

{

int i, w = 0;


for(i=0; i<n; i++)

{

w = w + x[i] * weight[i];

}


if(w > c)

return 1;//超重


else

return 0;

}



int GetVal(int n)//返回所有物品的價值和

{

int i, v = 0;


for(i=0; i<n; i++)

{

v = v + x[i] * val[i];

}


return v;

}



void Knap_1(int n, int flag, int c, int *price)//找到物品的裝包的最高的價值量

{

int i, p;


if(IsOverLoad(n, c) == 1)//超過揹包的裝載上限c,剪枝

return;


if(n == flag)//搜索完一條可能的解的路徑

{

p = GetVal(n);//獲得這種裝包的方案的總價值量


if(*price < p)

{

*price = p;//price 爲各種方案中的最高的價值量

}

return;//回溯

}


for(i=1; i>=0; i--)

{

x[n] = i;//生成可能的解路徑


Knap_1(n+1, flag, c, price);//遞歸調用

}

}



void Knap_2(int n, int flag, int c, int price)

{

int i, j, p;


if(IsOverLoad(n, c) == 1)

return;


if(n == flag)

{

p = GetVal(n);


if(price == p)

{

printf("--------------------bag-------------------\n");

for(j=0; j<n; j++)

{

if(x[j] == 1)

{

printf("| |p%d: | |\n", j);

printf("| |weight:%2d kg | |\n", weight[j]);

printf("| |price: %2d $ | |\n\n", val[j]);

}

}

printf("------------------------------------------\n\n");

return;//回溯法繼續搜索

}

return;//回溯法繼續搜索

}


for(i=1; i>=0; i--)

{

x[n] = i;


Knap_2(n+1, flag, c, price);

}

}


void main()

{

int price = 0, n, c, i;


printf("Input the limit of the bag can overload:\n");

scanf("%d", &c);

printf("Input the number of products:\n");

scanf("%d", &n);



printf("Input the weight of each produce:\n");

for(i=0; i<n; i++)

{ scanf("%d  %d", &weight[i],&val[i]);

// scanf("", );

}

/*

printf("Input the price of each produce:\n");

for(i=0; i<n; i++)

scanf("%d", &val[i]);

*/


Knap_1(0, n, c, &price);


Knap_2(0, n, c, price);


printf("The grass price :%d $\n", price);


getch();

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章