贪心算法:部分背包问题求解及证明

1. 什么是贪心算法

对于最优解问题,选取某种度量标准,将n个输入按度量标准排序,并按次序一次输入一个值。若当前输入和以前在这种度量标准下的部分解合并在一起能够构成可行解,则将其与部分解合并,否则则去掉这个输入。重复上述过程直到 枚举结束。这种通过某种度量标准获取最优解的分级处理方法成为贪心算法。

SPARKS语言描述:

procedure GREEDY(A, n)

	solution ← ∅
	
	for i ← 1 to n do
		x ← SELECT(A)
		if FEASIBLE(solution, x) then 
			solution ← UNION(solution, x)
		endif
	repeat
	
	return(solution)
	
end GREEDY

2. 贪心算法解决部分背包问题

SPARKS语言描述:

procedure GREEDY_KNAPSACK(P, W, M, X, n)
	// P(1:n)和W(1:n)分别含有按P(i)/W(i)≥P(i+1)/W(i+1)排序的n件物品的效益值和重量。
	// M是背包的容量大小,X(1:n)是解向量
	
	real P(1:n), W(1:n), X(1:n), M, cu
	integer i, n
	
	X ← 0
	cu ← M
	
	for i ← 1 to n do
		if  cu < W(i) then
			exit
		endif
		cu ← cu - W(i)
		X(i) ← 1
	repeat
	
	if i <= n then
		X(i) ← cu / W(i)
	end if
	
	return(X)
	
end GREEDY_KNAPSACK

C++实现:

#include <queue>
#include <iostream>
#include <stdio.h>

class coin {
private:
	int _weight;
	int _value;
	double _ratio;
public:
	coin(int w, int v) : _weight(w), _value(v), _ratio((double)v / w) {}
	double get_ratio() { return _ratio; }	
	double get_weight() { return _weight; }
	double get_value() { return _value; }
};

class cmp {
public:
	bool operator()(coin c1, coin c2) {
		return c1.get_ratio() < c2.get_ratio();
	}
};

void p2240() {
	int N(0), T(0), w(0), v(0);
	double s(0.0);
	std::cin >> N >> T;
	std::priority_queue<coin, std::vector<coin>, cmp> coins;
	for (int i = 0; i < N; ++i) {
		std::cin >> w >> v;
		coins.push(coin(w, v));
	}
	
	coin t = coins.top();
	coins.pop();
	while (true) {
		if (t.get_weight() <= T) {
			T -= t.get_weight();
			s += t.get_value();
			if (!coins.empty()) {
				t = coins.top();
				coins.pop();
			}
			else break;
		}
		else { 
			s += T * t.get_ratio();
			break;
		}
	}
	printf("%.2lf\n", s);
}

3. 最优解证明

一般证明方法:

  1. 设计问题最优解的一般形式
  2. 比较贪心解与最优解
    2.1 若最优解与贪心解相同,则贪心解就是最优解
    2.2 若最优解与贪心解不同
    1. 找出首次出现不同的位置i
    2. 用贪心解xi替换最优解的xi
    3. 设法保证在替换完成后仍不违反约束条件
    4. 设法证明替换完成后的新解的效益值至少不比原来的解更差
    5. 重复2.2直到替换后的最优解与贪心解相同
  3. 因为在上述代换改变前后,最优解的效益值没有任何损失,因此贪心解可以作为最优解

部分背包问题贪心算法的证明:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伯明翰谢老二

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值