当前位置:首页 » 操作系统 » 贪婪算法由来

贪婪算法由来

发布时间: 2022-04-19 15:49:29

Ⅰ 程序设计一课中提到的贪婪法基本思想是什么啊

贪婪法是一种不追求最优解,只希望得到较为满意解的方法。贪婪法一般可以快速得到满意的解,因为它省去了为找最优解要穷尽所有可能而必须耗费的大量时间。贪婪法常以当前情况为基础作最优选择,而不考虑各种可能的整体情况,所以贪婪法不要回溯。
贪婪算法的一般方法
1、问题描述
它有n个输入,而它的解就由这n个输入的某个子集组成,只是这个子集必须满足某些事先给定的条件。
2、约束条件 那些必须满足的条件称为约束条件。
3、可行解 满足约束条件的子集称为该问题的可行解。
4、目标函数 事先给定的衡量可行解优劣的量度标准,通常以函数的形式给出,称为目标函数。
5、最优解 使目标函数取极值(极大或极小)的可行解,称为最优解。
6、子结构模式 贪心技术中,问题的最优一般是原输入的子集,获取最优子集的贪心方法为子结构模式
7、有序模式 通过计算已有的判定而得出的最优条件,可以为下一步的判定提供依据,这种形式的贪心算法称为有序模式。
8、贪婪算法求解思想(分步处理)
�8�4 根据题意,选取一种量度标准;
�8�4 然后按这种量度标准对这n个输入排序,并按序一次输入一个量。
�8�4 如果这个输入和当前已构成在这种量度意义下的部分最优解加在一起不能产生一个可行解,则不把此输入加到这部分解中。
这种能够得到某种意义下的最优解的分级处理方法称为贪心算法。

Ⅱ 什么是贪婪算法

是贪心算法吧……
就是每次都取最优值。。。比如合并果子:
有n堆果子,每个果子都有一个重量,每次可以任意选择2堆果子将其合并成一堆,花费是这两堆果子的重量值之和,求最终合并成一堆的最小(最大)花费。
算法就是,每次取重量最小(最大)的两堆果子合并,直到还剩一堆。

Ⅲ 贪心算法的特性

贪婪算法可解决的问题通常大部分都有如下的特性:
⑴随着算法的进行,将积累起其它两个集合:一个包含已经被考虑过并被选出的候选对象,另一个包含已经被考虑过但被丢弃的候选对象。
⑵有一个函数来检查一个候选对象的集合是否提供了问题的解答。该函数不考虑此时的解决方法是否最优。
⑶还有一个函数检查是否一个候选对象的集合是可行的,也即是否可能往该集合上添加更多的候选对象以获得一个解。和上一个函数一样,此时不考虑解决方法的最优性。
⑷选择函数可以指出哪一个剩余的候选对象最有希望构成问题的解。
⑸最后,目标函数给出解的值。
⑹为了解决问题,需要寻找一个构成解的候选对象集合,它可以优化目标函数,贪婪算法一步一步的进行。起初,算法选出的候选对象的集合为空。接下来的每一步中,根据选择函数,算法从剩余候选对象中选出最有希望构成解的对象。如果集合中加上该对象后不可行,那么该对象就被丢弃并不再考虑;否则就加到集合里。每一次都扩充集合,并检查该集合是否构成解。如果贪婪算法正确工作,那么找到的第一个解通常是最优的。

Ⅳ 请问数钱的贪婪算法怎样确保得到最优解

贪婪算法:总是作出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,它所做出的仅是在某种意义上的局部最优解。
(注:贪婪算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题它能产生整体最优解。但其解必然是最优解的很好近似解。

基本思路:——从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。当达到某算法中的某一步不能再继续前进时,算法停止

实现该算法的过程:
从问题的某一初始解出发;
while 能朝给定总目标前进一步 do
求出可行解的一个解元素;
由所有解元素组合成问题的一个可行解;

基本要素:
1、 贪婪选择性质:所求问题的整体最优解可以通过一系列局部最优的选择,即贪婪选择来达到。(与动态规划的主要区别)
采用自顶向下,以迭代的方式作出相继的贪婪选择,每作一次贪婪选择就将所求问题简化为一个规模更小的子问题。
对于一个具体问题,要确定它是否具有贪婪选择的性质,我们必须证明每一步所作的贪婪选择最终导致问题的最优解。通常可以首先证明问题的一个整体最优解,是从贪婪选择开始的,而且作了贪婪选择后,原问题简化为一个规模更小的类似子问题。然后,用数学归纳法证明,通过每一步作贪婪选择,最终可得到问题的一个整体最优解。
2、最优子结构性质:包含子问题的最优解
1、 设有n个活动的安排,其中每个活动都要求使用同一资源,如演讲会场,而在同一时间只允许一个活动使用这一资源。每个活动都有使用的起始时间和结束时间。问:如何安排可以使这间会场的使用率最高。
活动 起始时间 结束时间
1 1 4
2 3 5
3 0 6
4 5 7
5 3 8
6 5 9
7 6 10
8 8 11
9 8 12
10 2 13
11 12 14

算法:一开始选择活动1,然后依次检查活动一i是否与当前已选择的所有活动相容,若相容则活动加入到已选择的活动集合中,否则不选择活动i,而继续检查下一活动的相容性。即:活动i的开始时间不早于最近加入的活动j的结束时间。
Prodere plan;
Begin
n:=length[e];
a {1};
j:=1;
for i:=2 to n do
if s[i]>=f[j] then
begin a a∪{i};
j:=i;
end
end;

例1 [找零钱] 一个小孩买了价值少于1美元的糖,并将1美元的钱交给售货员。售货员希望用数目最少的硬币找给小孩。假设提供了数目不限的面值为2 5美分、1 0美分、5美分、及1美分的硬币。售货员分步骤组成要找的零钱数,每次加入一个硬币。选择硬币时所采用的贪婪准则如下:每一次选择应使零钱数尽量增大。为保证解法的可行性(即:所给的零钱等于要找的零钱数),所选择的硬币不应使零钱总数超过最终所需的数目。

假设需要找给小孩6 7美分,首先入选的是两枚2 5美分的硬币,第三枚入选的不能是2 5美分的硬币,否则硬币的选择将不可行(零钱总数超过6 7美分),第三枚应选择1 0美分的硬币,然后是5美分的,最后加入两个1美分的硬币。

贪婪算法有种直觉的倾向,在找零钱时,直觉告诉我们应使找出的硬币数目最少(至少是接近最少的数目)。可以证明采用上述贪婪算法找零钱时所用的硬币数目的确最少(见练习1)。

Ⅳ 贪心算法的介绍

贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。

Ⅵ 如何理解Greedy layer-wise算法的工作原理

贪婪算法中采用逐步构造最优解的方法。在每个阶段,都作出一个看上去最优的决策(在一定的标准下)。决策一旦作出,就不可再更改。作出贪婪决策的依据称为贪婪准则(greedy criterion),也就是从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。当达到某算法中的某一步不能再继续前进时,算法停止。

Ⅶ 什么是分治算法贪婪算法

贪婪算法

虽然设计一个好的求解算法更像是一门艺术,而不像是技术,但仍然存在一些行之有效的能够用于解决许多问题的算法设计方法,你可以使用这些方法来设计算法,并观察这些算法是如何工作的。一般情况下,为了获得较好的性能,必须对算法进行细致的调整。但是在某些情况下,算法经过调整之后性能仍无法达到要求,这时就必须寻求另外的方法来求解该问题。

分治算法

就是把大问题分解成一些小问题,然后重小问题构造出大问题的解。

Ⅷ 贪婪算法背包

1)登上算法
用登山算法求解背包问题 function []=DengShan(n,G,P,W) %n是背包的个数,G是背包的总容量,P是价值向量,W是物体的重量向量 %n=3;G=20;P=[25,24,15];W2=[18,15,10];%输入量 W2=W; [Y,I]=sort(-P./W2);W1=[];X=[];X1=[]; for i=1:length(I) W1(i)=W2(I(i)); end W=W1; for i=1:n X(i)=0; RES=G;%背包的剩余容量 j=1; while W(j)<=RES X(j)=1; RES=RES-W(j); j=j+1; end X(j)=RES/W(j); end for i=1:length(I) X1(I(i))=X(i); end X=X1; disp('装包的方法是');disp(X);disp(X.*W2);disp('总的价值是:');disp(P*X');

时间复杂度是非指数的

2)递归法
先看完全背包问题
一个旅行者有一个最多能用m公斤的背包,现在有n种物品,每件的重量分别是W1,W2,...,Wn,
每件的价值分别为C1,C2,...,Cn.若的每种物品的件数足够多.
求旅行者能获得的最大总价值。
本问题的数学模型如下:
设 f(x)表示重量不超过x公斤的最大价值,
则 f(x)=max 当x>=w[i] 1<=i<=n
可使用递归法解决问题程序如下:
program knapsack04;
const maxm=200;maxn=30;
type ar=array[0..maxn] of integer;
var m,n,j,i,t:integer;
c,w:ar;
function f(x:integer):integer;
var i,t,m:integer;
begin
if x=0 then f:=0 else
begin
t:=-1;
for i:=1 to n do
begin
if x>=w[i] then m:=f(x-i)+c[i];
if m>t then t:=m;
end;
f:=t;
end;
end;
begin
readln(m,n);
for i:= 1 to n do
readln(w[i],c[i]);
writeln(f(m));
end.
说明:当m不大时,编程很简单,但当m较大时,容易超时.
4.2 改进的递归法
改进的的递归法的思想还是以空间换时间,这只要将递归函数计算过程中的各个子函数的值保存起来,开辟一个
一维数组即可
程序如下:
program knapsack04;
const maxm=2000;maxn=30;
type ar=array[0..maxn] of integer;
var m,n,j,i,t:integer;
c,w:ar;
p:array[0..maxm] of integer;
function f(x:integer):integer;
var i,t,m:integer;
begin
if p[x]<>-1 then f:=p[x]
else
begin
if x=0 then p[x]:=0 else
begin
t:=-1;
for i:=1 to n do
begin
if x>=w[i] then m:=f(i-w[i])+c[i];
if m>t then t:=m;
end;
p[x]:=t;
end;
f:=p[x];
end;
end;
begin
readln(m,n);
for i:= 1 to n do
readln(w[i],c[i]);
fillchar(p,sizeof(p),-1);
writeln(f(m));
end.
3)贪婪算法
改进的背包问题:给定一个超递增序列和一个背包的容量,然后在超递增序列中选(只能选一次)或不选每一个数值,使得选中的数值的和正好等于背包的容量。

代码思路:从最大的元素开始遍历超递增序列中的每个元素,若背包还有大于或等于当前元素值的空间,则放入,然后继续判断下一个元素;若背包剩余空间小于当前元素值,则判断下一个元素
简单模拟如下:

#define K 10
#define N 10

#i nclude <stdlib.h>
#i nclude <conio.h>

void create(long array[],int n,int k)
{/*产生超递增序列*/
int i,j;
array[0]=1;
for(i=1;i<n;i++)
{
long t=0;
for(j=0;j<i;j++)
t=t+array[j];
array[i]=t+random(k)+1;
}
}
void output(long array[],int n)
{/*输出当前的超递增序列*/
int i;
for(i=0;i<n;i++)
{
if(i%5==0)
printf("\n");
printf("%14ld",array[i]);
}
}

void beibao(long array[],int cankao[],long value,int count)
{/*背包问题求解*/
int i;
long r=value;
for(i=count-1;i>=0;i--)/*遍历超递增序列中的每个元素*/
{
if(r>=array[i])/*如果当前元素还可以放入背包,即背包剩余空间还大于当前元素*/
{
r=r-array[i];
cankao[i]=1;
}
else/*背包剩余空间小于当前元素值*/
cankao[i]=0;
}
}

void main()
{
long array[N];
int cankao[N]=;
int i;
long value,value1=0;
clrscr();
create(array,N,K);
output(array,N);
printf("\nInput the value of beibao:\n");
scanf("%ld",&value);
beibao(array,cankao,value,N);
for(i=0;i<N;i++)/*所有已经选中的元素之和*/
if(cankao[i]==1)
value1+=array[i];
if(value==value1)
{
printf("\nWe have got a solution,that is:\n");
for(i=0;i<N;i++)
if(cankao[i]==1)
{
if(i%5==0)
printf("\n");
printf("%13ld",array[i]);
}
}
else
printf("\nSorry.We have not got a solution.\n");
}
贪婪算法的另一种写法,beibao函数是以前的代码,用来比较两种算法:

#define K 10
#define N 10

#i nclude <stdlib.h>
#i nclude <conio.h>

void create(long array[],int n,int k)
{
int i,j;
array[0]=1;
for(i=1;i<n;i++)
{
long t=0;
for(j=0;j<i;j++)
t=t+array[j];
array[i]=t+random(k)+1;
}
}
void output(long array[],int n)
{
int i;
for(i=0;i<n;i++)
{
if(i%5==0)
printf("\n");
printf("%14ld",array[i]);
}
}

void beibao(long array[],int cankao[],long value,int count)
{
int i;
long r=value;
for(i=count-1;i>=0;i--)
{
if(r>=array[i])
{
r=r-array[i];
cankao[i]=1;
}
else
cankao[i]=0;
}
}

int beibao1(long array[],int cankao[],long value,int n)
{/*贪婪算法*/
int i;
long value1=0;
for(i=n-1;i>=0;i--)/*先放大的物体,再考虑小的物体*/
if((value1+array[i])<=value)/*如果当前物体可以放入*/
{
cankao[i]=1;/*1表示放入*/
value1+=array[i];/*背包剩余容量减少*/
}
else
cankao[i]=0;
if(value1==value)
return 1;
return 0;
}

void main()
{
long array[N];
int cankao[N]=;
int cankao1[N]=;
int i;
long value,value1=0;
clrscr();
create(array,N,K);
output(array,N);
printf("\nInput the value of beibao:\n");
scanf("%ld",&value);
beibao(array,cankao,value,N);
for(i=0;i<N;i++)
if(cankao[i]==1)
value1+=array[i];
if(value==value1)
{
printf("\nWe have got a solution,that is:\n");
for(i=0;i<N;i++)
if(cankao[i]==1)
{
if(i%5==0)
printf("\n");
printf("%13ld",array[i]);
}
}
else
printf("\nSorry.We have not got a solution.\n");
printf("\nSecond method:\n");
if(beibao1(array,cankao1,value,N)==1)
{
for(i=0;i<N;i++)
if(cankao1[i]==1)
{
if(i%5==0)
printf("\n");
printf("%13ld",array[i]);
}
}
else
printf("\nSorry.We have not got a solution.\n");
}

4)动态规划算法

解决0/1背包问题的方法有多种,最常用的有贪婪法和动态规划法。其中贪婪法无法得到问题的最优解,而动态规划法都可以得到最优解,下面是用动态规划法来解决0/1背包问题。

动态规划算法与分治法类似,其基本思想是将待求解问题分解成若干个子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划法求解的问题,经分解得到的子问题往往不是互相独立的,若用分治法解这类问题,则分解得到的子问题数目太多,以至于最后解决原问题需要耗费过多的时间。动态规划法又和贪婪算法有些一样,在动态规划中,可将一个问题的解决方案视为一系列决策的结果。不同的是,在贪婪算法中,每采用一次贪婪准则便做出一个不可撤回的决策,而在动态规划中,还要考察每个最优决策序列中是否包含一个最优子序列。

0/1背包问题

在0 / 1背包问题中,需对容量为c 的背包进行装载。从n 个物品中选取装入背包的物品,每件物品i 的重量为wi ,价值为pi 。对于可行的背包装载,背包中物品的总重量不能超过背包的容量,最佳装载是指所装入的物品价值最高,即p1*x1+p2*x1+...+pi*xi(其1<=i<=n,x取0或1,取1表示选取物品i) 取得最大值。
在该问题中需要决定x1 .. xn的值。假设按i = 1,2,...,n 的次序来确定xi 的值。如果置x1 = 0,则问题转变为相对于其余物品(即物品2,3,.,n),背包容量仍为c 的背包问题。若置x1 = 1,问题就变为关于最大背包容量为c-w1 的问题。现设r? 为剩余的背包容量。
在第一次决策之后,剩下的问题便是考虑背包容量为r 时的决策。不管x1 是0或是1,[x2 ,.,xn ] 必须是第一次决策之后的一个最优方案,如果不是,则会有一个更好的方案[y2,.,yn ],因而[x1,y2,.,yn ]是一个更好的方案。
假设n=3, w=[100,14,10], p=[20,18,15], c= 116。若设x1 = 1,则在本次决策之后,可用的背包容量为r= 116-100=16 。[x2,x3 ]=[0,1] 符合容量限制的条件,所得值为1 5,但因为[x2,x3 ]= [1,0] 同样符合容量条件且所得值为1 8,因此[x2,x3 ] = [ 0,1] 并非最优策略。即x= [ 1,0,1] 可改进为x= [ 1,1,0 ]。若设x1 = 0,则对于剩下的两种物品而言,容量限制条件为116。总之,如果子问题的结果[x2,x3 ]不是剩余情况下的一个最优解,则[x1,x2,x3 ]也不会是总体的最优解。在此问题中,最优决策序列由最优决策子序列组成。假设f (i,y) 表示剩余容量为y,剩余物品为i,i + 1,...,n 时的最优解的值,即:利用最优序列由最优子序列构成的结论,可得到f 的递归式为:
当j>=wi时: f(i,j)=max ①式
当0<=j<wi时:f(i,j)=f(i+1,j) ②式
fn( 1 ,c) 是初始时背包问题的最优解。
以本题为例:若0≤y<1 0,则f ( 3 ,y) = 0;若y≥1 0,f ( 3 ,y) = 1 5。利用②式,可得f (2, y) = 0 ( 0≤y<10 );f(2,y)= 1 5(1 0≤y<1 4);f(2,y)= 1 8(1 4≤y<2 4)和f(2,y)= 3 3(y≥2 4)。因此最优解f ( 1 , 11 6 ) = m a x = m a x = m a x = 3 8。
现在计算xi 值,步骤如下:若f ( 1 ,c) =f ( 2 ,c),则x1 = 0,否则x1 = 1。接下来需从剩余容量c-w1中寻求最优解,用f (2, c-w1) 表示最优解。依此类推,可得到所有的xi (i= 1.n) 值。
在该例中,可得出f ( 2 , 116 ) = 3 3≠f ( 1 , 11 6 ),所以x1 = 1。接着利用返回值3 8 -p1=18 计算x2 及x3,此时r = 11 6 -w1 = 1 6,又由f ( 2 , 1 6 ) = 1 8,得f ( 3 , 1 6 ) = 1 4≠f ( 2 , 1 6 ),因此x2 = 1,此时r= 1 6 -w2 = 2,所以f (3,2) =0,即得x3 = 0。

Ⅸ 贪婪启发式和贪婪算法的区别是什么

马踏棋盘的问题很早就有人提出,且早在1823年,J.C.Warnsdorff就提出了一个有名的算法。在每个结点对其子结点进行选取时,优先选择‘出口’最小的进行搜索,‘出口’的意思是在这些子结点中它们的可行子结点的个数,也就是‘孙子’结点越少的越优先跳,为什么要这样选取,这是一种局部调整最优的做法,如果优先选择出口多的子结点,那出口少的子结点就会越来越多,很可能出现‘死’结点(顾名思义就是没有出口又没有跳过的结点),这样对下面的搜索纯粹是徒劳,这样会浪费很多无用的时间,反过来如果每次都优先选择出口少的结点跳,那出口少的结点就会越来越少,这样跳成功的机会就更大一些。这种算法称为为贪心算法,也叫贪婪算法或启发式算法,它对整个求解过程的局部做最优调整,它只适用于求较优解或者部分解,而不能求最优解。这样的调整方法叫贪心策略,至于什么问题需要什么样的贪心策略是不确定的,具体问题具体分析。实验可以证明马遍历问题在运用到了上面的贪心策略之后求解速率有非常明显的提高,如果只要求出一个解甚至不用回溯就可以完成,因为在这个算法提出的时候世界上还没有计算机,这种方法完全可以用手工求出解来,其效率可想而知。
贪心算法当然也有正确的时候。求最小生成树的Prim算法和Kruskal算法都是漂亮的贪心算法。
贪心法的应用算法有Dijkstra的单源最短路径和Chvatal的贪心集合覆盖启发式
所以需要说明的是,贪心算法可以与随机化算法一起使用,具体的例子就不再多举了。其实很多的智能算法(也叫启发式算法),本质上就是贪心算法和随机化算法结合——这样的算法结果虽然也是局部最优解,但是比单纯的贪心算法更靠近了最优解。例如遗传算法,模拟退火算法。

Ⅹ 为什么贪心算法可用于解决最优化问题

最优化问题是程序设计中一类非常重要的问题。每一个最优化问题都包含一组约束条件和一个优化函数,满足约束条件的问题求解方案称为问题的可行解,使优化函数取得最优值的可行解称为问题的最优解。贪婪算法是解决最优化问题的一种基本方法。
它采用逐步构造最优解的思想,在问题求解的每一个阶段,都作出一个在一定标准下看上去最优的决策;决策一旦作出,就不可再更改。制定决策的依据称为贪婪准则。

热点内容
在香港怎么买安卓手机 发布:2024-11-16 03:15:37 浏览:761
存储sp 发布:2024-11-16 03:14:08 浏览:849
电视机存储功能 发布:2024-11-16 03:12:50 浏览:869
极品飞车17安卓怎么安装 发布:2024-11-16 03:12:13 浏览:316
长春java 发布:2024-11-16 03:10:47 浏览:577
性价比高的台式电脑怎么配置 发布:2024-11-16 03:04:58 浏览:632
软件测试学python 发布:2024-11-16 02:55:39 浏览:563
sql2008数据同步 发布:2024-11-16 02:33:46 浏览:928
sql2008sa密码 发布:2024-11-16 02:33:45 浏览:199
pr清缓存 发布:2024-11-16 02:31:28 浏览:656