Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
*egg-info*
.coverage
dist/
.hypothesis/eval_source/
.hypothesis/eval_source/
env/
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed .hypothesis/examples/a40d01c034da88b1/2e2eb4e0cdda39fc
Binary file not shown.
Binary file removed .hypothesis/examples/a40d01c034da88b1/2e9ed3030f598578
Binary file not shown.
Binary file removed .hypothesis/examples/a40d01c034da88b1/34851b91dcc435e8
Binary file not shown.
Binary file removed .hypothesis/examples/a40d01c034da88b1/54dc9704d01f52f8
Binary file not shown.
Binary file removed .hypothesis/examples/a40d01c034da88b1/69b51db2bf396d2d
Binary file not shown.
Binary file removed .hypothesis/examples/a40d01c034da88b1/806aa91ff03b9614
Binary file not shown.
Binary file removed .hypothesis/examples/a40d01c034da88b1/81ff1af3986f05e3
Binary file not shown.
Binary file removed .hypothesis/examples/a40d01c034da88b1/914fb471553aee33
Binary file not shown.
Binary file removed .hypothesis/examples/a40d01c034da88b1/a64bc761fe725749
Binary file not shown.
Binary file removed .hypothesis/examples/a40d01c034da88b1/b31fd3df4e01ab57
Binary file not shown.
Binary file removed .hypothesis/examples/a40d01c034da88b1/bbeb7cff16c47d4c
Binary file not shown.
Binary file removed .hypothesis/examples/a40d01c034da88b1/c0d6248587c66f7b
Binary file not shown.
Binary file removed .hypothesis/examples/a40d01c034da88b1/fd59b88514f719b7
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added .hypothesis/unicodedata/8.0.0/charmap.pickle.gz
Binary file not shown.
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
language: python
python:
- 2.7
- 3.4
- 3.5
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could also run py3.4? No need but no harm to actively test the two latest py3s.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep I'll add it. everything still failing atm anyway (doctests i think though)

install:
- pip install -r requirements.txt
- python setup.py develop
- pip install coveralls
script:
- python doctests.py
- coverage run --source=ciw -m unittest discover ciw
after_success: coveralls
after_success: coveralls
26 changes: 14 additions & 12 deletions ciw/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
from simulation import Simulation
from data_record import DataRecord
from server import Server
from individual import Individual
from arrival_node import ArrivalNode
from exit_node import ExitNode
from node import Node
from state_tracker import *
from exactnode import *
from import_params import *
from network import *
from __future__ import absolute_import

__version__ = '0.1.1'
from .simulation import Simulation
from .data_record import DataRecord
from .server import Server
from .individual import Individual
from .arrival_node import ArrivalNode
from .exit_node import ExitNode
from .node import Node
from .state_tracker import *
from .exactnode import *
from .import_params import *
from .network import *

__version__ = '0.1.0'
3 changes: 2 additions & 1 deletion ciw/arrival_node.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from __future__ import division
from individual import Individual
from .individual import Individual


class ArrivalNode(object):
Expand Down Expand Up @@ -34,6 +34,7 @@ def find_next_event_date(self):
times = [[self.event_dates_dict[nd+1][cls]
for cls in range(len(self.event_dates_dict[1]))]
for nd in range(len(self.event_dates_dict))]

mintimes = [min(obs) for obs in times]
nd = mintimes.index(min(mintimes))
cls = times[nd].index(min(times[nd]))
Expand Down
2 changes: 1 addition & 1 deletion ciw/deadlock_detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def initialise_at_node(self, node):
Initialises the state digraph when the node is created.
Adds the servers of that node if c < Inf.
"""
if node.c < 'Inf':
if node.c < float('Inf'):
self.statedigraph.add_nodes_from([str(s)for s in node.servers])

def detect_deadlock(self):
Expand Down
4 changes: 2 additions & 2 deletions ciw/exactnode.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from node import Node
from arrival_node import ArrivalNode
from .node import Node
from .arrival_node import ArrivalNode
from decimal import Decimal, getcontext

class ExactNode(Node):
Expand Down
6 changes: 3 additions & 3 deletions ciw/exit_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ def __init__(self):
"""
self.individuals = []
self.id_number = -1
self.next_event_date = "Inf"
self.node_capacity = "Inf"
self.next_event_date = float("Inf")
self.node_capacity = float("Inf")

def __repr__(self):
"""
Expand All @@ -31,4 +31,4 @@ def update_next_event_date(self):
Just passes as next_event_date always set to
the max_simulation_time
"""
pass
pass
23 changes: 13 additions & 10 deletions ciw/import_params.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import os
import yaml
import copy
from network import *
from .network import *


def create_network(params):
Expand Down Expand Up @@ -47,31 +47,34 @@ def create_network_from_dictionary(params_input):
validify_dictionary(params)
# Then make the Network object
arrivals = [params['Arrival_distributions']['Class ' + str(cls)]
for cls in xrange(len(params['Arrival_distributions']))]
for cls in range(len(params['Arrival_distributions']))]
services = [params['Service_distributions']['Class ' + str(cls)]
for cls in xrange(len(params['Service_distributions']))]
for cls in range(len(params['Service_distributions']))]
transitions = [params['Transition_matrices']['Class ' + str(cls)]
for cls in xrange(len(params['Transition_matrices']))]
for cls in range(len(params['Transition_matrices']))]
number_of_classes = params['Number_of_classes']
number_of_nodes = params['Number_of_nodes']
queueing_capacities = params['Queue_capacities']
queueing_capacities = [float(i) if i == "Inf" else i for i in params['Queue_capacities']]
class_change_matrices = params.get('Class_change_matrices',
{'Node ' + str(nd + 1): None for nd in xrange(number_of_nodes)})
{'Node ' + str(nd + 1): None for nd in range(number_of_nodes)})
number_of_servers, schedules, nodes, classes = [], [], [], []
for c in params['Number_of_servers']:
if isinstance(c, str) and c != 'Inf':
number_of_servers.append('schedule')
schedules.append(params[c])
elif c == 'Inf':
number_of_servers.append(float(c))
schedules.append(None)
else:
number_of_servers.append(c)
schedules.append(None)
for nd in xrange(number_of_nodes):
for nd in range(number_of_nodes):
nodes.append(ServiceCentre(
number_of_servers[nd],
queueing_capacities[nd],
class_change_matrices['Node ' + str(nd + 1)],
schedules[nd]))
for cls in xrange(number_of_classes):
for cls in range(number_of_classes):
classes.append(CustomerClass(
arrivals[cls],
services[cls],
Expand Down Expand Up @@ -99,7 +102,7 @@ def fill_out_dictionary(params_input):
'Name': 'Simulation',
'Number_of_nodes': len(params['Number_of_servers']),
'Number_of_classes': len(params['Arrival_distributions']),
'Queue_capacities': ['Inf' for _ in xrange(len(
'Queue_capacities': ['Inf' for _ in range(len(
params['Number_of_servers']))],
}

Expand Down Expand Up @@ -132,7 +135,7 @@ def validify_dictionary(params):
len(obs) for obs in params['Arrival_distributions'].values()] + [
len(obs) for obs in params['Service_distributions'].values()] + [
len(obs) for obs in params['Transition_matrices'].values()] + [
len(row) for row in obs for obs in params['Transition_matrices'].values()] + [
len(row) for row in [obs for obs in params['Transition_matrices'].values()][0]] + [
len(params['Number_of_servers'])] + [
len(params['Queue_capacities'])]
if len(set(num_nodes_count)) != 1:
Expand Down
39 changes: 18 additions & 21 deletions ciw/node.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from __future__ import division
from random import random, choice
from random import random
import os
from csv import writer

import networkx as nx
import numpy.random as nprandom

from data_record import DataRecord
from server import Server
from .data_record import DataRecord
from .server import Server


class Node(object):
Expand All @@ -29,28 +29,25 @@ def __init__(self, id_, simulation):
self.c = self.schedule[0][1]
raw_schedule_boundaries = [row[0] for row in raw_schedule]
self.date_generator = self.date_from_schedule_generator(raw_schedule_boundaries)
self.next_shift_change = self.date_generator.next()
self.next_shift_change = next(self.date_generator)
else:
self.c = node.number_of_servers
self.schedule = None
if node.queueing_capacity == "Inf":
self.node_capacity = "Inf"
else:
self.node_capacity = node.queueing_capacity + self.c
self.node_capacity = node.queueing_capacity + self.c
self.transition_row = [
self.simulation.network.customer_classes[
cls].transition_matrix[id_ - 1] for cls in xrange(
cls].transition_matrix[id_ - 1] for cls in range(
self.simulation.network.number_of_classes)]
self.class_change = node.class_change_matrix
self.individuals = []
self.id_number = id_
if self.schedule:
self.next_event_date = self.next_shift_change
else:
self.next_event_date = "Inf"
self.next_event_date = float("Inf")
self.blocked_queue = []
if self.c < 'Inf':
self.servers = [Server(self, i + 1) for i in xrange(self.c)]
if self.c < float('Inf'):
self.servers = [Server(self, i + 1) for i in range(self.c)]
self.highest_id = self.c
self.simulation.deadlock_detector.initialise_at_node(self)

Expand Down Expand Up @@ -78,7 +75,7 @@ def add_new_servers(self, shift_indx):
Add appropriate amount of servers for the given shift.
"""
num_servers = self.schedule[shift_indx][1]
for i in xrange(num_servers):
for i in range(num_servers):
self.highest_id += 1
self.servers.append(Server(self, self.highest_id))

Expand All @@ -103,7 +100,7 @@ def begin_service_if_possible_accept(self,
next_individual.service_time = self.get_service_time(
next_individual.customer_class)
if self.free_server():
if self.c < 'Inf':
if self.c < float('Inf'):
self.attach_server(self.find_free_server(),
next_individual)
next_individual.service_start_date = self.get_now(current_time)
Expand All @@ -129,7 +126,7 @@ def begin_service_if_possible_release(self, current_time):
Begins the service of the next individual, giving
that customer a service time, end date and node.
"""
if self.free_server() and self.c != 'Inf':
if self.free_server() and self.c != float('Inf'):
srvr = self.find_free_server()
if len([i for i in self.individuals if not i.server]) > 0:
ind = [i for i in self.individuals if not i.server][0]
Expand Down Expand Up @@ -159,7 +156,7 @@ def change_customer_class(self,individual):
if self.class_change:
individual.previous_class = individual.customer_class
individual.customer_class = nprandom.choice(
xrange(len(self.class_change)),
range(len(self.class_change)),
p = self.class_change[individual.previous_class])

def change_shift(self):
Expand All @@ -179,7 +176,7 @@ def change_shift(self):
self.add_new_servers(indx)

self.c = self.schedule[indx][1]
self.next_shift_change = self.date_generator.next()
self.next_shift_change = next(self.date_generator)
self.begin_service_if_possible_change_shift(
self.next_event_date)

Expand Down Expand Up @@ -207,7 +204,7 @@ def free_server(self):
"""
Returns True if a server is available, False otherwise
"""
if self.c == 'Inf':
if self.c == float('Inf'):
return True
return len([svr for svr in self.servers if not svr.busy]) > 0

Expand All @@ -227,7 +224,7 @@ def find_next_individual(self):
[ind.service_end_date for ind in self.individuals]
) if x == self.next_event_date]
if len(next_individual_indices) > 1:
next_individual_index = choice(next_individual_indices)
next_individual_index = nprandom.choice(next_individual_indices)
else:
next_individual_index = next_individual_indices[0]
return self.individuals[next_individual_index], next_individual_index
Expand Down Expand Up @@ -289,7 +286,7 @@ def release(self, next_individual_index, next_node, current_time):
next_individual = self.individuals.pop(next_individual_index)
next_individual.queue_size_at_departure = len(self.individuals)
next_individual.exit_date = current_time
if self.c < 'Inf':
if self.c < float('Inf'):
self.detatch_server(next_individual.server, next_individual)
self.write_individual_record(next_individual)
self.simulation.statetracker.change_state_release(self.id_number,
Expand Down Expand Up @@ -342,7 +339,7 @@ def update_next_event_date(self, current_time):
next_end_service = min([ind.service_end_date
for ind in self.individuals
if not ind.is_blocked
if ind.service_end_date >= current_time] + ["Inf"])
if ind.service_end_date >= current_time] + [float("Inf")])
if self.schedule:
next_shift_change = self.next_shift_change
self.next_event_date = min(
Expand Down
34 changes: 17 additions & 17 deletions ciw/simulation.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import division
import os
from random import (random, expovariate, uniform, triangular,
gammavariate, gauss, lognormvariate, weibullvariate, choice)
gammavariate, gauss, lognormvariate, weibullvariate)
from csv import writer, reader
import copy
from decimal import Decimal, getcontext
Expand All @@ -10,15 +10,15 @@
import yaml
import numpy.random as nprandom

from node import Node
from exactnode import ExactNode, ExactArrivalNode
from arrival_node import ArrivalNode
from exit_node import ExitNode
from server import Server
from individual import Individual
from data_record import DataRecord
from state_tracker import *
from deadlock_detector import *
from .node import Node
from .exactnode import ExactNode, ExactArrivalNode
from .arrival_node import ArrivalNode
from .exit_node import ExitNode
from .server import Server
from .individual import Individual
from .data_record import DataRecord
from .state_tracker import *
from .deadlock_detector import *


Record = namedtuple('Record', 'id_number customer_class node arrival_date waiting_time service_start_date service_time service_end_date time_blocked exit_date destination queue_size_at_arrival queue_size_at_departure')
Expand All @@ -44,7 +44,7 @@ def __init__(self, network, exact=False, name='Simulation', tracker=False, deadl
self.inter_arrival_times = self.find_times_dict('Arr')
self.service_times = self.find_times_dict('Ser')
self.transitive_nodes = [self.NodeType(i + 1, self)
for i in xrange(network.number_of_nodes)]
for i in range(network.number_of_nodes)]
self.nodes = ([self.ArrivalNodeType(self)] +
self.transitive_nodes +
[ExitNode()])
Expand Down Expand Up @@ -99,7 +99,7 @@ def find_distributions(self, n, c, kind):
Finds distribution functions
"""
if self.source(c, n, kind) == 'NoArrivals':
return lambda : 'Inf'
return lambda : float('Inf')
if self.source(c, n, kind)[0] == 'Uniform':
return lambda : uniform(self.source(c, n, kind)[1],
self.source(c, n, kind)[2])
Expand Down Expand Up @@ -129,8 +129,8 @@ def find_distributions(self, n, c, kind):
if self.source(c, n, kind)[0] == 'Empirical':
if isinstance(self.source(c, n, kind)[1], str):
empirical_dist = self.import_empirical(self.source(c, n, kind)[1])
return lambda : choice(empirical_dist)
return lambda : choice(self.source(c, n, kind)[1])
return lambda : nprandom.choice(empirical_dist)
return lambda : nprandom.choice(self.source(c, n, kind)[1])

def find_next_active_node(self):
"""
Expand All @@ -140,7 +140,7 @@ def find_next_active_node(self):
nd.next_event_date for nd in self.nodes]) if x == min([
nd.next_event_date for nd in self.nodes])]
if len(next_active_node_indices) > 1:
return self.nodes[choice(next_active_node_indices)]
return self.nodes[nprandom.choice(next_active_node_indices)]
return self.nodes[next_active_node_indices[0]]

def find_times_dict(self, kind):
Expand All @@ -150,8 +150,8 @@ def find_times_dict(self, kind):
"""
return {node+1: {
cls: self.find_distributions(node, cls, kind)
for cls in xrange(self.network.number_of_classes)}
for node in xrange(self.network.number_of_nodes)}
for cls in range(self.network.number_of_classes)}
for node in range(self.network.number_of_nodes)}

def get_all_individuals(self):
"""
Expand Down
Loading