01揹包回溯+遞歸解法

    學校的算法實驗,用回溯和遞歸求解01揹包問題。覺得回溯思路不適合解01揹包問題,因爲01揹包問題中摻雜了兩個變量:揹包容量和攜帶的價值(價值比較出最大價值),但畢竟是學校實驗,還是得做啊。

    我的思路是,設一個數組,長度爲物品的數量。數組爲賦值爲0,則表示當前物品不取;賦值爲1,則取。然後對每一位遍歷,最後比較。微笑微笑微笑微笑微笑用動態做最省事。

回溯代碼:

#include <stdio.h>
#include <malloc.h>
#define M 5
int *choice,*saved;
int maxV = -1;
void KNAPSACK(int *v,int *s,int C,int n);
int main(void)
{
	int s[M] = {3,5,7,8,9},v[M] = {4,6,7,9,10},C = 11;
	int i=0,sum=0;
	KNAPSACK(v,s,C,M);
	printf("選擇");
	for(i=0;i<M;i++)
	{
		if(saved[i])
		{
			printf("第%d項,",i+1);
			sum+=s[i];
		}
	} 
	printf("物品放入揹包,");
	printf("物品總體積爲:%d,總價值爲%d.",sum,maxV);
	return 0;
}
//v數組價值,s數組體積,C揹包容量,n數量 
void KNAPSACK(int *v,int *s,int C,int n)
{
	choice = (int*)malloc(sizeof(int)*(n+1));
	saved = (int*)malloc(sizeof(int)*(n+1));
	int flag = 0;
	int i=0,j=0,k=0;
	int value=0,bag=0;
	for(i=0;i<n;i++)
		choice[i]=-1,saved[i]=-1;
	while(k>=0)
	{
		while(choice[k]<1)   //篩選每一個物品,兩種可能,取或者不取分別對應0/1 
		{
			choice[k]++;
			if(k==n)
			{
				value=0,bag=0;
				for(i=0;i<n;i++)
				{
					if(choice[i])
					{
						bag+=s[i];
						value+=v[i];
					}
				}
				if(maxV<value&&bag<=C)
				{
					maxV = value;
					for(i=0;i<n;i++) saved[i] = choice[i];
				}
				break;
			}
			else k++;
		}
		choice[k] = -1;
		k--;
	}
} 

遞歸代碼:

#include <stdio.h>
#include <malloc.h>
#define M 5
int *choice,*saved;
int maxV = -1;
void KNAPSACK(int *v,int *s,int C,int cur);
int main(void)
{
	int s[M] = {3,5,7,8,9},v[M] = {4,6,7,9,10},C = 11;
	choice = (int*)malloc(sizeof(int)*M);
	saved = (int*)malloc(sizeof(int)*M);
	int i=0,sum=0;
	KNAPSACK(v,s,C,0);
	printf("選擇");
	for(i=0;i<M;i++)
	{
		if(saved[i])
		{
			printf("第%d項,",i+1);
			sum+=s[i];
		}
	} 
	printf("物品放入揹包,");
	printf("物品總體積爲:%d,總價值爲%d.",sum,maxV);
	return 0;
}
//v數組價值,s數組體積,C揹包容量,cur當前位 
void KNAPSACK(int *v,int *s,int C,int cur)
{
	if(cur==M-1)
	{
		int value=0,bag=0,i=0;
		for(i=0;i<M;i++)
		{
			if(choice[i])
			{
				bag+=s[i];
				value+=v[i];
			}
		}
		if(maxV<value&&bag<=C)
		{
			maxV = value;
			for(i=0;i<M;i++) saved[i] = choice[i];
		}
		return;
	}
	else
	{
		choice[cur] = 0;
		KNAPSACK(v,s,C,cur+1);
		choice[cur] = 1;
		KNAPSACK(v,s,C,cur+1);
	}
} 

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