用贪心准则解决背包问题

//用贪心准则解决背包问题
#include<iostream>
#include<iomanip>
#define length 100
using namespace std;
//以重量为贪心准则
void WeightCriterion(int n, int c, int* wc, double* vc)
{
	int i, j, weight;
	double w[length], v[length], value;
	for (i = 1; i <= n; i++) {
		w[i] = wc[i];
		v[i] = vc[i];
	}
	for (int j = 1; j < n; j++)
		for (i = 1; i <= n - j; i++) {
			if (w[i] >= w[i + 1]) {//按重量由小到大排序
				weight = w[i];
				w[i] = w[i + 1];
				w[i + 1] = weight;
				value = v[i];
				v[i] = v[i + 1];
				v[i + 1] = value;
			}
		}
	cout << "***************重量贪心准则******************" << endl;
	cout << setw(10) << "序号" << setw(10) << "重量" << setw(10) << "价值" << endl;
	for (i = 1; i <= n; i++)
		cout << setw(8) << i << setw(10) << w[i] << setw(10) << v[i] << endl;
	cout << "根据排列序号得到解为:(";
	int wei = 0, s[length],index;
	double val = 0.00;
	for (i = 1; i <= n; i++) {
		wei += w[i];
		if (wei <= c) {//是否超出背包容量
			val += v[i];
			cout << 1 << ",";
		}
		else {
			double d = (double)(c - w[i - 1]) / w[i];
			val += d* v[i];
			index = i;
			cout << setprecision(2) << d << ",";
			break;
		}
	}
	for (i = index+1; i <= n; i++) {
		cout << 0 << ",";
	}
	cout << ")" << setw(10) << "获得价值为:" << setprecision(4) << val << endl;
	cout << endl;
}
//以价值为贪心准则
void ValueCriterion(int n, int c, int* wc, double* vc)
{
	int i, j, weight;
	double w[length], v[length], value;
	for (i = 1; i <= n; i++) {
		w[i] = wc[i];
		v[i] = vc[i];
	}
	for (int j = 1; j < n; j++)
		for (i = 1; i <= n - j; i++) {
			if (w[i] <= w[i + 1]) {//按价值又大到小排序
				weight = w[i];
				w[i] = w[i + 1];
				w[i + 1] = weight;
				value = v[i];
				v[i] = v[i + 1];
				v[i + 1] = value;
			}
		}
	cout << "***************价值贪心准则******************" << endl;
	cout << setw(10) << "序号" << setw(10) << "重量" << setw(10) << "价值" << endl;
	for (i = 1; i <= n; i++)
		cout << setw(8) << i << setw(10) << w[i] << setw(10) << v[i] << endl;
	cout << "根据排列序号得到解为:(";
	int wei = 0, s[length],index;
	double val = 0.00;
	for (i = 1; i <= n; i++) {
		wei += w[i];
		if (wei <= c) {//是否超出背包容量
			val += v[i];
			cout << 1 << ",";
		}
		else {
			double d = (double)(c - w[i - 1]) / w[i];
			val += d * v[i];
			index = i;
			cout << setprecision(2) << d << ",";
			for (i = index + 1; i <= n; i++) {
				cout << 0 << ",";
			}
			cout << ")" << setw(10) << "获得价值为:" << setprecision(4) << val << endl;
			cout << endl;
			break;
		}
	}
}
//以价值密度为贪心准则
void ValueDensityCriterion(int n, int c, int* wc, double * vc)
{
	int i, j, weight, value;
	double w[length], v[length];
	for (i = 1; i <= n; i++) {
		w[i] = wc[i];
		v[i] = vc[i];
	}
	for (int j = 1; j < n; j++)
		for (i = 1; i <= n - j; i++) {
			if ((v[i]/w[i]) <= (v[i+1]/w[i+1])) {//按价值又大到小排序
				weight = w[i];
				w[i] = w[i + 1];
				w[i + 1] = weight;
				value = v[i];
				v[i] = v[i + 1];
				v[i + 1] = value;
			}
		}
	cout << "*************价值密度贪心准则****************" << endl;
	cout << setw(10) << "序号" << setw(10) << "重量" << setw(10) << "价值" << endl;
	for (i = 1; i <= n; i++)
		cout << setw(8) << i << setw(10) << w[i] << setw(10) << v[i] << endl;
	cout << "根据排列序号得到解为:(";
	int wei = 0, s[length],index;
	double val = 0.00;
	for (i = 1; i <= n; i++) {
		wei += w[i];
		if (wei <= c) {//是否超出背包容量
			val += v[i];
			cout << 1 << ",";
		}
		else {
			double d = (double)(c-w[i-1]) / w[i];
			val = val + d * v[i];
			index = i;
			cout << setprecision(2) << d << ",";
			break;
		}
	}
	for (i = index + 1; i <= n; i++) {
		cout << 0 << ",";
	}
	cout << ")" << setw(10) << "获得价值为:" << setprecision(4) << val << endl;
	cout << endl;
}
int main()
{
	int n, c, w[length];
	double v[length];
	cout << "请输入背包容量:";
	cin >> c;
	cout << "请输入物品个数:";
	cin >> n;
	cout << "请分别输入这" << n << "个商品的重量和价值" << endl;
	for (int i = 1; i <= n; i++) {
		cout << "w[" << i << "]=";
		cin >> w[i];
		cout << "v[" << i << "]=";
		cin >> v[i];
		cout << endl;
	}
	WeightCriterion(n, c, w, v);
	ValueCriterion(n, c, w, v);
	ValueDensityCriterion(n, c, w, v);
	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值