问题描述
有N个工作,他们分别有一个开始时间和结束时间。找出在整个时间段内,能完成的最多的工作,且工作之间不能重叠。
图片来自https://blog.csdn.net/linxid/article/details/79655238
算法思想
将所有工作按照开始时间排序,从最后一个工作开开始找起。首先选出最后一个工作。然后往前找,如果与最后一个工作重叠,则跳过。如果不重叠,则选出。然后再将前一个工作与最近一次选出的工作比较。由于工作是按照开始时间排序,从后依次往前找不重叠,就能保证剩余的时间最多,最后选出工作的数量也最多。
代码实现
class Job:
StarTime = 0
EndTime = 0
# 将读入文件中的数据以初始化建立job的列表
def ini_jobs(filename):
infile = open(filename, "r")
time = infile.readline()
i = 0
jobs = list()
while time != '':
jobs.append(Job())
jobs[i].StarTime = int(time[0:2].lstrip())
jobs[i].EndTime = int(time[2:5].lstrip())
i += 1
time = infile.readline()
return jobs
#将所有的工作按照开始时间排序(冒泡法)
def sort_by_stime(jobs):
i = len(jobs)-1
while i > 0:
j = 0
while j < i:
if jobs[j].StarTime > jobs[j+1].StarTime:
tmp = jobs[j]
jobs[j] = jobs[j + 1]
jobs[j + 1] = tmp
j += 1
i -= 1
# 检查2个工作时间是否重叠
def is_overlap(job1, job2):
if job1.StarTime >= job2.EndTime or job1.EndTime <= job2.StarTime:
return False
else:
return True
# 从排序的工作中选出要求的工作
def select(sorted_jobs):
res = list()
i = len(sorted_jobs) - 1
res.append(sorted_jobs[i])
i -= 1
while i >= 0:
if is_overlap(sorted_jobs[i], res[-1]) is False:
res.append(sorted_jobs[i])
i -= 1
return res
def fun():
tasks = ini_jobs('test')
sort_by_stime(tasks)
selected_jobs = select(tasks)
j = 1
for i in selected_jobs:
print('job' + str(j) + ':' + str(i.StarTime) + '--' + str(i.EndTime))
j += 1
if __name__ == '__main__':
fun()
test的文件内容形如
0 10
1 2
3 5
2 3
2 5