Случайное число с заданной вероятностью, какой алгоритм?
Делают длинный диапазон, составленный из отрезков, пропорциональных вероятностям. 0..22 : "0"
22..22+19=41: "1"
41..41+16=57: "2"
...
..100: "8"
Выбор из него с линейной вероятностью даст желаемое распределение.
Например, выпало 56 – попадает в диапазон, относящийся к "2"
Вот склепал на скорую руку:
https://repl.it/K2UJ/2import random 

def getrand():
  r = random.randint(1,100)
  if  r < 23:
    return 0 # 22%
  if 42 > r >= 23:
    return 1 # 19%
  if 58 > r >= 41:
    return 2 # 16%
  if 71 > r >= 57:
    return 3 # 13%
  if 81 > r >=70:
    return 4 # 10%
  if 89 > r >=80:
    return 5 # 8 % 
  if 95 > r >=88:
    return 6 # 6%
  if 99 > r >=94:
    return 7 # 4%
  if 101 > r >=98:
    return 8 # 2 %
result = []
rng = 1000000
for x in range(0,rng):
  result.append(getrand())

print "0 : "+str(result.count(0)/float(rng))+" ~ " +str(0.22 - result.count(0)/float(rng))
print "1 : "+str(result.count(1)/float(rng))+" ~ " +str(0.19 - result.count(1)/float(rng))
print "2 : "+str(result.count(2)/float(rng))+" ~ " +str(0.16 - result.count(2)/float(rng))
print "3 : "+str(result.count(3)/float(rng))+" ~ " +str(0.13 - result.count(3)/float(rng))
print "4 : "+str(result.count(4)/float(rng))+" ~ " +str(0.10 - result.count(4)/float(rng))
print "5 : "+str(result.count(5)/float(rng))+" ~ " +str(0.08 - result.count(5)/float(rng))
print "6 : "+str(result.count(6)/float(rng))+" ~ " +str(0.06 - result.count(6)/float(rng))
print "7 : "+str(result.count(7)/float(rng))+" ~ " +str(0.04 - result.count(7)/float(rng))
print "8 : "+str(result.count(8)/float(rng))+" ~ " +str(0.02 - result.count(8)/float(rng))

freqs = [ result.count(0)/float(rng),result.count(1)/float(rng),result.count(2)/float(rng),result.count(3)/float(rng),
result.count(4)/float(rng),result.count(5)/float(rng),result.count(6)/float(rng),result.count(7)/float(rng),result.count(8)/float(rng)]

print sum(freqs)0 : 0.219347 ~ 0.000653
1 : 0.190018 ~ -1.8e-05
2 : 0.160421 ~ -0.000421
3 : 0.129805 ~ 0.000195
4 : 0.100175 ~ -0.000175
5 : 0.07974 ~ 0.00026
6 : 0.060102 ~ -0.000102
7 : 0.040174 ~ -0.000174
8 : 0.020218 ~ -0.000218
1.0