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
|