python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python区间调度算法

Python实现区间调度算法

作者:python收藏家

区间调度算法是一种在给定的一组任务中,选择尽可能多的相互不冲突的任务的算法,本文主要介绍了如何使用Python实现区间调度算法,有需要的可以参考下

本文将介绍如何在Python中实现区间调度算法。让我们从区间调度算法的概述开始。

什么是区间调度算法

在算法设计领域,区间排序是一类问题。这些计划考虑到了一些任务。每个任务都由一个时间间隔表示,该时间间隔指示机器完成该任务所需的时间。如果系统或资源上的任何两个时间间隔之间没有重叠,则时间间隔的子集是兼容的。

区间调度算法的核心思想是将任务的开始和结束时间分开考虑,通过比较任务的开始时间或结束时间来确定任务的执行顺序。具体来说,可以将任务按照开始时间或结束时间进行排序,然后根据排序结果逐个执行任务,同时记录当前已执行的任务集合,以便在需要时进行调整。

区间调度最大化问题的目标是确定最大的兼容集或具有最小可能重叠的区间集合。这个想法是通过完成尽可能多的任务来优化吞吐量。

区间调度问题:

输入: n个间隔{s(i),.,f(i)−1}的输入,其中1 ≤ i ≤ n,i表示间隔,s(i)表示开始时间,f(i)表示结束时间。

输出: 一个时间表S的n个时间间隔,其中没有两个时间间隔在S冲突,总的时间间隔在S是最大的。

假设我们有一个事件列表,每个事件的格式为[a,b],其中a是开始时间,b是结束时间。一个人一次只能参加其中一个活动,他们可以立即从一个活动转到另一个活动。如果两个事件的停止时间和开始时间分别重合。找到一个人可以参加的最大数量的活动。

intervals = [[4,5],[0,2],[2,7],[1,3],[0,4]]

在这个问题中,我们必须确定一个人可以参加的活动的最大数量。检查下面的图表,看看这个人是如何尽可能多地参加活动的。

考虑下面的场景,如果一个人在间隔(4,5)和(0,2)参加一个事件,他将无法在间隔(2,7)、(1,3)和(0,4)参加事件,因此事件的最大数量将是两个。

如果我们想参加尽可能多的活动,我们应该参加在短时间内完成的小型活动。参加一个时间跨度较长的活动将不会有好处,因为我们将无法参加其他活动,由于重叠的间隔。尽量先选择持续时间最短的项目。

我们如何才能实现这一目标

选项是将所有间隔存储在列表中,并根据结束时间对列表项进行排序。

初始列表- [(4,5),(0,2),(2,7),(1,3),(0,4)]
排序列表- [(0,2),(1,3),(0,4),(4,5),(2,7)]

排序后的图如下所示:

根据图,我们可以参加(0,2)和(4,5)事件,但其余的仍然重叠。现在我们将计算程序的间隔。

intervals = [(4, 5), (0, 2), (2, 7), (1, 3), (0, 4)] 

# sorting the intervals 
intervals.sort(key=lambda x: x[1]) 

# print(intervals) 
# counting the events 
count = 0
# keeping track of ending of intervals 
end = 0
# list of the intervals in which person will attend the events 
answer = [] 

# traversing the list of intervals 
for interval in intervals: 
	# starting time of next interval will >= ending 
	# time of previous interval 
	if(end <= interval[0]): 
		# update the and 
		end = interval[1] 
		# increment the count by one 
		count += 1
		# insert the non-conflict interval in the list 
		answer.append(interval) 

# print statements will print non-conflict 
# intervals count as well intervals 
print("一个人可以参加的最大活动数是: ", count) 
print("其将参加活动的时间间隔列表为: ", answer) 

输出

'一个人可以参加的最大活动数是:', 2
'其将参加活动的时间间隔列表为:', [(0, 2), (4, 5)]

其他示例

示例1

# list of intervals 
intervals = [(1, 3), (7, 12), (2, 5), (6, 18), (14, 16)] 

接着,我们根据每个元组的结束时间或第二个元素对元组列表进行排序。Lambda是一个小函数,允许你传递任意数量的参数,但表达式应该在一行中。在上述情况下,lambda函数访问interval列表中元组的第二个元素,并将其作为键传递给sort函数,以便元组将按照第二个元素以升序排序。

# list of intervals 
intervals = [(1,3),(7,12),(2,5),(6,18),(14,16)] 

# sorting the intervals 
intervals.sort(key = lambda x : x [1]) 
print(intervals)

输出

[(1, 3), (2, 5), (7, 12), (14, 16), (6, 18)]

现在我们初始化count,并将变量记为零。计数和结束将根据条件在程序中更改。计数将告诉我们没有冲突的最大间隔数的计数,结束将帮助我们跟踪间隔。我们将在结果列表中存储非冲突间隔。

# counting the events 
count = 0

# keeping track of ending of intervals 
end = 0

# list of the intervals in which person will attend the events 
answer = [] 

我们逐个遍历每个间隔,并检查下一个间隔的开始时间是否大于或等于前一个间隔的结束时间。如果为真,我们将计数器递增1并将该间隔插入到答案列表中,我们这样做是因为不应该有任何冲突,并且因为我们已经基于间隔的结束时间对间隔进行了排序,所以我们首先参加排序周期间隔,以便我们可以最大化结果。在最后,我们只是打印计数的非冲突的时间间隔以及非冲突的时间间隔作为一个列表。

完整代码:

# list of intervals 
intervals = [(1, 3), (7, 12), (2, 5), (6, 18), (14, 16)] 

# sorting the intervals 
intervals.sort(key=lambda x: x[1]) 
# print(intervals) 

# counting the events 
count = 0

# keeping track of ending of intervals 
end = 0

# list of the intervals in which person will attend the events 
answer = [] 

# traversing the list of intervals 
for interval in intervals: 

	# starting time of next interval will >= ending time of previous interval 
	if(end <= interval[0]): 

		# update the and 
		end = interval[1] 

		# increment the count by one 
		count += 1

		# insert the non-conflict interval in the list 
		answer.append(interval) 

# print statements will print non-conflict intervals count as well intervals 
print("The count of Non-conflict intervals : ", count) 
print("List of the intervals : ", answer) 

输出

'The count of Non-conflict intervals : ', 3
'List of the intervals : ', [(1, 3), (7, 12), (14, 16)]

示例2

在这个例子中,可以清楚地看到,每个前一个间隔的结束时间等于下一个间隔的开始时间,这意味着我们可以在没有任何冲突的情况下为每个间隔安排工作,因此结果将是间隔的数量,即5。

intervals = [(2, 5), (5, 10), (10, 20), (20, 30), (30, 45)] 

# sorting the intervals 
intervals.sort(key=lambda x: x[1]) 
print(intervals) 
# counting the events 
count = 0
# keeping track of ending of intervals 
end = 0
# list of the intervals in which person will attend the events 
answer = [] 
# traversing the list of intervals 
for interval in intervals: 
	# starting time of next interval will >= ending time of previous interval 
	if(end <= interval[0]): 
		# update the and 
		end = interval[1] 
		# increment the count by one 
		count += 1
		# insert the non-conflict interval in the list 
		answer.append(interval) 

# print statements will print non-conflict intervals count as well intervals 
print("The count of non-overlapping events : ", count) 
print("List of intervals without overlapping : ", answer) 

输出

[(2, 5), (5, 10), (10, 20), (20, 30), (30, 45)]
'The count of non-overlapping events : ', 5
'List of intervals without overlapping  : ', [(2, 5), (5, 10), (10, 20), (20, 30), (30, 45)]

示例3

在这个例子中,间隔不符合我们的要求,所以间隔将以这样的方式排序,即最小周期间隔将开始,然后是更大的间隔。这就是排序后的区间- [(3,5),(4,5),(6,8),(10,11),(2,12),(9,12),(11,12)]。正如你所看到的,第一、第三、第四和第七个间隔彼此不重叠,所以没有冲突的间隔的最大数量将是4。

intervals = [(2, 12), (3, 5), (4, 5), (6, 8), (9, 12), (10, 11), (11, 12)] 

# sorting the intervals 
intervals.sort(key=lambda x: x[1]) 
print(intervals) 
# counting the events 
count = 0
# keeping track of ending of intervals 
end = 0
# list of the intervals in which person will attend the events 
answer = [] 

# traversing the list of intervals 
for interval in intervals: 
	# starting time of next interval will >= ending time of previous interval 
	if(end <= interval[0]): 
		# update the and 
		end = interval[1] 
		# increment the count by one 
		count += 1
		# insert the non-conflict interval in the list 
		answer.append(interval) 

# print statements will print non-conflict intervals count as well intervals 
print("The count of non-overlapping events : ", count) 
print("List of intervals without overlapping : ", answer) 

输出

[(3, 5), (4, 5), (6, 8), (10, 11), (2, 12), (9, 12), (11, 12)]
'The count of non-overlapping events : ', 4
'List of intervals without overlapping  : ', [(3, 5), (6, 8), (10, 11), (11, 12)]

示例4

在这个例子中,排序后的区间列表看起来像这样- [(1,2),(2,3),(2,4),(1,6),(4,9),(5,10)]。我们可以观察到第1、第2和第5个间隔不重叠,因此不重叠的最大间隔数为3。

intervals = [(1, 6), (2, 3), (5, 10), (1, 2), (2, 4), (4, 9)] 

# sorting the intervals 
intervals.sort(key=lambda x: x[1]) 
print(intervals) 
# counting the events 
count = 0
# keeping track of ending of intervals 
end = 0
# list of the intervals in which person will attend the events 
answer = [] 

# traversing the list of intervals 
for interval in intervals: 
	# starting time of next interval will >= ending time of previous interval 
	if(end <= interval[0]): 
		# update the and 
		end = interval[1] 
		# increment the count by one 
		count += 1
		# insert the non-conflict interval in the list 
		answer.append(interval) 

# print statements will print non-conflict intervals count as well intervals 
print("The count of non-overlapping events : ", count) 
print("List of intervals without overlapping : ", answer) 

输出

[(1, 2), (2, 3), (2, 4), (1, 6), (4, 9), (5, 10)]
'The count of non-overlapping events : ', 3
'List of intervals without overlapping  : ', [(1, 2), (2, 3), (4, 9)]

到此这篇关于Python实现区间调度算法的文章就介绍到这了,更多相关Python区间调度算法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文