interval scheduling问题

问题描述

有N个工作,他们分别有一个开始时间和结束时间。找出在整个时间段内,能完成的最多的工作,且工作之间不能重叠。
图片来自https://blog.csdn.net/linxid/article/details/79655238图片来自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
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值