贪心法实验

一、实验目的

1 理解贪心法的特征(最优子结构\贪心选择\局部最优)

2 理解贪心法的求解(划分过程\根据贪心策略做出选择,规模变小\求解子问题)

3 掌握贪心法的简单实现和时间复杂度分析

二、实验内容

1、背包问题

2、找零钱问题

3、图着色问题

三、问题分析

1、背包问题

      因为不是0/1问题,所以要根据物品的单位价值进行降序排列,先把单位价值大的物品装入背包,然后如果背包还有空间的话,再把剩余的物品按照比例放入背包当中

2、找零钱问题

      依旧是先把纸币的值按照降序排列,每次都去判断要找的钱是否大于最大的纸币,大于则就用大纸币,然后将要找的钱数缩小

3、图着色问题

     

依次遍历每个顶点,判断这个顶点与前后的顶点有没有相连,颜色有没有相同,以此来进行着色

四、问题解决

       1、背包问题:

(1)、算法描述:

算法:KnapSack

输入:背包容量C,物品重量w[],物品价值v[]

输出:背包的最大价值

过程:1、让w[],v[]两个数组按照单位重量价值降序排列

         2、定义一个长度为n的数组,并将其初始化为0

         3、考虑单位重量价值最大的物品:i=1

         4、循环知道wi >C

              4.1、将第i个物品放入背包

              4.2、C=C-wi;

              4.3、i++;

         5、最后装入的物品:xi=C/wi

       (2)、代码:

该算法的时间复杂度为:O(nlogn)

              (3)、运行截图:

2、找零钱问题:

(1)、算法描述:

算法:PayMoney

输入:找的钱数sum,纸币种类m[]

输出:找的纸币数量

过程:1、定义整形变量count

         2、只要sum>0,就重复执行以下操作

              2.1、循环变量i从0到m[]数组长度,重复以下操作

                     2.1.1如sum>=m[i],则count++;sum=sum-m[i];break;

              2.2i++、

         4、返回count

(2)、代码:

该算法时间复杂度为:O(n)

(3)、运行截图“

3、图着色问题:

(1)、算法描述:

算法:ColorGraph

输入:无向图G=(V,E)

输出:最小色数

过程:1、所有顶点置未着色状态;颜色k初始化为0;

         2、循环知道所有顶点均着色

              2.1、取下一种颜色k++;

              2.2、循环变量i从1至n依次考查所有顶点

                     2.2.1若顶点i已经着色,则转步骤2.2,考查下一个顶点

                     2.2.2若顶点i着颜色k不冲突,则color[i]=k;

         3、输出各顶点的着色

(2)、代码:

该算法的时间复杂度为O(k*n)

(3)、运行截图:

五、实验结果总结

回答以下问题:

  1. 请从你实现的级别中选择一题,说明贪心法的解决过程(划分阶段、依据贪心策略做出选择、求解子问题)

对于背包问题,对物品进行降序排列之后,依次判断物品的重量是都小于背包的容量,如果小于则直接放入背包当中,直到不能够完整放下去之后,再对物品进行切割,按照比例装入背包,计算背包价值

  1. 你觉得贪心法、动态规划法、分治法有相同点吗?有不同点吗?请举例说明。

有相同点,它们都是将问题实例归纳为更小的相似的子问题,并通过求解子问题产生一个全局最优解;也有不同点,其中贪心法的当前选择可能要依赖已经作出的所有选择,但不依赖于有待于做出的选择和子问题;而分治法中的各个子问题是独立的 (即不包含公共的子子问题),因此一旦递归地求出各子问题的解后,便可自下而上地将子问题的解合并成问题的解。动态规划则是主要应用于最优化问题,这类问题会有多种可能的解,每个解都有一个值,而动态规划找出其中最优(最大或最小)值的解。

  1. 你觉得贪心法能用递归实现吗?如果能,请把你实现的一道题目改为贪心法的递归程序。

可以通过递归实现。

       对于图着色问题的递归算法:

       void trycolor(int s,Graph G)/*填颜色,s为开始图色的顶点,本算法从1开始*/

{

    int i;

    if(s>G.vnum){/*如果s大于顶点的个数,递归出口*/

        output(G);

        exit(1);

    }else{

        for(i=1;i<=N;i++){/*对每一种色彩逐个测试*/

            color[s]=i;

            //如果flag=1进行下一种颜色的测试

            if(colorsame(s,G)==0){

                trycolor(s+1,G);/*进行下一块的着色*/

                break;

           }

        }

    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值