Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- S = 32767
- def f(h):
- total = sum(h)
- n = len(h)
- p = [ x / float(total) for x in h ]
- o = [ +max(x > 0, int(round(x * S))) for x in p ]
- errs = lambda: [ o[i] - S*p[i] for i in range(n) ]
- err = errs()
- xs = S - sum(o)
- def isorted(minv, rev):
- ii = [ i for i in range(n) if o[i] > minv ]
- ii.sort(key=lambda i: err[i], reverse=rev)
- return ii
- if xs >= 0:
- ei = isorted(0, False)
- for i in ei:
- if xs == 0 or err[i] >= 1: break
- xs -= 1
- o[i] += 1
- err = errs()
- nz = n - o.count(0)
- addall = xs / nz
- o = [ x and x + addall for x in o ]
- xs -= addall * nz
- for i in isorted(0, False)[:xs]: o[i] += 1
- else:
- xs = -xs
- while 1:
- not01 = n - o.count(0) - o.count(1)
- if xs < not01 or xs < 1: break
- addall = xs / nz
- o = [ x and max(x - addall, 1) for x in o ]
- xs = sum(o) - S
- for x in isorted(1, True)[:xs]:
- o[x] -= 1
- return o
- def maketests():
- import random
- random.seed(0)
- t = []
- for _ in range(100):
- l = 1 + min(int(random.expovariate(1/100.)), 1000)
- t.append([int(random.expovariate(1/10.)) for _ in range(l)])
- return t
- def score(hist, prob):
- return sum((p/float(0x7fff) - float(h)/sum(hist))**2 for h, p in zip(hist, prob))
- print '%.17g' % sum(score(t, f(t)) for t in maketests())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement