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
118from collections import Counter
import random
import secrets
import time
import matplotlib.pyplot as plt
import numpy as np
class Job:
def __init__(self, duration: int):
self.duration: int = duration
self.done: bool = False
self.id: str = secrets.token_hex()
def __repr__(self) -> str:
return f'Job({self.duration})'
def __isub__(self, num):
self.duration -= num
return self
class Cluster:
def __init__(self, n_machines):
self.resources = np.zeros(n_machines)
self.jobs = []
def add_job(self, job):
if not isinstance(job, Job):
raise TypeError(f'job not of type Job but {type(job)}')
self.jobs.append(job)
def step(self):
# time.sleep(0.1)
zero_array = np.zeros_like(self.resources)
self.resources = np.maximum(zero_array, self.resources - 1)
def available_resources(self):
"""Returns random available resource."""
return np.flatnonzero(self.resources == 0)
def assign_job(self, resource, job):
self.resources[resource] = job.duration
def done(self):
return len(self.jobs) == 0 and (self.resources == 0).all()
# More RL-like functions
def do_action(self, job):
"""Assign given job to random chosen resource and perform time step."""
available = self.available_resources()
if len(available) == 0:
raise ValueError(
'Not able to perform action, no resources available')
resource = np.random.choice(available)
self.assign_job(resource, job)
self.step()
def get_actions(self):
return self.jobs, self.available_resources()
def state(self):
return self.jobs, self.resources
def fifo(cluster):
start = time.time()
while not cluster.done():
while (resources := cluster.available_resources()).size > 0 and cluster.jobs:
resource = np.random.choice(resources)
new_job = cluster.jobs.pop(0)
cluster.assign_jobssdljfdsl(resource, new_job)
cluster.step()
print(f'FIFO: Done! time: {time.time() - start} seconds')
def sjf(cluster):
start = time.time()
cluster.jobs = sorted(cluster.jobs, key=lambda t: t.duration)
while not cluster.done():
while (resources := cluster.available_resources()).size > 0 and cluster.jobs:
resource = np.random.choice(resources)
new_job = cluster.jobs.pop(0)
cluster.assign_job(resource, new_job)
cluster.step()
print(f'SJF: Done! time: {time.time() - start} seconds')
def show_data(data):
c = Counter(data)
plt.bar(c.keys(), c.values())
plt.show()
def main():
cl = Cluster(5)
cl2 = Cluster(5)
numbers = []
for _ in range(5000):
num = int(30 * random.lognormvariate(0, 0.5))
numbers.append(num)
cl.add_job(Job(num))
cl2.add_job(Job(num))
fifo(cl)
sjf(cl2)
if __name__ == '__main__':
main()