算法设计与分析学习笔记(3)贪心算法

贪心思想:贪心算法要求不从全局看待问题,先从当前子问题找点最优解,那么如果子问题都是最优的选择,一定能找到全局最优的结果。
因此贪心算法可以很有用,贪心算法既是很容易理解的算法,又是不容易理解的算法,因为贪心策略的选择因人而异。贪心算法讲究的是当前子问题的最优解,所以寻找贪心算法的最优策略时就要有“走一步,看一步”这样的心理状态,如果能找到子问题的最优解,那么再从全局观察,加以简单的证明,那么就可以确认选择了最优的策略,那么我们就可以去使用这种策略去解决问题了。
重难点:题目是否可以使用贪心法去考虑,如果使用贪心思想来看待问题,到底应该选择哪种贪心策略呢?
实例: 最优服务次序问题
最优服务次序问题:设有n个顾客同时等待一项服务。顾客i需要的服务时间为ti,1≤i≤n。共有s处可以提供此服务。应如何安排n个顾客的服务次序才能使平均等待时间达到最小平均等待时间是n个顾客等待服务时间的总和除以n。
问题分析:最优服务次序问题:有n个顾客在同时等待一项服务,但是这个服务可以在很多处地方提供服务。要安排n个顾客的服务次序使得平均等待时间达到最小平均等待时间,那么我们来看一下等待时间是怎么来的:
假设原问题为T(先假设只有一个服务点),而我们已经知道了某个最优服务系列,即最优解为A={t(1),t(2),….t(n)}(其中t(i)为第i个用户需要的服务时间),
则每个用户等待时间为:
T(1)=t(1);
T(2)=t(1)+t(2);

T(n)=t(1)+t(2)+t(3)+…+t(n);

那么总等待时问,即最优值为:
TA=n*t(1)+(n-1)*t(2)+…+(n+1-j)t(i)+…+2t(n-1)+t(n);

由于平均等待时间是n个顾客等待时间的总和除以n,故本题实际上就是求使顾客等待时间的总和最小的服务次序。
时间越短应被计算次数越多,所以对服务时间最短的顾客先服务的贪心选择策略。
建模
(1)首先定义顾客人数(n)和服务处个数(s),建立列表储存每个顾客所需的服务时间,再将列表升序排序。
(2)创建服务时间列表和等待时间列表,对每个服务点的目前时间进行比较,数值最小的服务点即为最快能接受服务的服务点,为该服务点进行服务。
(3)将每个用户的等待时间相加,再除以客户的总数,即得到最小平均服务时间。
算法描述:首先将所有的等待时间从小到大排序,分别用两个数组存放当前服务点的某一点的等待时间和当前服务点的所有等待时间,按照这种机制,遍历整个等待时间,直到把所有的等待时间都放在各个服务点中,我们再求得所有服务点的等待时间的和,这个和便是我们选择的的贪心策略的最优解,再去除以等待时间的总数,便求得了最小平均服务时间。
算法源码:

#最优服务次序问题
#初始化两个数组 
#s1[]数组存放i在j服务处的等待时间
#s2[]数组存放j服务处对所有等待时间

def gree(arr,n,s):     #定义gree函数
    j=0
    s1=[]              #定义两个数组
    s2=[]
    for i in range(s):  #两个数组初始化为0
        s1.append(0)
        s2.append(0)

    for i in range(n):
        s1[j]+=arr[i]   #s1[]数组存放i在j服务处的等待时间
        s2[j]+=s1[j]    #s2[]数组存放j服务处对所有等待时间
        j+=1            #递增
        if j==s:        #如果j递增到了所有s服务处,那就从第一个服务处重新开始,一直这样循环
             j=0         #直到将所有人都排满为止

    sum=0               #定义求和sum
    for i in range(s):  #将在s个服务处的各个服务处的所有等待时间都加起来
        sum+=s2[i]

    return sum//n       #最小平均等待时间就是所有等待时间总和除以人数n

if __name__ == '__main__':
    arr=[56,12,1,99,1000,234,33,55,99,812]    #实验数据测试
    arr.sort()                                #升序等待时间
    n=len(arr)                                 
    t=gree(arr,n,2)
    print("最小平均等待时间:",t)

测试数据
1.Sample Input
10 2
56 12 1 99 1000 234 33 55 99 812
Sample Output
336
2.Sample Input
10 3
1 6 33 8 55 9 44 33 7 44
Sample Output
36
3.Sample Input
10 4
3 77 43 98 34 11 23 43 19 29
Sample Output
51

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值