趣学算法之贪心算法

14天阅读挑战赛
努力是为了不平庸~
算法学习有些时候是枯燥的,这一次,让我们先人一步,趣学算法!欢迎记录下你的那些努力时刻(算法学习知识点/算法题解/遇到的算法bug/等等),在分享的同时加深对于算法的理解,同时吸收他人的奇思妙想,一起见证技术er的成长~

趣学算法之贪心算法

算法知识点

贪心算法
贪心法算法框架
贪心法通过分步决策的方法求解问题,每一步决策产生n-元组解(x0,x1,…,xn-1)的一个分量。贪心法每一步上用作决策依据的选择准则被称为最优量度标准。一般背包问题可以用贪心算法求解;0-1背包问题却不能用贪心算法求解,而只能得到它的近似解。贪心算法不能保证对所有问题都得到整体最优解。
对许多问题,如:一般背包问题、最佳合并模式问题、单源最短路径问题,最小生成树问题等,贪心算法确实能产生整体最优解。
一些情况下,贪心算法不能得到整体最优解,却是最优解的很好近似。

算法题目来源

(1)背包问题;
(2)最小代价生成树;

算法题目描述

给定n种物品和一个容量为M的背包。物品i的重量是wi,其价值为pi。应如何选择装入背包的物品,使得装入背包中物品的总价值最大?

做题思路

背包问题的解可表示成一个n-元组:X=(x0,x1,…xn-1), 0≤xi≤1, 0≤i 用贪心法求解,找出最优量度标准是至关重要的.
限定1
.选取目标函数(总价值)作为量度标准,每次取价值最大的物品装包,不考虑重量.
.限定2
.选取重量作为量度标准,每次取重量最小的物体装包,不考虑收益.
.限定3
.选取单位重量价值最大的物品装包,即每次选pi/wi最大的物品装包.

模板代码

SolutionTypeGreedy(STypea[],intn)
{
SolutionTypesolution=.;//初始时,解向量不包含任何分量
for (inti=0;i {//问题的解用n元组(x0,x1,…,xn-1)表示
STypex=Select(a);//遵循最优度量标准选择一个分量x
if (Feasiable(solution,x)) //新分量x加入后,部分解须可行
solution=Union(solution,x); //形成新的部分解
}
return solution;//返回生成的最优解
}

做题过程中遇到的bug及解决方案

基本步骤:
1、首先计算每种物品单位重量的价值Pi/Wi并按非增次序进行排序;
2、然后依贪心选择策略,选择单位重量价值最高的物品装入背包。依此策略一直地进行下去,将尽可能多的物品全部装入背包,直到将背包装满。
3、若装入某件物品时,不能全部装下,而背包内的物品总重量仍未达到W,则根据背包的剩余载重,选择单位重量价值次高的物品并尽可能多地装入背包。

背包问题的贪心算法

void GreedyKnapsack(float *x)
{   //前置条件:w[i]已按p[i]/w[i]的非增次序排序
float u=m;//将背包剩余载重量u初始化为m
for (int i=0;i<n;i++) x[i]=0;//对解向量x初始化
for (i=0;i<n;i++){//按最优量度标准选择解分量xi
if (w[i]>u) break;//若当前物品i已无法全部装下,则跳出
x[i]=1.0;//否则,整个装入当前物品i
u=u-w[i];}//同时背包剩余载重减w[i]
if (i<n) x[i]=u/w[i]; //背包剩余空间只够放下当前物品i的x[i]部分
}

相关算法题型题目总结

最小代价生成树
设G =(V,E)是无向连通带权图,即一个网络。E中每条边(v,w)的权为c[v][w]。
若极小连通子图G’包括图G中的所有顶点,并有尽可能少的边,则称G’为G的生成树。
生成树上各边的权值代表相应的代价。树中各条边的代价总和是生成树的代价。
图的生成树不唯一,采用不同的遍历方法,从不同的结点出发可得到不同的生成树。在G的所有生成树中,代价最小的生成树称为G的最小生成树。
网络的最小生成树在实际中有广泛应用。例如:在设计通信网络时,用图的顶点表示城市,用边(v,w)的权c[v][w]表示建立城市v和城市w之间的通信线路所需的费用,则最小生成树就给出了建立通信网络的最经济的方案。一般情况下,用贪心法得到的是近似最优解,而不能保证得到最优解。但用贪心法计算最小生成树,却可以设计出保证得到最优解的构造最小生成树的有效算法。本节介绍的构造最小生成树的Prim算法和Kruskal算法都可以看作是应用贪心算法设计策略的例子。尽管这2个算法做贪心选择的方式不同,它们都利用了下面的最小生成树性质:
贪心法求带权无向图的最小代价生成树的算法

ESetType SpanningTree(ESetType E,int n)
{//G=(V,E)为无向图,E是图G的边集,n是图中结点数
ESetType S=.//S为生成树上边的集合
int u,v,k=0;
EType e;//e为一条边
while (k<n-1&& E中尚有未检查的边){
e=select(E);//按最优度量标准选择一条边
if (S∪e 不包含回路){//判断可行性
S=S∪e;//在生成树边集S中添加一条边
k++;} //k为生成树边集S中边的条数
}
return S;
}

读书笔记

一个问题的最优解包含其子问题的最优解,则称此问题具有最优子结构性质。
问题的最优子结构性质是该问题可用动态规划算法或贪心算法求解的关键特征。
所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。
这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别。

你可能感兴趣的:(算法,算法)