Как мне сгенерировать гистограмму для заданного распределения вероятностей (для функционального тестирования сервера)?

StackOverflow https://stackoverflow.com/questions/53786

Вопрос

Я пытаюсь автоматизировать функциональное тестирование сервера, используя реалистичное частотное распределение запросов.(своего рода нагрузочное тестирование, своего рода симуляция)

Я выбрал то, что Вейбулл распределение, поскольку оно "вроде" соответствует распределению, которое я наблюдал (быстро увеличивается, быстро падает, но не мгновенно)

Я использую этот дистрибутив для генерации количества запросов, которые должны быть отправлены каждый день между заданной начальной и конечной датой

Я взломал алгоритм на Python, который вроде как работает, но он кажется запутанным:

how_many_days = (end_date - start_date).days
freqs = defaultdict(int)
for x in xrange(how_many_responses):
    freqs[int(how_many_days * weibullvariate(0.5, 2))] += 1
timeline = []
day = start_date
for i,freq in sorted(freqs.iteritems()):
    timeline.append((day, freq))
    day += timedelta(days=1)
return timeline

Какие есть лучшие способы сделать это?

Это было полезно?

Решение

Это быстро и, вероятно, не настолько точно, но если вы рассчитаете PDF-файл самостоятельно, то, по крайней мере, вам будет проще разместить несколько файлов меньшего / большего размера на одной временной шкале. dev это стандартное отклонение гуассианского шума, которое контролирует шероховатость.Обратите внимание, что это нет "правильный" способ сгенерировать то, что вы хотите, но это просто.

import math
from datetime import datetime, timedelta, date
from random import gauss

how_many_responses = 1000
start_date = date(2008, 5, 1)
end_date = date(2008, 6, 1)
num_days = (end_date - start_date).days + 1
timeline = [start_date + timedelta(i) for i in xrange(num_days)]

def weibull(x, k, l):
    return (k / l) * (x / l)**(k-1) * math.e**(-(x/l)**k)

dev = 0.1
samples = [i * 1.25/(num_days-1) for i in range(num_days)]
probs = [weibull(i, 2, 0.5) for i in samples]
noise = [gauss(0, dev) for i in samples]
simdata = [max(0., e + n) for (e, n) in zip(probs, noise)]
events = [int(p * (how_many_responses / sum(probs))) for p in simdata]

histogram = zip(timeline, events)

print '\n'.join((d.strftime('%Y-%m-%d ') + "*" * c) for d,c in histogram)

Другие советы

Почему бы тебе не попробовать Мясорубка 3 чтобы протестировать ваш сервер под нагрузкой, он поставляется со всем этим и многим другим готовым, а также поддерживает python в качестве языка сценариев

Немного более длинная, но, вероятно, более читаемая переработка ваших последних четырех строк:

samples = [0 for i in xrange(how_many_days + 1)]
for s in xrange(how_many_responses):
    samples[min(int(how_many_days * weibullvariate(0.5, 2)), how_many_days)] += 1
histogram = zip(timeline, samples)
print '\n'.join((d.strftime('%Y-%m-%d ') + "*" * c) for d,c in histogram)

При этом выборки всегда отбрасываются в пределах диапазона дат, но вы получаете соответствующий скачок в конце временной шкалы для всех выборок, которые находятся выше диапазона [0, 1].

Вместо того чтобы указывать количество запросов как фиксированное значение, почему бы вместо этого не использовать коэффициент масштабирования?На данный момент вы рассматриваете запросы как ограниченное количество и рандомизируете дни, на которые приходятся эти запросы.Казалось бы, более разумно рассматривать ваши запросы в день как независимые.

from datetime import *
from random import *

timeline = []
scaling = 10
start_date = date(2008, 5, 1)
end_date = date(2008, 6, 1)

num_days = (end_date - start_date).days + 1
days = [start_date + timedelta(i) for i in range(num_days)]
requests = [int(scaling * weibullvariate(0.5, 2)) for i in range(num_days)]
timeline = zip(days, requests)
timeline

Я переписал приведенный выше код, чтобы он был короче (но, может быть, сейчас он слишком запутан?).

timeline = (start_date + timedelta(days=days) for days in count(0))
how_many_days = (end_date - start_date).days
pick_a_day = lambda _:int(how_many_days * weibullvariate(0.5, 2))
days = sorted(imap(pick_a_day, xrange(how_many_responses)))
histogram = zip(timeline, (len(list(responses)) for day, responses in groupby(days)))
print '\n'.join((d.strftime('%Y-%m-%d ') + "*" * c) for d,c in histogram)

Другим решением является использование Rpy, который легко переносит всю мощь R (включая множество инструментов для дистрибутивов) в Python.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top