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

本文介绍了一种针对大量double类型数据寻找最接近指定目标值的数字组合的算法。该算法采用回溯法进行搜索,时间复杂度为O(2^n)。通过排序和递归比较,确保了找到最优解的可能性,尤其是在数据规模较小时。

在网上看到的一个题目,从N个数字(N较大)从取出随意m个数字(m不定)相加,得到最接近一个常数c的组合,网上有不少类似算法,但多为int类型数据,这个为double型,而且N都较小,或者要求相等,最优解的例子较少,所以写了一个,时间复杂度为O(2^n),所以在数字较大的时候,结果没法验证,在数字较小的情况,结果完全正确而且必定是最优解

 

/**********************************************************************************/

#include <iostream>
#include <fstream>

using namespace std;
void QuickSort(double e[], int first, int end); 
void Compare(double e[],int s,int n); 
const int N=99;
const double mubiao=412645.6; 
double temp[N]={0}; 
double tar[N]={0}; 
double tempnum=0;
double tarnum=412645.6;

int main()
{
	int i=0;
	int x=0;
	int y=0;
	double sum1=0;
	double sum2=0;
	double s[N];
	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];
	}
	QuickSort(s,0,N-1);
	while (sum1<mubiao)
	{
		sum1=sum1+s[x];
		x++;
	}
	while(sum2<mubiao)
	{
		sum2=sum2+s[N-1-y];
		y++;
	}

	for (int k=y;k<x;k++)
	{
		Compare(s,k,N);
	}

	cout<<"The best group is:"<<endl;

	for (int j=0;j<N;j++)
	{
		cout<<tar[j]<<endl;
	}
	system("Pause");
}

void QuickSort(double e[], int first, int end)
{
	int i=first,j=end;
	double temp=e[first];
	while(i<j)
	{
		while(i<j && e[j]>=temp)
			j--;
		e[i]=e[j];
		while(i<j && e[i]<=temp)
			i++;		
		e[j]=e[i];
	}
	e[i]=temp;
	if(first<i-1)
		QuickSort(e,first,i-1);
	if(end>i+1)		
		QuickSort(e,i+1,end);

}

void Compare(double e[],int s,int n)
{
	for(int i=n;i>=s;i--)
	{
		temp[s]=e[i];
		if (s>1)
		{
			Compare(e,s-1,n-1);
		} 
		else
		{
			for (int j=0;j<N;j++)
			{
				tempnum=tempnum+temp[j];
			}
			if (abs(mubiao-tempnum)<tarnum)
			{
				tarnum=abs(mubiao-tempnum);
				tempnum=0;
				for (int j=0;j<N;j++)
				{
					tar[j]=temp[j];
				}
			} 
			else
			{
				tempnum=0;
			}
		}
	}
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值