物品 |
A |
B |
C |
D |
F |
重量 |
1 |
2 |
3 |
4 |
5 |
价值 |
3 |
10 |
6 |
3 |
5 |
程序代码:
- //GreedyAlgorithm.h
- #include<iostream>
- using namespace std;
- class GreedyAlgorithm{
- public:
- GreedyAlgorithm(int _weight[],int _value[],int capacity);
- double *ComputeRatio();
- void SortRatio(double _Ratio[]);
- double ComputeProfit();
- private:
- int *weight;
- int *value;
- int capacity;
- double profit;
- };
- //GreedyAlgorithm.cpp
- #include"GreedyAlgorithm.h"
- //================================
- //函数名称:GreedyAlgorithm
- //函数功能:初始化对象
- //函数参数说明:_weight[] 物品重量,_value[] 物品价值,_capacity 背包容量
- //函数返回值:void
- //创建时间:2009-04-28
- //更新:
- //================================
- GreedyAlgorithm::GreedyAlgorithm(int _weight[],int _value[],int _capacity){
- this->weight=_weight;
- this->value=_value;
- this->capacity=_capacity;
- this->profit=0;
- return;
- }
- //================================
- //函数名称:ComputeRatio
- //函数功能:计算出物品的单位价值
- //函数参数说明:
- //函数返回值:double *
- //创建时间:2009-04-28
- //更新:
- //================================
- double *GreedyAlgorithm::ComputeRatio(){
- double *Ratio=new double[5];
- for(int i=0;i<5;i++)
- Ratio[i]=(double)value[i]/weight[i];
- return Ratio;
- }
- //================================
- //函数名称:SortRatio
- //函数功能:根据单位价值比大小,对物品的价值和重量进行排序
- //函数参数说明:
- //函数返回值:void
- //创建时间:2009-04-28
- //更新:
- //================================
- void GreedyAlgorithm::SortRatio(double _Ratio[]){
- for(int i=0;i<5;i++)
- for(int j=i+1;j<5;j++)
- {
- if(_Ratio[j]>_Ratio[i]){
- int temp=weight[i];
- weight[i]=weight[j];
- weight[j]=temp;
- temp=value[i];
- value[i]=value[j];
- value[j]=temp;
- }
- }
- return;
- }
- //================================
- //函数名称:ComputeProfit
- //函数功能:计算背包的内所放物品的最大价值
- //函数参数说明:
- //函数返回值:double
- //创建时间:2009-04-28
- //更新:
- //================================
- double GreedyAlgorithm::ComputeProfit()
- {
- int temp=0;
- int i=0;
- while(temp<=capacity){
- if(i==5) break;
- else{
- if((weight[i]+temp)<=capacity){
- profit+=value[i];
- temp+=weight[i];
- }
- else if((weight[i]+temp)>capacity){
- int _weight=capacity-temp;
- double _Ratio=(double)value[i]/weight[i];
- profit+=_Ratio*_weight;
- temp+=_weight;
- }
- }
- i++;
- }
- return profit;
- }
- //main.cpp
- #include<iostream>
- #include"GreedyAlgorithm.h"
- using namespace std;
- int main(){
- int _weight[5]={1,2,3,4,5};
- int _value[5]={3,10,6,3,5};
- int _capacity=7;
- GreedyAlgorithm *greedy=new GreedyAlgorithm(_weight,_value,_capacity);
- greedy->SortRatio(greedy->ComputeRatio());
- cout<<"The Maximum Profit is: "<<greedy->ComputeProfit()<<endl;
- return 0;
- }
一、动态规划算法介绍
动态规划算法(Dynamic Programming Algorithm, DPA)与分治法类似,其基本思想是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划法求解的问题,经分解得到的子问题往往不是互相独立的,若用分治法解这类问题,则分解得到的子问题数目太多,以至于最后解决原问题需要耗费过多的时间。在用分治法求解时,有些子问题被重复计算了许多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算。为了达到此目的,可以用一个表来记录所有已解决的子问题的答案。这就是动态规划法的基本思想。
动态规划算法使用于解最优化问题。通常可按以下4个步骤设计:
1、找出最优解的性质,并刻画其结构特征;
2、递归地定义最优值;
3、以自底向上的方式计算出最优值;
4、根据计算最优值时得到的信息,构造最优解。
步骤1~3是动态规划算法的基本步骤。在只需要求出最优值的情形,步骤4可以省去。若需要求出问题的最优解,则必须执行步骤4。此时,在步骤3中计算最优值时,通常需记录更多的信息,以便在步骤4中,根据所记录的信息,快速构造出一个最优解。
二、0-1背包问题
【问题描述】:给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包容量为c。问应如何选择装入背包中的物品,使得装入背包中物品的总价值最大。在选择装入背包的物品时,对每种物品i只有两种选择,即装入背包或不装入背包。不能将物品i装入背包多次,也不能只装入部分的物品i。因此,该问题称为0-1背包问题。
【算法分析】:0-1背包问题的最优子结构,设(y1,y2,...,yn)是所给0-1背包问题的一个最优解,则(y2,y3,...,yn)是经过一次选择后的0-1背包问题的最优解。0-1背包问题的递归关系,设当前子问题的最优值为m(i,j),即m(i,j)使背包容量为j,可选择物品为i,i+1,...,n时0-1背包问题的最优值。由0-1背包问题的最优子结构性质,可以建立计算m(i,j)的递归式:
当i=n时,若j>=wn,则m(i,j)=vn;若0<=j<wn,则m(i,j)=0。
当i<n时,若j>=wi,则m(i,j)=max{m(i+1,j),m(i+1,j-wi)+vi};若0<=j<wi,则m(i,j)=m(i+1,j)。
留言列表