2008-09-10 19 views
3

Bir sunucunun işlevlerini gerçekçi bir frekans dağılımı kullanarak otomatik olarak test etmeye çalışıyorum. o "tür" (hızlı rampaları anında hızlı ama düştüğü) Gözlemlediğim dağılımını maçlarıBelirli bir olasılık dağılımı için nasıl bir histogram oluştururum (bir sunucuda işlev testi yapmak için)?

olarak (yük testi çeşit, simülasyon sıralama)

Ben Weibull dağılımını seçtiniz

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 
: Ben Python bir algoritmasını birlikte işlerin bu tür kesmek ettik ama kludgy hissediyor

belirlenmiş başlangıç ​​ve bitiş tarihi arasındaki her gün gönderilmesi gerekmektedir istek sayısını üretmek için bu dağılımı kullanın

Bunu yapmak için daha iyi yollar var mı? ,

+0

Bu algoritma beklenen yanıt sayısını her zaman döndürür, ancak genellikle başlangıç ​​ve bitiş tarihleri ​​arasında tam olarak uymaz, bu frekansları elle karıştırmazsam bunun mümkün olmadığından emin değilim? –

+0

Başlangıç ​​ve bitiş tarihleri ​​arasında sınırsız destek ile bir olasılık dağılımı kullandığınızdan emin değilsiniz. Bir anahtar olarak değişmeden dağıtılan rastgele sayıyı kullandığınız sürece, bu soruna sahip olacaksınız. – Kai

cevap

1

Bu hızlı ve büyük olasılıkla doğru değildir, ancak PDF'yi kendiniz hesaplarsanız, en azından birkaç küçük/büyük olanı tek bir zaman çizelgesine yerleştirmeyi kolaylaştırırsınız. dev, pürüzlülüğü kontrol eden Guassian gürültüsündeki std sapmasıdır. İstediğinizi oluşturmak için bu değil 'doğru' yol olduğunu unutmayın, ama bu kolaydır.

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) 
+0

Büyük dağıtım simülasyon yoluyla oluşturulan çok daha iyi görünüyor. –

1

Neden bunu tüm bunları ve daha önceden oluşturulmuş ile gelir, sizin sunucu test yüklemeye The Grinder 3 kalkma ve bir betik dili yerine sabit bir değer olarak isteklerinin sayısını vermenin

+0

Maalesef, bu işlev bazı fonksiyonel testlerde de kullanılacaktır, bu yüzden hepsini mümkün olduğunca ailede tutmayı çok isterim. Belki de simülasyon, yük testinden daha iyi bir tanımdır –

0

olarak piton destekler Neden bunun yerine bir ölçekleme faktörü kullanmıyorsunuz? Şu anda, istekleri sınırlı bir miktar olarak ele alıyorsunuz ve bu isteklerin reddedildiği günleri rastgele yapıyorsunuz. Günlük taleplerinizi bağımsız olarak ele almak daha mantıklı görünebilir.

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 
+0

Bu işlev, aradığım şekli üretmiyor gibi görünüyor.Eğer wikipedia makalesini kontrol ederseniz, hızlıca yükselen ve daha sonra başlangıçta yüksek olan sayfa görüntülerini modellediği göründüğü gibi zamanla izleyen kırmızı eğriyi seçtim, ancak insanlar zaman içinde yeni içeriğe olan ilgilerini kaybeder. –

+0

Aslında bütün nokta (benim perspektifimden :-), isteklerin sayısının güne bağlı olması. Sadece bir süre boyunca rastgele yükleri modellemeye çalışmıyorum. –

+0

Tamam, ama şimdi yaptığınız şey sadece dağıtıma yaklaşıyor. Neden dağıtımın kendisi ya da dağıtım artı bir miktar gürültü kullanmıyorsunuz? Bu nedenle, geçmişi olmayan bir geçmişe dayalı süreç modellemektasınız. – Kai

0

ben kısa olması yukarıdaki kodu yeniden yazdı (ama belki de artık gizleme?) Biraz daha uzun

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) 
+0

Bahsi işlev için ithalat vardır: tarih saat alma datetime itertools rasgele içe weibullvariate gelen timedelta den IMAP, GroupBy, how_many_responses = 100 başlangıç_tarihi = tarihi sayısı (2008, 5, 1) end_date = tarihi içe (2008, 6, 1) –

1

ancak son dört hatlarının muhtemelen daha okunabilir rework:

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) 

Bu, örnekleri her zaman tarih aralığı içinde bırakır, ancak [0, 1] aralığının üzerindeki tüm örneklerden zaman çizelgesinin sonunda karşılık gelen bir çarpma elde edersiniz.

+0

Güzel, beğendim. Her zaman yineleyici şeyler şeyler denemek, ama bu okumak için kesinlikle daha kolay :-) –

0

Başka bir çözüm Pythonda kolayca tüm (dağılımlar için araçları çok dahil) R gücünün koyar Rpy, kullanmaktır.

İlgili konular