贪心算法思想

 贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题他能产生整体最优解或者是整体最优解的近似解。

一、 基本概念:

先看一个找零钱的例子,假设有3种硬币,面值分别为1元,5角,1角。这三种硬币数量不限,现在要给顾客找2元7角钱,请问怎么找钱才能使找给顾客的硬币最少呢?你也许会不假思索的说出答案:2枚1元的,1枚5角的,2枚1角硬币。在这里,我们下意识地应用了所谓的贪心算法。

所谓贪心算法,就是总是做出当前看来是最好的选择的一种方法。以上述为例,为了给顾客找的硬币最少,在选择硬币的时候,当然优先选择面值最大的。

(1)贪心选择性质

就是指所求解的最优解可以通过一系列的局部最优解得到。所谓局部最优解,就是指在当前的状态下做出的最好选择。

(2)最优子结构性质


            当一个问题的最优解包含着它的子问题的最优解时,就称此问题具有最优子结构性质。找零钱问题本身就具有最优子结构性质。但是,要判断一个问题是否具备以上两种性质,也就是说判断一个问题是否可以通过贪心算法得到最优解,是一件比较困难的事情。这里需要比较复杂而严格的数学证明。因此虽然贪心算法简单易实现,并且效率很高,但是使用贪心算法之前必须对问题本身进行深入而透彻地分析和证明,以保证使用贪心算法得到最优解。其实,虽然贪心算法不是对所有问题都能得到整体的最优解,但是实际应用中的许多问题都可以使用贪心算法得到最优解。与此同时,即使使用贪心算法不能产生出问题的最优解,但最终结果也是最优解的很好的近似解。因此在解决一般性问题时,我们大可不必过分要求一定要得到问题的最优解,也没有必要进行严格的推理证明,使用贪心算法是种不错的选择。我们经常使用的哈夫曼编码算法,求解最小生成树的克鲁斯卡尔算法和普里姆算法,求解图的单源最短路径的迪克斯特拉算法等都是基于贪心算法的思想设计出来的。


二、最优装船问题

:有一批集装箱要装入一个载重量为C的货船中,每个集装箱的质量由用户自己输入指定,在货船的装载体积不限的前提下,如何装载集装箱才能尽可能多地将集装箱装入货船中?
【分析】
     这个问题可以用贪心算法求得最优解。只要每次装船时,采取“质量最轻的集装箱先装船”的策略,就可以得到最优装船问题的一个最优解。在设计算法时,可用一个数组w存放每个集装箱的质量,例如w[2]=5,就表示第2个集装箱的质量为5.再设置一个向量数组x存放集装箱的取舍状态。其中,对1表示将第i个集装箱放入船中,x[i]=0表示第i个集装箱不装入货船。最终输出的结果应当是向量数组x[]的下标,如果输出结果为{0,1,4,5}表示将第0,1,4,5个集装箱装入货船中。也就是输出数组x中所有x[i]=1的下标i。

     应用贪心算法求解,为了装载尽可能多的集装箱,每次都要选出数组w[]中当前质量最轻的(即w[i]值最小的)集装箱,并将x[i]置1,同时重置c=c-w[i](,即变量c中存放货船的剩余载重量,c的初始值为货船总载重量C。循环执行上述操作,直到w[i]>c。可用下面这段代码描述:

Loading (int X[],int w[],int c,int n)
{
    int i,s=0;
    int *t =(int*)malloc(sizeof(int)*n);//存放w的下标
    sort(w,t,n);              //排序
    for(i=0; i<n; i++)
        x[i]=0;//初始化数组x[]
    for(i=0; i<n&&w[t[i]]<=c; i++)
    {
        x[t[i]]=1;
        c=c-w[[i]];
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值