贪心算法求解问题(优化版)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
贪心算法求解问题
问题分析:
此问题为程序最优存储问题,问题要求最后存储的两个磁带上的长度差异就最小。若在最优解中去掉i个程序段,显然在(n-i)个程序段的存储中应仍是最优解,因为此问题存在最优子结构。
另外,由于每个程序的长度不同,每将一个程序存储到A或者B(用A和B来表示两个磁带上存储程序的集合)后,显然还与后续怎么存储程序有关,即当前结果依赖子问题的结果。这正是动态规划算法的基本特征,而贪心算法仅在当前状态下做出最好选择,然后再去做子问题的局部最优解最终就是问题的最优解,贪心算法不依赖于将来所做的子问题的解,显示,此问题是一个动态规划问题,是一个0-1背包问题。
虽然对有些问题,贪心算法并不能得到一个最优解,但往往能快速地得到一个近似最优解。下面就来讨论如何用贪心算法得到近似最优解。
贪心算法思路
为了使最后两个磁带的长度差异越小,就先将长度较大的程序优先放入到磁带(此处用A和B分别表示两个磁带)上。因此排序选择递减排序。
用p[ ]数组来存放第i个程序长度为p[i-1],首先将其按程序长度大小递减的顺序排序,将排好序的各程序下标记录到与与p[]等长的数组a[ ]中。
然后再根据a[]中记录的下标找到相应的程序p[a[i]]放到A或者B 中。
现在就接下就是如何存放来达到近似最优解的问题了
开始A和B中没有任何元素(本程序中采用vector动态定义A,B),如果用sumA和sumB来标记A和B中已存入程序的总长度,在存入当前最优解时,先比较sumA和sumB 的大小,将最优解存入到程序总长度较短的那个程序集合,如果长度一样,则存入到A或者B中(本程序是存入到A集合中),可以看到这样存入的话,就会尽量减小A和B长度的差异,从而尽量接近最优存储得到近似最优解
之前提交的贪心算法的思想是直接交叉存入到A和B中,那样得到的
解在一定程度能得利近似最优解,那种思想只对程序段长度相差小的情
况有比较好的结果,因为那种思想大概是将程序段平均到A和B中,在很多情况下不能得到近似最优解。这些优化最重要是核心思想上的优化,这次程序设计中,在放入A或者B前先比较A和B的长度,这样才更有针对性的存放,得到的效果比之前的好了很多,另外在,程序实现代码上也有了很大的优化,代码优化见“代码优化说明”
程序源代码(Microsoft Visual Studio 2010)
// 贪心算法求解问题.cpp : 定义控制台应用程序的入口点。
//
#include"stdafx.h"
#include
#include
usingnamespace std;
//将各程序按长度的递减顺序排序,用a[ ]来记录排好序程序的下标
void Rank(vector
{
int t;
for(int j =0;j for(int i=0;i if(p[i] { t=p[i];p[i]=p[i+1];p[i+1]=t; t=a[i];a[i]=a[i+1];a[i+1]=t; } } //采用贪心算法将程序长度最大的放入到A和B中 void GreedySelector(vector { int sumA=0; //定义A中程序的总长度 int sumB=0; //定义B中程序的总长度 int m=0,j=0; //用m标志A数组的长度,n标志B数组的长度 //将当前的最优解(最大长度)存入到A、B中总长度较短一个集合 for(int i=0;i { if(sumB>=sumA) { A.resize(++m); //当有数据存入时,动态将A数组长度加1 A[m-1]=a[i]; sumA+=p[A[m-1]]; //计算A中程度总长度 } else { B.resize(++j); B[j-1]=a[i]; sumB+=p[B[j-1]]; } } } int _tmain(int argc, _TCHAR* argv[]) { int n; cout<<"请输入程序的数目:"; cin>>n; vector vector for(int i=0;i { cout<<"请输入第"< cin>>p[i]; } a[0]=0; for(int i=1;i a[i]=a[i-1]+1; Rank(p,a,n); //调用排序函数 GreedySelector(p,A,B,a,n); //调用贪心算法将程序放入到A和B中 int sum1=0,sum2=0; for(int i=0;i sum1+=p[A[i]]; for(int i=0;i sum2+=p[B[i]]; cout< cout<<"-------------------贪心算法结果-------------------"< cout<<"用贪心算法近似最优值为: "<