Sut i Osod Dosraniadau Dyfodi a Gwasanaeth¶
Mae Ciw yn cynnig amrywiaeth o ddosraniadau amser rhwng-dyfodiad a gwasanaeth.
Ffeindiwch restr lawn fan hyn.
Gwrthrychau ydynt, a ddiffinnir yn y gwrthrych Network gyda'r allweddeiriau 'arrival_distributions'
a 'service_distributions'
.
'Arrival_distributions'
: Dyma'r dosraniad a samplwyd amseroedd rhwng-dyfodiad. Hynny yw yr amser rhwng dau ddyfodiad olynol. Mae'n benodol ar gyfer nodau a dosbarthau cwsmer spesifig.'Service_distributions'
: Dyma'r dosraniad a samplwyd amseroedd gwasanaeth. Hynny yw faint o amser mae cwsmer yn gwario gyda gweinydd (yn annibynnol o faint o weinyddion sydd yno). Mae'n benodol ar gyfer nodau a dosbarthau cwsmer spesifig.
Mae'r enghraifft ganlynol, gyda dau nod a dau ddosbarth cwsmer, y defnyddio wyth gwahanol ddosraniad dyfodi a gwasanaeth:
>>> import ciw
>>> N = ciw.create_network(
... arrival_distributions={'Class 0': [ciw.dists.Deterministic(0.4),
... ciw.dists.Empirical([0.1, 0.1, 0.1, 0.2])],
... 'Class 1': [ciw.dists.Deterministic(0.2),
... ciw.dists.Pmf([0.2, 0.4], [0.5, 0.5])]},
... service_distributions={'Class 0': [ciw.dists.Exponential(6.0),
... ciw.dists.Lognormal(-1, 0.5)],
... 'Class 1': [ciw.dists.Uniform(0.1, 0.7),
... ciw.dists.Triangular(0.2, 0.3, 0.7)]},
... routing={'Class 0': [[0.0, 0.0], [0.0, 0.0]],
... 'Class 1': [[0.0, 0.0], [0.0, 0.0]]},
... number_of_servers=[1, 1]
... )
Rhedwn hwn (gyda rhifyddeg union) am 25 uned amser:
>>> ciw.seed(10)
>>> Q = ciw.Simulation(N, exact=10)
>>> Q.simulate_until_max_time(50)
>>> recs = Q.get_all_records()
Mae'r system yn defnyddio'r wyth dosraniad canlynol:
ciw.dists.Deterministic(0.4)
:Samplu 0.4 pob amser.
ciw.dists.Deterministic(0.2)
:Samplu 0.2 pob amser.
ciw.dists.Empirical([0.1, 0.1, 0.1, 0.2])
:Samplu'r rhifau 0.1, 0.1, 0.1 a 0.2 ar hap.
ciw.dists.Pmf([0.2, 0.4], [0.5, 0.5])
:Samplu 0.2 hanner yr amser, a 0.4 hanner yr amser.
ciw.dists.Exponential(6.0)
:Samplu o'r dosraniad esbonyddol gyda paramedr \(\lambda = 6.0\). Cymedr disgwyliedig o 0.1666...
ciw.dists.Uniform(0.1, 0.7)
:Samplu unrhyw rhif rhwng 0.1 a 0.7 gyda tebygolrwydd hafal. Cymedr disgwyliedig o 0.4.
ciw.dists.Lognormal(-1, 0.5)
:Samplu o;r dosraniad lognormal gyda paramedrau \(\mu = -1\) a \(\sigma = 0.5\). Cymedr disgwyliedig o 0.4724...
ciw.dists.Triangular(0.2, 0.3, 0.7)
:Samplu o'r dosraniad trionglog gyda modd 0.3, terfyn isaf 0.2 a terfyn uchaf 0.7. Cymedr disgwyliedig o 0.4.
O'r holl gofnodion data, casglwch yr amseroedd gwasanaeth a'r dyddiadau dyfodi ar gyfer pob nod a pob dosbarth cwsmer:
>>> servicetimes_n1c0 = [r.service_time for r in recs if r.node==1 and r.customer_class==0]
>>> servicetimes_n2c0 = [r.service_time for r in recs if r.node==2 and r.customer_class==0]
>>> servicetimes_n1c1 = [r.service_time for r in recs if r.node==1 and r.customer_class==1]
>>> servicetimes_n2c1 = [r.service_time for r in recs if r.node==2 and r.customer_class==1]
>>> arrivals_n1c0 = sorted([r.arrival_date for r in recs if r.node==1 and r.customer_class==0])
>>> arrivals_n2c0 = sorted([r.arrival_date for r in recs if r.node==2 and r.customer_class==0])
>>> arrivals_n1c1 = sorted([r.arrival_date for r in recs if r.node==1 and r.customer_class==1])
>>> arrivals_n2c1 = sorted([r.arrival_date for r in recs if r.node==2 and r.customer_class==1])
Nawr gwelwn os yw'r amser gwasanaeth ac amser rhwng dyfodiad cymedrig yn cyfateb a'r dosraniadau:
>>> from decimal import Decimal
>>> sum(servicetimes_n1c0) / len(servicetimes_n1c0) # Disgwyl 0.1666...
Decimal('0.1600313200')
>>> sum(servicetimes_n2c0) / len(servicetimes_n2c0) # Disgwyl 0.4724...
Decimal('0.4250531396')
>>> sum(servicetimes_n1c1) / len(servicetimes_n1c1) # Disgwyl 0.4
Decimal('0.4108660556')
>>> sum(servicetimes_n2c1) / len(servicetimes_n2c1) # Disgwyl 0.4
Decimal('0.3942034906')
>>> set([r2-r1 for r1, r2 in zip(arrivals_n1c0, arrivals_n1c0[1:])]) # Dylai ond samplu 0.4
{Decimal('0.4')}
>>> set([r2-r1 for r1, r2 in zip(arrivals_n1c1, arrivals_n1c1[1:])]) # Dylai ond samplu 0.2
{Decimal('0.2')}
>>> expected_samples = {Decimal('0.2'), Decimal('0.1')} # Dylai ond samplu 0.1 a 0.2
>>> set([r2-r1 for r1, r2 in zip(arrivals_n2c0, arrivals_n2c0[1:])]) == expected_samples
True
>>> expected_samples = {Decimal('0.2'), Decimal('0.4')}# Dylai ond samplu 0.2 a 0.4
>>> set([r2-r1 for r1, r2 in zip(arrivals_n2c1, arrivals_n2c1[1:])]) == expected_samples
True
Dosraniadau eich hun¶
Diffinir dosraniad trwy etifeddu o'r dosbarth cyffredinol ciw.dists.Distribution
.
Mae hwn yn galluogi defnyddwyr i diffinio'u dosraniadau ei hunain.
Ystyriwch dosraniad sy'n samplu'r gwerth 3.0 50% o'r amser, ac yn samplu haprif unffurf rhwng 0 ac 1 fel arall. Gallwn ysgrifennu hwn trwy etifeddu o'r dosbarth cyffredinol, a diffinio dull sample
newydd:
>>> import random
>>> class CustomDistribution(ciw.dists.Distribution):
... def sample(self, t=None, ind=None):
... if random.random() < 0.5:
... return 3.0
... return random.random()
Gal rhoi hwn i mewn i'r gwrthrych Network
yn y ffordd arferol.
Dosraniadau Cyfunedig¶
Gan fod gwrthrychau dosraniad yn edifeddu o'r dosbarth dosraniad cyffredinol, gall cael eu cyfuno trwy defnyddio'r gweithrediadau +
, -
, *
, ac /
.
Er enghraifft, gadewch i ni cyfuno dosraniad Esbonyddol a dosraniad Deterministig ym mhob un o'r pedwar ffordd:
>>> Exp_add_Det = ciw.dists.Exponential(0.05) + ciw.dists.Deterministic(3.0)
>>> Exp_sub_Det = ciw.dists.Exponential(0.05) - ciw.dists.Deterministic(3.0)
>>> Exp_mul_Det = ciw.dists.Exponential(0.05) * ciw.dists.Deterministic(3.0)
>>> Exp_div_Det = ciw.dists.Exponential(0.05) / ciw.dists.Deterministic(3.0)
Mae'r dosraniadau cyfunedig hyn yn rhoi'r cyfuniad o'r gwerthoedd a samplwyd:
>>> ciw.seed(10)
>>> [round(ciw.dists.Exponential(0.05).sample(), 2) for _ in range(5)]
[16.94, 11.2, 17.26, 4.62, 33.57]
>>> [round(ciw.dists.Deterministic(3.0).sample(), 2) for _ in range(5)]
[3.0, 3.0, 3.0, 3.0, 3.0]
>>> # Adio
>>> ciw.seed(10)
>>> [round(Exp_add_Det.sample(), 2) for _ in range(5)]
[19.94, 14.2, 20.26, 7.62, 36.57]
>>> # Tynnu
>>> ciw.seed(10)
>>> [round(Exp_sub_Det.sample(), 2) for _ in range(5)]
[13.94, 8.2, 14.26, 1.62, 30.57]
>>> # Lluosi
>>> ciw.seed(10)
>>> [round(Exp_mul_Det.sample(), 2) for _ in range(5)]
[50.83, 33.61, 51.78, 13.85, 100.7]
>>> # Rhannu
>>> ciw.seed(10)
>>> [round(Exp_div_Det.sample(), 2) for _ in range(5)]
[5.65, 3.73, 5.75, 1.54, 11.19]