Comments (4)
Dear @amm266 thank you for the question. I think this is possible by creating custom distribution objects. For example, say service times should usually follow an Exponential distribution with rate 6, but there is a certain probability `error_prob' of the service erroring and finishing halfway through. This could be modelled as:
class ErroredService(ciw.dists.Distribution):
def __init__(self, rate, error_prob):
self.rate = rate
self.error_prob = error_prob
def sample(self, t, ind):
full_service_time = random.expovariate(self.rate)
rnd = random.random()
if rnd < self.error_prob:
return full_service_time * 0.5
return full_service_time
Now let's see how the error_prob
affects the mean service time:
>>> N1 = ciw.create_network(
... arrival_distributions=[ciw.dists.Exponential(rate=5)],
... service_distributions=[ErroredService(rate=6, error_prob=0.1)],
... number_of_servers=[1]
... )
>>> ciw.seed(0)
>>> Q = ciw.Simulation(N1)
>>> Q.simulate_until_max_time(500)
>>> recs = Q.get_all_records()
>>> service_times = [r.service_time for r in recs]
>>> sum(service_times) / len(service_times)
0.16053608937056327
compared to a higher error rate:
>>> N2 = ciw.create_network(
... arrival_distributions=[ciw.dists.Exponential(rate=5)],
... service_distributions=[ErroredService(rate=6, error_prob=0.9)],
... number_of_servers=[1]
... )
>>> ciw.seed(0)
>>> Q = ciw.Simulation(N2)
>>> Q.simulate_until_max_time(500)
>>> recs = Q.get_all_records()
>>> service_times = [r.service_time for r in recs]
>>> sum(service_times) / len(service_times)
0.09299399922270359
from ciw.
However this doesn't record whether the service errored or not, just affects the service time. If you also want to record this, you will have to make use of custom Node and DataRecord objects.
This assigns a Boolean attribute errored
to the individual:
class ErroredService(ciw.dists.Distribution):
def __init__(self, rate, error_prob):
self.rate = rate
self.error_prob = error_prob
def sample(self, t, ind):
full_service_time = random.expovariate(self.rate)
rnd = random.random()
if rnd < self.error_prob:
ind.errored = True
return full_service_time * 0.5
ind.errored = False
return full_service_time
This creates a custom DataRecord object that has the errored_service
field:
from collections import namedtuple
ErroredDataRecord = namedtuple('Record', [
'id_number',
'customer_class',
'original_customer_class',
'node',
'arrival_date',
'waiting_time',
'service_start_date',
'service_time',
'errored_service',
'service_end_date',
'time_blocked',
'exit_date',
'destination',
'queue_size_at_arrival',
'queue_size_at_departure',
'server_id',
'record_type'
])
And this creates a custom Node object that gives that DataRecord the relevant data:
import math
class ErroredNode(ciw.Node):
def write_individual_record(self, individual):
if math.isinf(self.c):
server_id = False
else:
server_id = individual.server.id_number
record = ErroredDataRecord(
individual.id_number,
individual.previous_class,
individual.original_class,
self.id_number,
individual.arrival_date,
individual.service_start_date - individual.arrival_date,
individual.service_start_date,
individual.service_end_date - individual.service_start_date,
individual.errored,
individual.service_end_date,
individual.exit_date - individual.service_end_date,
individual.exit_date,
individual.destination,
individual.queue_size_at_arrival,
individual.queue_size_at_departure,
server_id,
'service')
individual.data_records.append(record)
Now we can count the number of errored services. As before let's compare a large and small error_prob
:
>>> N1 = ciw.create_network(
... arrival_distributions=[ciw.dists.Exponential(rate=5)],
... service_distributions=[ErroredService(rate=6, error_prob=0.1)],
... number_of_servers=[1]
... )
>>> ciw.seed(0)
>>> Q = ciw.Simulation(N1, node_class=ErroredNode)
>>> Q.simulate_until_max_time(500)
>>> recs = Q.get_all_records()
>>> errored_serviced = [r.errored_service for r in recs]
>>> sum(errored_serviced) / len(errored_serviced)
0.10408326661329063
as expected. And with a higher error probability:
>>> N2 = ciw.create_network(
... arrival_distributions=[ciw.dists.Exponential(rate=5)],
... service_distributions=[ErroredService(rate=6, error_prob=0.9)],
... number_of_servers=[1]
... )
>>> ciw.seed(0)
>>> Q = ciw.Simulation(N2, node_class=ErroredNode)
>>> Q.simulate_until_max_time(500)
>>> recs = Q.get_all_records()
>>> errored_serviced = [r.errored_service for r in recs]
>>> sum(errored_serviced) / len(errored_serviced)
0.9032128514056225
from ciw.
@amm266 Let me know if this helps at all :)
from ciw.
thanks a lot @geraintpalmer!
it helps me so much.
if you want to add this feature for future releases, contact me so I can help you develop it.
from ciw.
Related Issues (20)
- can Ciw set a state-dependent system capacity allocation for simulation? HOT 3
- Wishlist for Ciw 3.0 HOT 9
- re-entrance customer with dynamic priority HOT 6
- Emulate Simpy's Machine Shop example HOT 5
- Type Annotations HOT 1
- Black Code Formatter HOT 1
- Recommended practices for model configuration storage HOT 1
- How to implement class-selective servers?
- [Question]: What happens when service discipline returns None? HOT 1
- Slotted undocumented HOT 2
- [Feature Request] Failure to start service HOT 2
- [FYI] Are there other types of blocking in queueing networks beyond Type I? HOT 1
- [Feature Request] Time/State-Dependent Baulking HOT 3
- [Media Request] Wikipedia Article HOT 3
- [FYI] Wikipedia Article Draft
- [FYI] Ciw examples of Wikipedia Articles HOT 1
- [Feature Request] Service linger time and batch serving HOT 3
- Consider getting open peer review of package by pyOpenSci HOT 2
- NumPy 2.0 Migration
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ciw.