-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlpt.py
More file actions
executable file
·72 lines (58 loc) · 2.31 KB
/
lpt.py
File metadata and controls
executable file
·72 lines (58 loc) · 2.31 KB
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
#!/usr/bin/env python3
"""Longest Processing Time (LPT) algorithm for makespan minimization."""
import argparse
from collections.abc import Generator, Iterable, Sequence
from typing import NamedTuple
from code2dtree import Expr, genFunc2dtree, getVarList
from code2dtree.nodeIO import printTree, PrintOptions, PrintStatus, saveTree, SAVE_FORMATS
from code2dtree.linExpr import LinConstrTreeExplorer
from code2dtree.types import Real
def argmin(x: Sequence[Real | Expr]) -> int:
"""Largest index of minimum value in non-empty list."""
n = len(x)
minIndex, minValue = 0, x[0]
for i in range(1, n):
if x[i] <= minValue:
minIndex, minValue = i, x[i]
return minIndex
class AssnEvent(NamedTuple):
job: int
machine: int
def greedy(x: Iterable[Real | Expr], m: int) -> Generator[AssnEvent, None, Sequence[int]]:
"""Jobs have sizes x. There are m machines."""
assn = []
jobGen = iter(x)
loads = []
for j, xj in zip(range(m), jobGen):
yield AssnEvent(job=j, machine=j)
assn.append(j)
loads.append(xj)
for j, xj in enumerate(jobGen, m):
i = argmin(loads)
yield AssnEvent(job=j, machine=i)
assn.append(i)
loads[i] += xj
return assn
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('n', type=int, help='number of jobs')
parser.add_argument('m', type=int, help='number of machines')
formats = ', '.join(SAVE_FORMATS)
parser.add_argument('-o', '--output', help=f'path to output file (formats: {formats})')
parser.add_argument('--lineNo', action='store_true', default=False,
help='display line numbers')
args = parser.parse_args()
print('n={n} jobs, m={m} machines'.format(n=args.n, m=args.m))
x = getVarList('x', args.n, style='simple')
te = LinConstrTreeExplorer([x[i-1] >= x[i] for i in range(1, args.n)])
dtree = genFunc2dtree(greedy, (x, args.m), te)
if args.output is not None:
saveTree(dtree, args.output)
else:
lineNoCols = 4 if args.lineNo else 0
options = PrintOptions(lineNoCols=lineNoCols)
status = PrintStatus()
printTree(dtree, options, status)
print(f'\nnodes: {status.nodes}, leaves: {status.leaves}, lines={status.lines}')
if __name__ == '__main__':
main()