-
Notifications
You must be signed in to change notification settings - Fork 0
/
tools.py
146 lines (131 loc) · 5.21 KB
/
tools.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# -*- coding:utf-8 -*-
import Logger
from Tasks import *
from WorkStations import *
"""
3
0 4 4
1 4 8
2 2 4
5
0 15 [1] [] [4] [0,1]
1 30 [] [] [] []
2 35 [] [] [] []
3 10 [] [4] [] []
4 8 [] [] [] []
"""
# 获取输入
def input_information():
logger = Logger.getLogger("Tool") # GetLogger
# 记得初始化name为下标
workstation_list = []
tasks_list = []
for i in range(int(input())):
command = input().split(' ') # 每一行的命令
workstation = WorkStations(int(command[0]), int(command[1]), float(command[2]))
workstation_list.append(workstation)
# print(workstation)
del command
for i in range(int(input())):
command = input().split(' ') # 每一行的命令
task = Tasks(int(command[0]), float(command[1]), eval(command[2]), eval(command[3]), eval(command[4]),
eval(command[5]))
tasks_list.append(task)
# print(task)
return workstation_list, tasks_list
'''
1. 部分任务不能分发到指定的工作站上;
2. 部分任务一定要同时运行在同一台工作站上;
3. 部分任务一定不能同时运行在同一台工作站上;
'''
def initial_deploy(workstation_list: list, tasks_list: list):
logger = Logger.getLogger("Tool") # GetLogger
logger.info("Starting initial deployment...")
for i in tasks_list:
if not i: # 被去重了
continue
# TODO:并行任务此处还可以优化
task_list = [i]
work_load = i.work_load
for other_tasks in i.limit2:
if not tasks_list[other_tasks]:
continue
work_load += tasks_list[other_tasks].work_load # 并行
task_list.append(tasks_list[other_tasks])
tasks_list[other_tasks] = False
logger.debug("Total Work_Load of task {}:{}".format(i.name, str(work_load)))
match_list = [-1, 0]
for j in workstation_list:
for banned_workstation in i.limit1:
if j.name == banned_workstation:
logger.debug("Task {} Unable on Banned Workstation:{}".format(i.name, j.name))
continue
for banned_task in i.limit3:
if banned_task in j.queue:
logger.debug("Task {} Unable with Banned Task:{}".format(i.name, j.queue))
continue
match_rate = work_load / j.capacity_constraints - random() / 8 # 随机扰动
if match_rate > 1: # 放不下
continue # 换一个工作站
if match_rate > match_list[1]: # 更新最新
match_list[0] = j.name
match_list[1] = match_rate
# deploy
if match_list[0] == -1: # 没有一个能放下
logger.error("No WorkStation can contain Task {}".format([task.name for task in task_list]))
else:
workstation_list[match_list[0]].queue.append(task_list)
return workstation_list
def calculate_balance(workstation_list: list):
logger = Logger.getLogger("Tool") # GetLogger
logger.info("Start Calculating balance...")
max_time = [0, 0]
min_time = [0, 0]
outage = False
for i in workstation_list:
total_work_load = 0
if not i.status:
outage = True
try:
for task in i.working:
total_work_load += task.work_load
except TypeError: # 如果为空
pass
try:
for i_2 in i.queue: # 加上队列中的时间
for i_3 in i_2:
total_work_load += i_3.work_load
except TypeError: # 如果为空
pass
time = total_work_load / i.load_capacity
if time > max_time[1]:
max_time[0] = i.name
max_time[1] = time
if time <= min_time[1]:
min_time[0] = i.name
min_time[1] = time
logger.debug("balance Output:ratio:" + str((max_time[1] - min_time[1]) / max_time[1]))
logger.debug("balance Output:WorkStation:Max:{},Min:{}".format(max_time[0], min_time[0]))
return (max_time[1] - min_time[1]) / max_time[1], max_time[0], min_time[0], outage
def steal_tasks(workstation_list: list, max_workstation: int, min_workstation: int):
logger = Logger.getLogger("Tool") # GetLogger
try:
task_max = workstation_list[max_workstation].queue.pop()
except IndexError:
logger.warning("{} Reached the bottom of Task Queue!".format(workstation_list[max_workstation].name))
return 0
logger.debug("Putting Task {} to WorkStation {}".format([task.name for task in task_max].__str__(),
workstation_list[min_workstation].name))
workstation_list[min_workstation].queue.append(task_max)
return 1
def print_complete_map(workstation_list):
logger = Logger.getLogger("Tool") # GetLogger
for i in workstation_list:
log_info = ""
for task_i in i.complete_tasks:
log_info += " "
for task_j in task_i:
log_info += str(task_j.name)
log_info += ","
logger.debug("{}<-{}".format(i.name, log_info)) # log:完成情况
# logger.info("{},".format([each for each in i.complete_tasks].__str__()))