贪心算法解决活动安排

问题

问题概述

分析问题

解决问题

编程

编程流程以及数据类型选择

发现问题以及解决

最终实现

总结

程序缺陷以及完善

解题心路历程


问题


问题概述

设有n个活动的集合E={1,2,……,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi,且si<fi。如果选择了活动i,则它在时间区间[si,fi]内占用资源。若区间[si,fi]与区间[sj,fj]不相交,则称活动i与活动j是相容的。也就是说,当si>=fj或者sj>=fi时,活动i与活动j相容。活动安排问题就是要在所给的活动集合中选出最大的相容活动子集合。


分析问题

通过问题概述,可以模拟一个场景:

一个舞台在一天中是空闲的,可以用作活动的场合,不可以同时进行两个活动。所以活动的开始时间和结束时间是活动安排的判断标准。

问题的答案以及目的,是让舞台得到充分利用,进行最多的活动,即求出进行最大的活动的个数。


解决问题

可以将申请场地的所有的活动进行非减序排列(非减序排列,即说明当两个活动的结束时间相同,可以进行并列)。

定义两个集合,用于存储入选活动和候选活动。

获得非减序排列的活动排序后,对于第一个的活动,直接进行选择。此时,第一个活动即是入选活动。其它的活动是候选活动,对活动的开始时间和结束时间进行比较。有以下几种情况:

  1. 入选活动集合的最后一个活动的结束时间大于候选活动集合的第1个活动的开始时间,那个这个候选活动即被淘汰出候选活动集合。
  2. 入选活动集合的最后一个活动的结束时间小于等于候选活动集合的第一个活动的开始时间,那么这个候选活动将被选择到入选活动集合中。

重复以上操作,当候选活动集合没有活动时,则解决问题。以上的选择即是贪心选择,选择出当前的最优解。

综上,问题的解决有两个大的部分,部分1是对活动进行非减序排序;部分2是对活动进行贪心选择。


编程


编程流程以及数据类型选择

结合问题的部分,可以确定有以下步骤

  1. 通过键盘输入获得活动的开始时间和结束时间,使用元组存储活动的开始时间和结束时间,为活动元组;使用2个列表分别存储活动id、活动元组
  2. 根据活动的结束时间对活动进行非减序排列,并使用字典存储已经排序好的活动,字典的键对应活动的id,值对应活动元组。为候选活动字典
  3. 打印排序好的活动列表,打印活动字典
  4. 使用贪心算法对活动进行选择,使用字典存储入选活动的id和开始时间和结束时间,为入选活动字典
  5. 打印结果

发现问题以及解决

问题1:如何根据列表中元组元素的第二个参数进行排序,即对活动的结束时间进行排序

解决:定义一个函数

def takeSecond(elem):return elem[1]

用于返回列表的每个元组的第2个元素,并使用内置函数sort对列表进行排序

sort(key=takeSecond)

最终实现

程序代码:

#proname:greedy_act#author:zhj#time:2019.10.29#language:python#version:1.0
#arg:tuple=>(0,1)
#return:tuple[1]=>1
def takeSecond(elem):return elem[1]
#arg:lst_id:[1,2,3,..,n]
#    lst_act:[(s[1],f[1]),(s[2],f[2]),...,(s[n],f[n])]
#return:sort of dict_act
# {1:(,*),2:(,**),...,n:(,**n)}
def sortAct(lst_id,lst_act):lst_sort_act = lst_actlst_sort_act.sort(key=takeSecond)dict_act = dict(zip(lst_id,lst_sort_act))return dict_act#test:success
#arg:dict_act
#{1:(,*),2:(,**),...,n:(,**n)}
#return:gree of gree_act[id:(,*),id:(,**),...,id:(,*****)]
def greedy(dict_act):true_id = []true_act = []#purpose: get the first to append the listtrue_ele_tuple = dict_act[1]true_id.append(1)true_act.append(true_ele_tuple)#purpose: get the  finish time of fist activity to divide elementele_divi = true_ele_tuple[1]for i in range(1,num_act):
#get the first act finish timeid = int(1+i)#purpose:get the seconde activity to the last activitytuple_ele_act = dict_act[id]#print(tuple_ele_act) #test:successif (tuple_ele_act[0] >= ele_divi):true_id.append(id)true_act.append(tuple_ele_act)ele_divi = tuple_ele_act[1]greedy_act = dict(zip(true_id,true_act))return greedy_act
#main
input_act = input("请输入活动的个数,n = ")
num_act = int(input_act)
print("请分别输入开始时间s[i]和结束时间f[j]:")
lst_id = []
lst_act = []
for i in range(1,num_act+1):lst_id.append(i)input_start =eval(input("s["+str(i)+"]="))input_finish =eval(input("f["+str(i)+"]="))tuple = ()#purpose:def tuple to save the act_start and  act_finishtuple = (input_start,input_finish)lst_act.append(tuple)del tupleprint("")
dict_act = sortAct(lst_id,lst_act)
print("按结束时间非减序排列如下:")
print("序号----开始时间----结束时间")
for i in range(1,num_act+1):id = int(i)ele_tuple = dict_act[i]print(id,"------",ele_tuple[0],"----------",ele_tuple[1])
#test;success
greedy_act = greedy(dict_act)
#print(greedy_act)#test:success
true_id = list(greedy_act.keys())
# print(true_id)#test:success
print("----------------------")
print("安排的活动序号依次为:")
printlen = len(true_id)
for id in true_id:tuple_print = greedy_act[id]print(id,"    ",tuple_print[0],"------>",tuple_print[1])

运行结果截图:

总结


程序缺陷以及完善

  • 缺陷:没有异常判断,可能出现输入异常等等异常;

    • 完善:可以进行增加的话,因为代码工作量不大
  • 无法打印所有的活动安排方案


题目中是要求输出最多活动安排,所以也可以是另外一个方案。例如本题中,活动安排方案是 1->4->8->11,共4个活动。而2->4->8->11,1->4->9->11也是4个活动。

  • 完善:另一种处理方式,不只是贪心选择,而是将不符合的活动直接进行删除:第一个候选活动的开始时间小于最后一个入选活动的结束时间,那么这个候选活动,则直接进行删除

    • 例如本题中

      • 活动1已成功入选,那么活动2,3都直接删除
      • 活动4入选,同贪心选择,可以输出1->4->8->11
      • 回到第1步,删除活动4,则活动5直接删除;
      • 进行贪心选择,发现有1->6->11,存入列表,因为活动个数小于4,所以排除
      • 不断重复以上逻辑
    • 注:哪天有空,可以试试编写,并会在这里引用。
  • 代码优化:
    • 有很多代码可以进行优化,逻辑可以更加严密。

解题心路历程

使用贪心算法解决活动安排问题,可以说是对初学Python的一次有效的实践和应用。有以下几点需要笔记:

  • 使用正确的数据类型可以事半功倍:之前有尝试使用字典嵌套列表,结果发现处理流程,特别繁杂。所以使用字典嵌套元组,可以让问题处理逻辑更加清晰。减少大量的代码。
  • 程序逻辑清楚,可以使用函数优化代码,要明确每个函数的参数以及返回值是什么,以及这个函数的目的是什么

本篇已完成编写,如有更改,会在此列出。

贪心算法解决活动安排-Python实现(排序+贪心选择)相关推荐

  1. 贪心算法之活动安排问题C语言代码

    贪心算法之活动安排问题C语言 问题描述 该问题要求高效地安排一系列争用某一公共资源的活动. n:活动的个数,其中每个活动都要求使用同一资源,如演讲会场等.而且在同一时间内只有一个活动能使用这一资源. ...

  2. C语言会场安排问题贪心算法,贪心算法解决会场安排问题多处最优服务次序问题(含源代码).doc...

    贪心算法解决会场安排问题多处最优服务次序问题(含源代码) 西 安年月日-,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源.每个活动i都有一个要求使用该资源 ...

  3. 算法笔记(0002) - 【贪心算法】活动安排问题

    贪心算法 原理 在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解.贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许 ...

  4. 贪心算法实现活动安排问题

    贪心算法实现活动安排问题: 设有n个活动的集合E={1,2,...,n},其中,每个活动都要求使用同一资源,如演讲会场等,而在同一时间内,只有一个活动能使用这一资源.每个活动i都有一个要求使用该资源的 ...

  5. 贪心算法之活动安排问题(填表详解+思路解析)

    贪心算法 总是选择当前看起来最优的选择(局部最优解),得到的结果是一个整体最优解. 但是总是选择局部最优解并不总是能得到整体最优解,需要在问题具有:贪心选择性和优化子结构时才成立. 贪心选择性:第一次 ...

  6. 贪心算法-02活动安排问题

    活动安排问题 简介 活动安排问题是需要共享公共资源的一系列活动的高效安排问题,以在限定的资源前提下尽可能多地安排活动.一般,算法题中给出开始结束时间的活动序列都可以使用这种贪心思路. 问题描述 有若干 ...

  7. 基于贪心算法的活动安排问题

    一.问题的描述 学校的小礼堂每天都会有许多活动,有时间这些活动的计划时间会发生冲突,需要选择出一些活动进行举办.小刘的工作就是安排学校小礼堂的活动,每个时间最多安排一个活动. 现在小刘有一些活动计划的 ...

  8. C++编程笔记:贪心算法实现活动安排问题

    问题描述: 设有n个活动的集合E={1,2,-,n},其中,每个活动都要求使用同一资源,而在同一时间内只有一个活动能使用这一资源.每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi,且s ...

  9. 【贪心算法】活动安排问题

    活动安排问题就是要在所给的活动集合中选出最大的相容活动子集合,是可以用贪心算法有效求解的很好例子. 该问题要求高效地安排一系列争用某一公共资源的活动. 贪心算法提供了一个简单.漂亮的方法使得尽可能多的 ...

最新文章

  1. 【C++】多线程与原子操作和无锁编程【五】
  2. Android Binder 学习笔记
  3. 淘汰原因_大部分人被淘汰的原因都是因为安于现状
  4. python爬虫程序实例-10个python爬虫入门实例
  5. 关于Linux 是怎么来的,该如何去学
  6. UGUI 锚点设置为四方扩充模式然后设置局部坐标为0将出现什么问题
  7. Java 随心笔记10
  8. 【转】阿里技术专家详解DDD系列 第二讲 - 应用架构
  9. 【HDU - 1025】Constructing Roads In JGShining's Kingdom(dp最长上升子序列模型 + 二分优化)
  10. es6 数组去重,数组里面的对象去重
  11. “蚂蚁行军”和彩色边框设计
  12. Android Studio 使用教程(4)---gradle项目构建
  13. 安装oracle失败,停止在76%
  14. 第二百五十八节,Tornado框架-逻辑处理get()方法和post()方法,初识模板语言
  15. [Django]我的第一个网页,报错啦~(自己实现过程中遇到问题以及解决办法)
  16. 什么叫做蓝牙技术(转贴)
  17. 模二运算,模二加减乘除
  18. Windows图片和传真查看器打开图片慢
  19. keras 中的verbose详解
  20. Python正向和反向迭代器介绍

热门文章

  1. word中三线表的制作(及续表的制作)
  2. 必看!一名全栈工程师的必备“百宝箱”
  3. 信号处理中去除基线(baseline)干扰的几种方法器
  4. clang fatal error: ‘stdio.h‘ file not found
  5. 认识emu8086仿真内存
  6. 国家高新技术企业认定管理工作网
  7. 高频DCDC电源减小EMI的布局技巧
  8. 阿里代码规范检测工具-idea
  9. Python 中的 *list
  10. (转)ISV英文全称是Independent Software Vendors ,意为“独立软件开发商”