您的位置:首页 > 其它

0-1背包问题——使用动态规划方法解决

2011-03-21 10:09 477 查看
思路:向后处理法

fi(x)=max{fi-1(x), fi-1(x-wi)+pi}

/*
背包问题——使用动态规划方法解决
*/
#include <stdio.h>
void DKNAP_Pack(float p[], float w[], float M, int n, int x[])
{
float P[1000],W[1000],pp,ww;
int F[100];
int i,j,k,l,h,next,u;
l = h = 1;
F[0] = 1;
P[1] = W[1] = 0;
F[1] = next = 2;

for(i=1; i<n; i++)
{
k = l;
u = l;
while(u<=h && W[u]+w[i]<M)
u++;
if(u>h)
u--;
for(j=l; j<=u; j++)
{
pp = P[l] + p[i];
ww = W[l] + w[i];
while(k<=h && W[k]<ww)
{
P[next] = P[k];
W[next] = W[k];
next++;
k++;
};
if(k<=h && W[k]==ww)
{
if(P[k] > pp)
pp = P[k];
k++;
}
if(pp > P[next-1])
{
P[next] = pp;
W[next] = ww;
next++;
}
while(k<=h && P[k]<=P[next-1])
k++;
}//for
while(k<=h)
{
P[next] = P[k];
W[next] = W[k];
next++;
k++;
}
l = h+1;
h = next-1;
F[i+1] = next;
}//for

/*有了S(n-1),求最终答案*/
i = F[n-1];
while(i<F
&& w
+W[i]<=M)
i++;
i--;
if(P[i]+p
> P[F
-1])
{
P[F
] = P[i]+p
;
W[F
] = W[i]+w
;
}else
{
P[F
] = P[F
-1];
W[F
] = W[F
-1];
}

printf("P=%f, W=%f./n", P[F
], W[F
]);
/*求x
,即w的组成成分*/
for(i=0; i<=n; i++)
printf("%d  ",F[i]);
printf("Ouput p and w:/n");
for(i=F[0]; i<=F
; i++)
printf("%f %f/n",P[i], W[i]);
printf("/n");
pp = P[F
];
ww = W[F
];
for(i=n-1; i>=0; i--)
{
j=F[i];
x[i+1] = 0;
while(j<F[i+1])
{
if(pp==P[j] && ww==W[j])
{
x[i+1] = 0;
break;
}
if(pp-p[i+1]==P[j] && ww-w[i+1]==W[j])
{

x[i+1] = 1;
pp = pp-p[i+1];
ww = ww-w[i+1];
break;
}
j++;
}//while
}//for

}
int main()
{
int i, n, x[10];
float p[10],w[10],M;
M = 6;
n = 3;
p[1] = 1;
p[2] = 2;
p[3] = 5;
w[1] = 2;
w[2] = 3;
w[3] = 4;
DKNAP_Pack(p, w, M, n, x);

for(i=1; i<=n; i++)
printf("%d ",x[i]);
getchar();
getchar();
getchar();
return 0;
}


算法空间复杂度是O(2^n),但是由于M比2^n小很多,而且根据支配规则(wi>wj时,必须有pi>pj)可以清楚一些不满足条件的序偶,故实际上,算法是可行的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐