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
|
from __future__ import division
import random
def uniform_int(minval, maxval):
"Create a function that draws ints uniformly from {minval, ..., maxval}"
def _draw():
return random.randint(minval, maxval)
return _draw
def uniform(minval, maxval):
"Create a function that draws floats uniformly from [minval, maxval]"
def _draw():
return random.uniform(minval, maxval)
return _draw
def bernoulli(p):
"Create a function that flips a weight coin with probability p"
def _draw():
return random.random() < p
return _draw
def uniform_choice(choices):
"Create a function that draws uniformly elements from choices"
selector = uniform_int(0, len(choices) - 1)
def _draw():
return choices[selector()]
return _draw
def truncate(minval, maxval):
def _limit(fun):
def _f(*args, **kargs):
val = fun(*args, **kargs)
return min(maxval, max(minval, val))
return _f
return _limit
def redraw(minval, maxval):
def _redraw(dist):
def _f(*args, **kargs):
in_range = False
while not in_range:
val = dist(*args, **kargs)
in_range = minval <= val <= maxval
return val
return _f
return _redraw
def exponential(minval, maxval, mean, limiter=redraw):
"""Create a function that draws floats from an exponential
distribution with expected value 'mean'. If a drawn value is less
than minval or greater than maxval, then either another value is
drawn (if limiter=redraw) or the drawn value is set to minval or
maxval (if limiter=truncate)."""
def _draw():
return random.expovariate(1.0 / mean)
return limiter(minval, maxval)(_draw)
def multimodal(weighted_distributions):
"""Create a function that draws values from several distributions
with probability according to the given weights in a list of
(distribution, weight) pairs."""
total_weight = sum([w for (d, w) in weighted_distributions])
selector = uniform(0, total_weight)
def _draw():
x = selector()
wsum = 0
for (d, w) in weighted_distributions:
wsum += w
if wsum >= x:
return d()
assert False # should never drop off
return _draw
def uniform_slack(min_slack_ratio, max_slack_ratio):
"""Choose deadlines uniformly such that the slack
is within [cost + min_slack_ratio * (period - cost),
cost + max_slack_ratio * (period - cost)].
Setting max_slack_ratio = 1 implies constrained deadlines.
"""
def choose_deadline(cost, period):
slack = period - cost
earliest = slack * min_slack_ratio
latest = slack * max_slack_ratio
return cost + random.uniform(earliest, latest)
return choose_deadline
|