summaryrefslogtreecommitdiff
path: root/job_scheduling/jobschedule-to-latex.py
blob: 057dc84c92f6b47b67f5ce2f06b68e35a967d684 (plain)
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
#!/usr/bin/env python3
import re
import sys

job_dependencies_ended = {
    3:  (1, 2),
    5:  (3, 4),
    7:  (3, 4, 6),
    9:  (5, 8),
    11: (10,),
    12: (9, 11),
}

job_dependencies_started = {
    8: (5,),
}

# Styling parameter: Sum of these must be smaller than 6, otherwise small
# duration cannot be represented.
leftSize, rightSize = 1, 1
leftSize, rightSize = 0, 0  # set to 0 to disable this feature
# Scale time to dimension
timeScale = .2
# Height of a row
rowSize = .5
# Margin on top and bottom of a row (twice this must be smaller than height)
rowMargin = .1

# Predefined colors from https://en.wikibooks.org/wiki/LaTeX/PGF/TikZ#Color
colors = [
'red',
'green',
'blue',
'cyan',
'magenta',
#'yellow',
#'black',
'gray',
'darkgray',
'lightgray',
'brown',
#'lime',
'olive',
'orange',
'pink',
'purple',
'teal',
'violet',
#'white',
]


# Map of job numbers to their start time and duration
# To be sorted by start time and job number
jobs = {}

for line in sys.stdin:
    line = line.strip()
    if line == "unsat":
        sys.exit('unsat!')
    if line == "sat":
        continue
    m = re.match(r'([dt])(\d+) -> (\d+)', line)
    what = m.group(1)
    jobnr = int(m.group(2))
    # start time if what=='t',
    # duration if what=='d'
    time = int(m.group(3))

    if jobnr not in jobs:
        jobs[jobnr] = [None] * 2
    jobs[jobnr][0 if what == 't' else 1] = time

def job_key_func(item):
    jobnr, (startTime, duration) = item
    # Assume max job nr below large number
    return startTime * 10000 + jobnr


def draw_box(rownr, x1, x2):
    # Tikz draw in Cartesian space
    lastRow = len(jobs)
    y1 = (lastRow - rownr) * rowSize + rowMargin
    y2 = (lastRow - rownr + 1) * rowSize - rowMargin

    attrs = []
    # Add color
    attrs += ["draw=%s" % colors[i]]
    attrs += ["fill=%s" % colors[i]]

    attrs = ','.join(attrs)

    tpl = r"\draw[{attrs}] ({x1}, {y1}) rectangle ({x2}, {y2});"
    print(tpl.format(**vars()))

for i, (jobnr, (startTime, duration)) in enumerate(sorted(jobs.items(), key=job_key_func)):
    line = ""

    # Scale
    startTimeX = startTime * timeScale
    durationX = duration * timeScale

    middleX1 = startTimeX
    if jobnr in job_dependencies_started:
        middleX1 += leftSize

    middleX2 = startTimeX + durationX
    if jobnr in job_dependencies_ended:
        middleX2 -= rightSize

    if middleX1 != startTimeX:
        draw_box(i, startTimeX, middleX1,
                job_dependencies_started[jobnr])
    draw_box(i, middleX1, middleX2)
    if middleX2 != startTimeX + durationX:
        draw_box(i, middleX2, startTimeX + durationX,
                job_dependencies_ended[jobnr])
    tpl = r"\draw[{attrs}] ({x1}, {y1}) rectangle ({x2}, {y2});"

    texty = (len(jobs) - i) * rowSize + .2
    # Print jobnr on the left side
    print(r'\node[anchor=east] at (%f,%f) {%s};' % (-.1, texty, jobnr))
    # Print start and duration on the right side
    print(r'\node[anchor=west] at (%f,%f) {%s};' % (startTimeX + durationX + .1, texty,
        "%d + %d = %d" % (startTime, duration, startTime + duration)))

# Print jobs as follows:
# a bar (width is duration, height is same for all jobs).
#   color is unique
#   y position depends on order (sort by start time, then job number)
# display job number on the side
# display dependencies on the right or:
#   color left side with start dependency
#   color right side with end dependency