您的位置:首页 > 其它

一个简单的0-1背包问题(2)

2012-11-30 15:43 295 查看
还是上次的问题,从N个数字(N较大)从取出随意m个数字(m不定)相加,得到最接近一个常数c的组合,原来用无穷列举的方法解出来,时间复杂度上为O(2^n),对于n比较大的情况,几乎为无解,重新设计了算法,用动态规划的方法实现,时间复杂度为nc,同样能够得到最优解,但是所花费的时间大大减小,唯一不爽的是,要求数组都是int类型,c也一样,如果是double类型的话,为了精度,需要开销的空间太大,我的老爷机没法继续实现,所以没有做double数组的算法,如果大家有兴趣,可以继续写下去
void MyAlogorithms::Knapsack(int w[],int c,int n,int **f)
{

for (int y=0;y<=w[n-1];y++)
f[n-1][y]=0;
for (int y=w[n-1];y<c-1;y++)
f[n-1][y]=w[n-1];

for (int i=n-2;i>=0;i--)
{
for (int y=0;y<=w[i];y++)
f[i][y]=f[i+1][y];
for (int y=w[i];y<c-1;y++)
f[i][y]=max(f[i+1][y],f[i+1][y-w[i]]+w[i]);

}
f[0][c-1]=f[1][c-1];
if (c>=w[0])
{
f[0][c-1]=max(f[1][c-1],f[2][c-1-w[0]]+w[0]);

}
}

void MyAlogorithms::Traceback(int **f,int w[],int c,int n,int x[])
{
for (int i=0;i<n-1;i++)
{
if (f[i][c-1]==f[i+1][c-1])
{
x[i]=0;
}
else
{
x[i]=1;
c=c-w[i];
}
}
x[n-1]=(f[n-1][c-1])?1:0;
}

测试

#include <iostream>
#include <fstream>
#include "MyAlgorithms.h"

using namespace std;

const int N=99;
const int tarnum=412645;

int main()
{
int i=0;
int sum=0;
int s
;
ifstream in;
in.open("shuzi.txt");
if (!in.is_open())
{
cout<<"Can't open the file";
exit(EXIT_FAILURE);
}
in>>s[i];
while(in.good())
{
i++;
in>>s[i];
}

MyAlogorithms ma;
int **f=new int*
;
for (int k=0;k<N;k++)
{
f[k]=new int[tarnum];
}
int b
={0};
ma.Knapsack(s,tarnum,N,f);

ma.Traceback(f,s,tarnum,N,b);

for (int k=0;k<N;k++)
{
sum=sum+b[k]*s[k];
if (1==b[k])
{
cout<<s[k]<<endl;
}

}

cout<<sum<<endl;

for(int k=0;k<N;k++)
delete []f[k];
delete []f;

system("Pause");

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: