工作 | 权重 | 工作时间 |
---|---|---|
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}