1.贪心算法
每一步都做出当时看起来最佳的选择。也就是说,总是做出局部最优的选择,寄希望这样的选择能导致全局最优解。贪心算法并不保证得到最优解,但是对很多问题确实可以求得最优解。包括最小生成树和Dijkstra算法,以及一些启发式NP算法。
2.贪心算法问题
2.1活动选择问题:
有一个需要使用每个资源的n个活动组成的集合S= {a1,a2,···,an },资源每次只能由一个活动使用。每个活动ai都有一个开始时间si和结束时间fi,一旦被选择后,活动ai就占据半开时间区间[si,fi)。如果[si,fi]和[sj,fj]互不重叠,则称ai和aj两个活动是兼容的。该问题就是要找出一个由互相兼容的活动组成的最大子集。例如下图所示的活动集合S,其中各项活动按照结束时间单调递增排序。
#include
#include
#include
#include
using namespace std;
void greedy_Activity(int s[],int f[],int n){ //已知n个活动的起始时间和中止时间
int m=0;
int k=0;
vector<int> ivec;
ivec.push_back(m);
for(m=1;mif(s[m]>=f[k]){
ivec.push_back(m);
k=m;
}
}
for(auto c:ivec)
cout<1<<" ";
cout<return ;
}
int main(){
int s[]={1,3,0,5,3,5,6,8,8,2,12};
int f[]={4,5,6,7,9,9,10,11,12,14,16};
greedy_Activity(s,f,11);
system("pause");
return 0;
}
2.2 分数背包问题(注意:0-1背包问题不能由贪心算法解出)
#include
using namespace std;
const int N = 3;
void Knapsack(int n,float M,float v[],float w[],float x[]);
int main()
{
float M = 50;//背包所能容纳的重量
//这里给定的物品按单位价值减序排序
float w[] = {0,10,20,30};//下标从1开始
float v[] = {0,60,100,120};
float x[N+1];
cout<<"背包所能容纳的重量为:"<cout<<"待装物品的重量和价值分别为:"<for(int i=1; i<=N; i++)
{
cout<<"["<"]:("<","<")"<cout<<"选择装下的物品比例如下:"<for(int i=1; i<=N; i++)
{
cout<<"["<"]:"<return 0;
}
void Knapsack(int n,float M,float v[],float w[],float x[])
{
//Sort(n,v,w);//这里假定w[],v[]已按要求排好序
int i;
for (i=1;i<=n;i++)
{
x[i]=0;//初始化数组x[]
}
float c=M;
for (i=1;i<=n;i++)//物品整件被装下,x[i]=1
{
if (w[i]>c)
{
break;
}
x[i]=1;
c-=w[i];
}
//物品i只有部分被装下
if (i<=n)
{
x[i]=c/w[i];
}
}
2.3 最小生成树算法和最短路径问题在图论章节再介绍。