python实现带链式约束可中断的总加权完成时间最小算法

工作 权重 工作时间
1 6 3
2 18 6
3 12 6
4 8 5
5 8 4
6 17 8
7 18 10

有以上7个工作,每个工作带有权重,表示如果该工作在未完成前每个时刻需要付出的代价。
工作不能同时进行,但可以中断。
现将这些工作分为工作链
1+2+3+4
5+6+7
工作链中任务时必须顺序进行
目标:总加权完成时间最小

算法

对于每个工作链,计算前i个工作的(总权重/总时间),得到该工作链获得最大(总权重/总时间)的索引
比较每个工作链,找到(总权重/总时间)最大的工作的索引
首先计算该工作从开始到索引的部分(包括索引)
重复刚才的过程,直到所有工作被安排
python实现如下:

def calculate_quota(tasks):
    biggest_quota = 0
    biggest_quota_index = 0
    weight = 0
    time = 0
    index = 0
    for task in tasks:
        weight += task['weight']
        time += task['time']
        quota = weight / time
        if quota > biggest_quota:
            biggest_quota = quota
            biggest_quota_index = index
        index += 1
    return biggest_quota, biggest_quota_index


def interrupt_chain_smallest_weighted_time(*all_tasks):
    amount = 0
    for tasks in all_tasks:
        amount += len(tasks)
    schedule = list()
    cost = 0
    time = 0
    while len(schedule) != amount:
        index = 0
        quota_list = list()
        for tasks in all_tasks:
            biggest_quota, biggest_quota_index = calculate_quota(tasks)
            quota_list.append([biggest_quota, biggest_quota_index, index])
            index += 1
        best_tasks = sorted(quota_list, key=lambda x: x[0], reverse=True)[0]
        schedule.extend(all_tasks[best_tasks[2]][:best_tasks[1]+1])
        for task in all_tasks[best_tasks[2]][:best_tasks[1]+1]:
            time += task['weight']
            cost += time * task['weight']
        del all_tasks[best_tasks[2]][:best_tasks[1]+1]
    return schedule, cost


def main():
    tasks_0 = [dict(weight=6, time=3, index=1),
               dict(weight=18, time=6, index=2),
               dict(weight=12, time=6, index=3),
               dict(weight=8, time=5, index=4)]
    tasks_1 = [dict(weight=8, time=4, index=5),
               dict(weight=17, time=8, index=6),
               dict(weight=18, time=10, index=7)]
    schedule, cost = interrupt_chain_smallest_weighted_time(tasks_0, tasks_1)
    print(cost)
    for task in schedule:
        print(task)


if __name__ == '__main__':
    main()

输出:

4407
{'weight': 6, 'time': 3, 'index': 1}
{'weight': 18, 'time': 6, 'index': 2}
{'weight': 8, 'time': 4, 'index': 5}
{'weight': 17, 'time': 8, 'index': 6}
{'weight': 12, 'time': 6, 'index': 3}
{'weight': 18, 'time': 10, 'index': 7}
{'weight': 8, 'time': 5, 'index': 4}

猜你喜欢

转载自blog.csdn.net/weixin_43793472/article/details/88531474