首页 > 其他分享 >加权区间调度问题

加权区间调度问题

时间:2024-01-20 20:14:44浏览次数:22  
标签:加权 jobp memo list 调度 range 权值 区间 活动

问题描述:给定n个job,每个活动i的开始时间和结束时间,对应一个权值,找出权值之和最大的相容活动子集。(若两个job的时间不相交,则称两个活动是相容的compatible)

方案一(递归算法)

算法设计:

OPT(j): //j个活动求相容活动子集的最大权值
    If j == 0 then
return 0
Else
return max(OPT(p(j)) + vj, OPT(j-1))
    Endif

算法分析:

算法时间复杂度:自顶而下的递归算法是指数时间的,因为会重复计算子问题,不带记忆性,时间复杂度大概是O(1.618^n)(介于根号2^n~2^n)。

算法空间复杂度:O(n),需要大小为n的数组存储每个子问题的解。

程序设计:

 1 n = int(input('请输入活动个数:'))
 2 list_act = [[0 for i in range(3)] for j in range(n)]
 3 for i in range(0, n):
 4     list_act[i][0] = int(input('请输入第{}活动开始时间:'.format(i+1)))
 5     list_act[i][1] = int(input('请输入第{}活动结束时间:'.format(i+1)))
 6     list_act[i][2] = int(input('请输入第{}活动权值:'.format(i+1)))
 7 print(list_act)
 8 
 9 pre = [0] * n
10 for i in range(1, n):
11     for j in range(i-1, -1, -1):
12         if list_act[j][1] <= list_act[i][0]:
13             pre[i] = j + 1
14             break
15 print(pre)
16 
17 def option(n):
18     if n == 0:
19         return 0
20     if n >= 1:
21         if option(pre[n-1]) + list_act[n-1][2] >= option(n-1):
22             return option(pre[n-1]) + list_act[n-1][2]
23         else:
24             return option(n-1)
25 
26 print('相容活动权值之和最大是:', option(n))
27 
28 record = [[0 for i in range(2)] for j in range(n)]
29 for i in range(1 , n+1):
30     if option(pre[i-1]) + list_act[i-1][2] >= option(i-1):
31         record[i-1][0] = 1
32         record[i-1][1] = pre[i-1]
33     else:
34         record[i-1][0] = 0
35         record[i-1][1] = i - 1
36 
37 for i in range(1 , n+1):
38     j = record[i-1][1]
39     if j > 0 and record[j-1][0] == 1:
40         print('第{}个活动将被选择'.format(j))

结果输出:

方案二(动态规划算法)

算法设计:

1.输入活动的开始时间、结束时间和对应权值,存储在列表 job 中,并按照结束时间的早晚对活动进行排序,存储在列表 jobp 中。

2.使用动态规划的思想,定义两个数组 p 和 m,其中 p[i] 表示在选择前 i 个活动中,最后一个活动的索引,即 jobp[p[i]] 是最后一个被选择的活动;m[i] 表示选择前 i 个活动的最大权值和。

3.初始化 p 和 m 数组,p[0] = m[0] = 0。

4.对于每个活动 i,从前往后遍历,找到第一个不与前一个活动冲突的活动 j,即满足 jobp[i]['s'] >= jobp[j]['e']。然后将 j 的索引赋值给 p[i]。

5.使用备忘录数组 memo 来记录每个子问题的解,避免重复计算。对于每个活动 i,计算选择前 i 个活动的最大权值和,即 memo[i] = max(jobp[i]['v'] + memo[p[i]], memo[i - 1])。然后将 memo[i] 的值存储在数组 m 中。

6.返回 m[n],即选择所有活动的最大权值和。

算法分析:

算法的时间复杂度为 O(n^2),其中 n 是活动的个数。

算法的空间复杂度为 O(n),需要使用一个大小为 n 的备忘录数组来存储每个子问题的解。

程序设计:

 1 def solve(n):
 2     p = [0] * (n + 1)
 3     m = [0] * (n + 1)
 4     memo = [0] * (n + 1)
 5     job = [{'s': 0, 'e': 0, 'v': 0, 'index': 0} for _ in range(n + 1)]
 6     print("请依次输入活动的开始时间、结束时间和对应权值:")
 7     for i in range(1, n + 1):
 8         s, e, v = map(int, input().split())
 9         job[i]['s'], job[i]['e'], job[i]['v'] = s, e, v
10         job[i]['index'] = i
11     jobp = sorted(job, key=lambda x: x['e'],reverse=False)
12     for index, dictionary in enumerate(jobp,start=0):
13         dictionary['index'] = index
14     for i in range(n, 0, -1):
15         for j in range(n-1, 0, -1):
16             if jobp[i]['s'] >= jobp[j]['e']:
17                 p[i] = jobp[j]['index']
18                 break
19     for i in range(1, n + 1):
20         memo[i] = max(jobp[i]['v'] + memo[p[i]], memo[i - 1])
21         m[i] = memo[i]
22     return m[n]
23 
24 if __name__ == "__main__":
25     n = int(input("请输入活动个数:"))
26     result = solve(n)
27     print("最大权值为:",result)

结果输出:

标签:加权,jobp,memo,list,调度,range,权值,区间,活动
From: https://www.cnblogs.com/doris510/p/17976814

相关文章

  • [译] kubernetes:kube-scheduler 调度器代码结构概述
    本文翻译自https://github.com/kubernetes/community/blob/master/contributors/devel/sig-scheduling/scheduling_code_hierarchy_overview.md译者:胡云Troy调度器代码层次结构概述介绍调度器监视新创建的还没有分配节点的Pod。当发现这样的Pod后,调度器将Pod调度到最......
  • 利用topologySpreadConstraints使多个Pod在节点之间均衡调度
    在ingress-nginx部署时有个需求,就是3个节点单个节点需要至少跑3个实例。这需求有点像异地多活时,每个区域至少要跑2实例一样,不同之处是一个是节点级别,一个是区域级别。deployment在副本数多的时候虽然可以让调度器大致上的平均调度,但是当遇到个别节点压力大的时候会降低调度score......
  • 利用topologySpreadConstraints使多个Pod在节点之间均衡调度
    在ingress-nginx部署时有个需求,就是3个节点单个节点需要至少跑3个实例。这需求有点像异地多活时,每个区域至少要跑2实例一样,不同之处是一个是节点级别,一个是区域级别。deployment在副本数多的时候虽然可以让调度器大致上的平均调度,但是当遇到个别节点压力大的时候会降低调度score......
  • 使用Cron表达式调度多个任务的实现方法
    Cron表达式是一种用于指定定时任务执行时间的字符串格式。通过合理运用Cron表达式,我们可以方便地调度多个任务,并按照设定的时间规则自动执行。本文将介绍如何使用Cron表达式来调度多个任务,以帮助您更好地管理和执行定时任务。一、什么是Cron表达式Cron表达式是一种由6个或7个字段组......
  • 布控球在可视化指挥调度系统应用中大有作为
     随着科技的不断发展,可视化指挥调度系统在各行各业中的应用越来越广泛。其中,布控球作为一种新型的安全管理设备,逐渐成为了可视化指挥调度系统中的重要组成部分。布控球是一种集视频监控、报警、对讲等功能于一体的综合布控设备。它通过高清摄像头和先进的图像处理技术,实时捕捉......
  • 区间本质不同子串个数
    传送门LCT好题。description给定一个长度为\(n\)的只包含小写英文字母的字符串。有\(m\)次询问,每次问一个子串的本质不同子串个数。\(n\leq10^5\)\(m\leq2\times10^5\)solution考虑按询问右端点从小到大离线。先建出母串的SAM,设\(\text{len}_x\)表示状......
  • 加权排列熵Weighted Permutation Entropy及多尺度系列(Matlab版)
    学者们开发了各种复杂性度量来比较时间序列并区分规则(例如,周期),混沌和随机行为。提出了加权排列熵概念,其是一个定义简单的复杂性度量,可以很容易地计算任何类型的时间序列,无论是规则的,混沌的,嘈杂的,还是基于现实的时间序列。(matlab代码获取:https://mbd.pub/o/bread/mbd-ZZmbm5pv)参......
  • 统计区间(双指针)
    这题求的非空区间可以是整个数组内的任意一个区间,刚开始我是想用一个for和一个whilefor(inti=0;i<n;i++){ l=0,sum=0; while(l<i){ intj=l; for(intk=j;k<i;k++){ sum+=a[k]; if(sum>=k){ s++; break; ) } l++; }}但因为数据太大,......
  • 神经网络优化篇:详解指数加权平均的偏差修正(Bias correction in exponentially weighte
    指数加权平均的偏差修正\({{v}_{t}}=\beta{{v}_{t-1}}+(1-\beta){{\theta}_{t}}\)在上一个博客中,这个(红色)曲线对应\(\beta\)的值为0.9,这个(绿色)曲线对应的\(\beta\)=0.98,如果执行写在这里的公式,在\(\beta\)等于0.98的时候,得到的并不是绿色曲线,而是紫色曲线,可以注意到紫色曲线......
  • 神经网络优化篇:理解指数加权平均数(Understanding exponentially weighted averages)
    理解指数加权平均数回忆一下这个计算指数加权平均数的关键方程。\({{v}_{t}}=\beta{{v}_{t-1}}+(1-\beta){{\theta}_{t}}\)\(\beta=0.9\)的时候,得到的结果是红线,如果它更接近于1,比如0.98,结果就是绿线,如果\(\beta\)小一点,如果是0.5,结果就是黄线。进一步地分析,来理解如何计......